yahns.git  about / heads / tags
sleepy, multi-threaded, non-blocking application server for Ruby
blob 40f2c58f61761660d15229c12556c2d44a9d78e5 2742 bytes (raw)
$ git show maint:lib/yahns/http_context.rb	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
 
# -*- encoding: binary -*-
# Copyright (C) 2013-2016 all contributors <yahns-public@yhbt.net>
# License: GPL-3.0+ (https://www.gnu.org/licenses/gpl-3.0.txt)
# frozen_string_literal: true

# subclasses of Yahns::HttpClient will class extend this

module Yahns::HttpContext # :nodoc:
  attr_accessor :check_client_connection
  attr_accessor :client_body_buffer_size
  attr_accessor :client_header_buffer_size
  attr_accessor :client_max_body_size
  attr_accessor :input_buffering  # :lazy, true, false
  attr_accessor :output_buffering # true, false
  attr_accessor :persistent_connections # true or false only
  attr_accessor :client_timeout
  attr_accessor :qegg
  attr_accessor :queue # set right before spawning acceptors
  attr_reader :app
  attr_accessor :app_defaults
  attr_writer :input_buffer_tmpdir
  attr_accessor :output_buffer_tmpdir

  def http_ctx_init(yahns_rack)
    @yahns_rack = yahns_rack
    @app_defaults = yahns_rack.app_defaults
    @check_client_connection = false
    @client_body_buffer_size = 8 * 1024
    @client_header_buffer_size = 4000
    @client_max_body_size = 1024 * 1024 # nil => infinity
    @input_buffering = true
    @output_buffering = true
    @persistent_connections = true
    @client_timeout = 15
    @qegg = nil
    @queue = nil

    # Dir.tmpdir can change while running, so leave these as nil
    @input_buffer_tmpdir = nil
    @output_buffer_tmpdir = nil
  end

  # call this after forking
  def after_fork_init
    @app = __wrap_app(@yahns_rack.app_after_fork)
  end

  def __wrap_app(app)
    # input_buffering == false is handled in http_client
    return app if @client_max_body_size.nil?

    require_relative 'cap_input'
    return app if @input_buffering == true

    # @input_buffering == false/:lazy
    require_relative 'max_body'
    Yahns::MaxBody.new(app, @client_max_body_size)
  end

  # call this immediately after successful accept()/accept4()
  def logger=(l) # cold
    @logger = @app_defaults["rack.logger"] = l
  end

  def logger
    @app_defaults["rack.logger"]
  end

  def mkinput(client, hs)
    (@input_buffering ? Yahns::TeeInput : Yahns::StreamInput).new(client, hs)
  end

  def errors=(dest)
    @app_defaults["rack.errors"] = dest
  end

  def errors
    @app_defaults["rack.errors"]
  end

  def tmpio_for(len, env)
    # short requests are most common
    if len && len <= @client_body_buffer_size;
      # Can't use binmode, yet: https://bugs.ruby-lang.org/issues/11945
      tmp = StringIO.new(''.dup)
    else # too big or chunked, unknown length
      tmp = @input_buffer_tmpdir
      mbs = @client_max_body_size
      tmp = mbs ? Yahns::CapInput.new(mbs, tmp) : Yahns::TmpIO.new(tmp)
      (env['rack.tempfiles'] ||= []) << tmp
    end
    tmp
  end
end

git clone git://yhbt.net/yahns.git
git clone https://yhbt.net/yahns.git