Class: Net::PTTH

Inherits:
Object
  • Object
show all
Includes:
Celluloid
Defined in:
lib/net/ptth.rb,
lib/net/ptth/test.rb,
lib/net/ptth/parser.rb,
lib/net/ptth/socket.rb,
lib/net/ptth/response.rb,
lib/net/ptth/incoming_request.rb,
lib/net/ptth/outgoing_request.rb,
lib/net/ptth/outgoing_response.rb

Overview

Public: PTTH constructor.

Attempts to mimic HTTP when applicable

Defined Under Namespace

Classes: IncomingRequest, OutgoingRequest, OutgoingResponse, Parser, Response, Socket, TestServer

Constant Summary collapse

SocketError =
Class.new(StandardError)
CRLF =
"\r\n".freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(address, options = {}) ⇒ PTTH

Public: Constructor

address: The address where the connection will be made
port: An optional port if the port is different from the one in the
      address


29
30
31
32
33
34
35
# File 'lib/net/ptth.rb', line 29

def initialize(address, options = {})
  info = URI.parse(address)

  @host, @port = info.host, info.port || options.fetch(:port, 80)
  @keep_alive = options.fetch(:keep_alive, false)
  set_debug_output = StringIO.new
end

Instance Attribute Details

#appObject

Returns the value of attribute app.



19
20
21
# File 'lib/net/ptth.rb', line 19

def app
  @app
end

Instance Method Details

#closeObject

Public: Closes de current connection



52
53
54
55
56
# File 'lib/net/ptth.rb', line 52

def close
  @keep_alive = false
  socket.close if socket.open?
  @_socket = nil
end

#parserObject

Public: Access to the PTTH::Parser



66
67
68
# File 'lib/net/ptth.rb', line 66

def parser
  @_parser ||= Net::PTTH::Parser.new
end

#request(req) ⇒ Object

Public: Generates a request based on a Net::HTTP object and yields a

      response

req: The request to be executed


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/net/ptth.rb', line 75

def request(req)
  outgoing = Net::PTTH::OutgoingRequest.new(req)
  packet = outgoing.to_s
  socket.write(packet)

  parser.reset
  response = ""
  while !parser.finished?
    buffer = socket.read
    debug "= #{buffer}"

    response << buffer
    parser   << buffer
  end

  debug "* Initial Response: #{response}"

  if parser.upgrade?
    debug "* Upgrade response"
    debug "* Reading socket"
    parser.reset

    while socket.open?
      response = ""
      parser.reset

      buffer = socket.read
      response << buffer
      parser << buffer

      if parser.finished?
        parser.body = buffer.split(CRLF*2).last
      end

      incoming = Net::PTTH::IncomingRequest.new(
        parser.http_method,
        parser.url,
        parser.headers,
        parser.body
      )

      env = incoming.to_env
      outgoing_response = Net::PTTH::OutgoingResponse.new(*app.call(env))
      socket.write(outgoing_response.to_s)
    end
  else
    debug "* Simple request"

    if parser.finished?
      parser.body = buffer.split(CRLF*2).last
    end

    response = Net::PTTH::Response.new(
      parser.http_method,
      parser.status_code,
      parser.headers,
      parser.body
    )

    keep_connection_active if keep_alive?(response)

    response
  end

rescue IOError => e
rescue EOFError => e
  close
end

#set_debug_output=(output) ⇒ Object

Public: Mimics Net::HTTP set_debug_output

output: A StringIO compatible object


41
42
43
44
45
46
47
48
# File 'lib/net/ptth.rb', line 41

def set_debug_output=(output)
  @debug_output = output
  Celluloid.logger = if output.is_a?(String)
                       ::Logger.new(output)
                     else
                       output
                     end
end

#socketObject

Public: Access to the PTTH::Socket



60
61
62
# File 'lib/net/ptth.rb', line 60

def socket
  @_socket ||= Net::PTTH::Socket.new(@host, @port)
end