lib/puma/server.rb
def process_client(client)
      parser = HttpParser.new
      close_socket = true

      begin
        while true
          parser.reset

          env = @proto_env.dup
          data = client.readpartial(CHUNK_SIZE)
          nparsed = 0

          # Assumption: nparsed will always be less since data will get filled
          # with more after each parsing.  If it doesn't get more then there was
          # a problem with the read operation on the client socket. 
          # Effect is to stop processing when the socket can't fill the buffer
          # for further parsing.
          while nparsed < data.length
            nparsed = parser.execute(env, data, nparsed)

            if parser.finished?
              cl = env[CONTENT_LENGTH]

              case handle_request(env, client, parser.body, cl)
              when false
                return
              when :async
                close_socket = false
                return
              end

              nparsed += parser.body.bytesize if cl

              if data.bytesize > nparsed
                data.slice!(0, nparsed)
                parser.reset
                env = @proto_env.dup
                nparsed = 0
              else
                unless ret = IO.select([client, @persistent_check], nil, nil, @persistent_timeout)
                  raise EOFError, "Timed out persistent connection"
                end

                return if ret.first.include? @persistent_check
              end
            else
              # Parser is not done, queue up more data to read and continue parsing
              chunk = client.readpartial(CHUNK_SIZE)
              return if !chunk or chunk.length == 0  # read failed, stop processing

              data << chunk
              if data.length >= MAX_HEADER
                raise HttpParserError,
                  "HEADER is longer than allowed, aborting client early."
              end
            end
          end
        end

      # The client disconnected while we were reading data
      rescue EOFError, SystemCallError
        # Swallow them. The ensure tries to close +client+ down

      # The client doesn't know HTTP well
      rescue HttpParserError => e
        @events.parse_error self, env, e

      # Server error
      rescue StandardError => e
        @events.unknown_error self, env, e, "Read"

      ensure
        begin
          client.close if close_socket
        rescue IOError, SystemCallError
          # Already closed
        rescue StandardError => e
          @events.unknown_error self, env, e, "Client"
        end
      end
    end
# Given a connection on +client+, handle the incoming requests.
#
# This method support HTTP Keep-Alive so it may, depending on if the client
# indicates that it supports keep alive, wait for another request before
# returning.
#
Given a connection on +client+, handle the incoming requests.
This method support HTTP Keep-Alive so it may, depending on if the client
indicates that it supports keep alive, wait for another request before
returning.
Given a connection on + client + handle the incoming requests . This method support HTTP Keep - Alive so it may depending on if the client indicates that it supports keep alive wait for another request before returning .
def process_client(client)
      parser = HttpParser.new
      close_socket = true
      begin
        while true
          parser.reset
          env = @proto_env.dup
          data = client.readpartial(CHUNK_SIZE)
          nparsed = 0
          while nparsed < data.length
            nparsed = parser.execute(env, data, nparsed)
            if parser.finished?
              cl = env[CONTENT_LENGTH]
              case handle_request(env, client, parser.body, cl)
              when false
                return
              when :async
                close_socket = false
                return
              end
              nparsed += parser.body.bytesize if cl
              if data.bytesize > nparsed
                data.slice!(0, nparsed)
                parser.reset
                env = @proto_env.dup
                nparsed = 0
              else
                unless ret = IO.select([client, @persistent_check], nil, nil, @persistent_timeout)
                  raise EOFError, "Timed out persistent connection"
                end
                return if ret.first.include? @persistent_check
              end
            else
              chunk = client.readpartial(CHUNK_SIZE)
              return if !chunk or chunk.length == 0  
              data << chunk
              if data.length >= MAX_HEADER
                raise HttpParserError,
                  "HEADER is longer than allowed, aborting client early."
              end
            end
          end
        end
      rescue EOFError, SystemCallError
      rescue HttpParserError => e
        @events.parse_error self, env, e
      rescue StandardError => e
        @events.unknown_error self, env, e, "Read"
      ensure
        begin
          client.close if close_socket
        rescue IOError, SystemCallError
        rescue StandardError => e
          @events.unknown_error self, env, e, "Client"
        end
      end
    end
def process_client ( client ) parser = HttpParser . new close_socket = true begin while true parser . reset env = @proto_env . dup data = client . readpartial ( CHUNK_SIZE ) nparsed = 0 while nparsed < data . length nparsed = parser . execute ( env , data , nparsed ) if parser . finished? cl = env [ CONTENT_LENGTH ] case handle_request ( env , client , parser . body , cl ) when false return when :async close_socket = false return end nparsed += parser . body . bytesize if cl if data . bytesize > nparsed data . slice! ( 0 , nparsed ) parser . reset env = @proto_env . dup nparsed = 0 else unless ret = IO . select ( [ client , @persistent_check ] , nil , nil , @persistent_timeout ) raise EOFError , "Timed out persistent connection" end return if ret . first . include? @persistent_check end else chunk = client . readpartial ( CHUNK_SIZE ) return if ! chunk or chunk . length == 0 data << chunk if data . length >= MAX_HEADER raise HttpParserError , "HEADER is longer than allowed, aborting client early." end end end end rescue EOFError , SystemCallError rescue HttpParserError => e @events . parse_error self , env , e rescue StandardError => e @events . unknown_error self , env , e , "Read" ensure begin client . close if close_socket rescue IOError , SystemCallError rescue StandardError => e @events . unknown_error self , env , e , "Client" end end end
Given a connection on +client+, handle the incoming requests.
Given a connection on + client + handle the incoming requests .
# Assumption: nparsed will always be less since data will get filled # with more after each parsing.  If it doesn't get more then there was # a problem with the read operation on the client socket.  # Effect is to stop processing when the socket can't fill the buffer # for further parsing. # Parser is not done, queue up more data to read and continue parsing # read failed, stop processing # The client disconnected while we were reading data # Swallow them. The ensure tries to close +client+ down # The client doesn't know HTTP well # Server error # Already closed
client