Method: Puma::Server#process_client

Defined in:
lib/puma/server.rb

#process_client(client) ⇒ Object

Given a connection on client, handle the incoming requests, or queue the connection in the Reactor if no request is available.

This method is called from a ThreadPool worker thread.

This method supports HTTP Keep-Alive so it may, depending on if the client indicates that it supports keep alive, wait for another request before returning.

Return true if one or more requests were processed.



474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
# File 'lib/puma/server.rb', line 474

def process_client(client)
  # Advertise this server into the thread
  Thread.current.puma_server = self

  close_socket = true

  requests = 0

  begin
    if @queue_requests && !client.eagerly_finish

      client.set_timeout(@first_data_timeout)
      if @reactor.add client
        close_socket = false
        return false
      end
    end

    with_force_shutdown(client) do
      client.finish(@first_data_timeout)
    end

    @requests_count += 1
    case handle_request(client, requests + 1)
    when false
    when :async
      close_socket = false
    when true
      requests += 1

      client.reset

      # This indicates data exists in the client read buffer and there may be
      # additional requests on it, so process them
      next_request_ready = if client.has_back_to_back_requests?
        with_force_shutdown(client) { client.process_back_to_back_requests }
      else
        with_force_shutdown(client) { client.eagerly_finish }
      end

      if next_request_ready
        @thread_pool << client
        close_socket = false
      elsif @queue_requests
        client.set_timeout @persistent_timeout
        if @reactor.add client
          close_socket = false
        end
      end
    end
    true
  rescue StandardError => e
    client_error(e, client, requests)
    # The ensure tries to close +client+ down
    requests > 0
  ensure
    client.io_buffer.reset

    begin
      client.close if close_socket
    rescue IOError, SystemCallError
      # Already closed
    rescue StandardError => e
      @log_writer.unknown_error e, nil, "Client"
    end
  end
end