class NchanTools::Subscriber::HTTPChunkedClient

Public Class Methods

aliases() click to toggle source
# File lib/nchan_tools/pubsub.rb, line 1440
def self.aliases
  [:chunked]
end

Public Instance Methods

new_bundle(uri, opt) click to toggle source
# File lib/nchan_tools/pubsub.rb, line 1444
def new_bundle(uri, opt)
   opt[:accept]="*/*"
   opt[:headers]=(opt[:headers] or {}).merge({"TE" => "Chunked"})
  super
end
provides_msgid?() click to toggle source
# File lib/nchan_tools/pubsub.rb, line 1427
def provides_msgid?
  false
end
run(*args) click to toggle source
# File lib/nchan_tools/pubsub.rb, line 1431
def run(*args)
  if @http2
    @subscriber.on_failure error(0, "Chunked transfer is not allowed in HTTP/2")
    @connected = 0
    return
  end
  super
end
setup_bundle(b) click to toggle source
# File lib/nchan_tools/pubsub.rb, line 1450
def setup_bundle(b)
  super
  b.body_buf = nil
  b.on_headers do |code, headers|
    if code == 200
      if headers["Transfer-Encoding"] != "chunked"
        @subscriber.on_failure error(0, "Transfer-Encoding should be 'chunked', was '#{headers["Transfer-Encoding"]}'.", b)
        close b
      else
        @notready -= 1
        @cooked_ready.signal true if @notready == 0
        b.connected= true
      end
    else
      b.buffer_body!
      b.stop_after_headers = false
    end
  end
  
  b.stop_after_headers = true
  @inchunk = false
  @chunksize = 0
  @repeat = true
  @chunkbuf = ""
  b.on_chunk do |chunk|
    #puts "yeah"
    @chunkbuf << chunk
    @repeat = true
    while @repeat
      @repeat = false
      if !@inchunk && @chunkbuf.slice!(/^([a-fA-F0-9]+)\r\n/m)
        @chunksize = $~[1].to_i(16)
        @inchunk = true
      end
      
      if @inchunk
        if @chunkbuf.length >= @chunksize + 2
          msgbody = @chunkbuf.slice!(0...@chunksize)
          @chunkbuf.slice!(/^\r\n/m)
          @timer.reset if @timer
          unless @nomsg
            msg=Message.new msgbody, nil, nil
          else
            msg=msgbody
          end
          if @subscriber.on_message(msg, b) == false
            @subscriber.finished+=1
            close b
          end
          @repeat = true if @chunkbuf.length > 0
          @inchunk = false
          @chunksize = 0
        end
      end
    end
  end
  
  b.on_response do |code, headers, body|
    if code != 200
      @subscriber.on_failure(error(code, "", b))
    else
      @subscriber.on_failure error(410, "Server Closed Connection", b)
    end
    close b
  end
  
  b
end