class Net::PTTH

Public: PTTH constructor.

Attempts to mimic HTTP when applicable

Constants

CRLF
IncomingRequest
OutgoingRequest
OutgoingResponse
Response
Socket
SocketError

Attributes

app[RW]

Public Class Methods

new(address, options = {}) click to toggle source

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
# 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

Public Instance Methods

close() click to toggle source

Public: Closes de current connection

# File lib/net/ptth.rb, line 52
def close
  @keep_alive = false
  socket.close if socket.open?
  @_socket = nil
end
parser() click to toggle source

Public: Access to the PTTH::Parser

# File lib/net/ptth.rb, line 66
def parser
  @_parser ||= Net::PTTH::Parser.new
end
request(req) click to toggle source

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

      response

req: The request to be executed
# 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) click to toggle source

Public: Mimics Net::HTTP set_debug_output

output: A StringIO compatible object
# 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
socket() click to toggle source

Public: Access to the PTTH::Socket

# File lib/net/ptth.rb, line 60
def socket
  @_socket ||= Net::PTTH::Socket.new(@host, @port)
end

Private Instance Methods

debug(string) click to toggle source

Private: outputs debug information

string: The string to be logged
# File lib/net/ptth.rb, line 164
def debug(string)
  return unless @debug_output
  @debug_output << string + "\n"
end
keep_alive?(response) click to toggle source
# File lib/net/ptth.rb, line 146
def keep_alive?(response)
  response.status == 200 && @keep_alive
end
keep_connection_active() click to toggle source
# File lib/net/ptth.rb, line 150
def keep_connection_active
  after(1) do
    while @keep_alive do
      # All you need is love. Something to keep alive the connection of that
      # given socket
      socket.write("<3") if socket.open?
      sleep 1
    end
  end
end