515: def process_client(client)
516: begin
517: parser = HttpParser.new
518: params = {}
519:
520: data = client.readpartial(Const::CHUNK_SIZE)
521: nparsed = 0
522:
523:
524:
525:
526:
527: while nparsed < data.length
528: nparsed = parser.execute(params, data, nparsed)
529:
530: if parser.finished?
531: script_name, path_info, handlers = @classifier.resolve(params[Const::REQUEST_URI])
532:
533: if handlers
534: params[Const::PATH_INFO] = path_info
535: params[Const::SCRIPT_NAME] = script_name
536: params[Const::REMOTE_ADDR] = params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last
537:
538:
539: request = HttpRequest.new(params, data[nparsed ... data.length] || "", client)
540:
541:
542: break if request.body == nil
543:
544:
545: response = HttpResponse.new(client)
546:
547:
548: handlers.each do |handler|
549: handler.process(request, response)
550: break if response.done or client.closed?
551: end
552:
553:
554: unless response.done or client.closed?
555: response.finished
556: end
557: else
558:
559:
560: client.write(Const::ERROR_404_RESPONSE)
561: end
562:
563: break
564: else
565:
566: data << client.readpartial(Const::CHUNK_SIZE)
567: if data.length >= Const::MAX_HEADER
568: raise HttpParserError.new("HEADER is longer than allowed, aborting client early.")
569: end
570: end
571: end
572: rescue EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
573:
574: rescue HttpParserError
575: STDERR.puts "#{Time.now}: BAD CLIENT (#{params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last}): #$!"
576: rescue => details
577: STDERR.puts "#{Time.now}: ERROR: #$!"
578: STDERR.puts details.backtrace.join("\n")
579: ensure
580: client.close unless client.closed?
581: end
582: end