unicorn-simon 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. checksums.yaml +7 -0
  2. data/.CHANGELOG.old +25 -0
  3. data/.document +28 -0
  4. data/.gitattributes +5 -0
  5. data/.gitignore +25 -0
  6. data/.mailmap +26 -0
  7. data/.manifest +156 -0
  8. data/.olddoc.yml +18 -0
  9. data/Application_Timeouts +77 -0
  10. data/CONTRIBUTORS +35 -0
  11. data/COPYING +674 -0
  12. data/DESIGN +95 -0
  13. data/Documentation/.gitignore +5 -0
  14. data/Documentation/GNUmakefile +30 -0
  15. data/Documentation/unicorn.1.txt +187 -0
  16. data/Documentation/unicorn_rails.1.txt +175 -0
  17. data/FAQ +70 -0
  18. data/GIT-VERSION-FILE +1 -0
  19. data/GIT-VERSION-GEN +39 -0
  20. data/GNUmakefile +253 -0
  21. data/HACKING +120 -0
  22. data/ISSUES +90 -0
  23. data/KNOWN_ISSUES +79 -0
  24. data/LATEST +30 -0
  25. data/LICENSE +67 -0
  26. data/Links +56 -0
  27. data/NEWS +2465 -0
  28. data/PHILOSOPHY +139 -0
  29. data/README +138 -0
  30. data/Rakefile +16 -0
  31. data/SIGNALS +123 -0
  32. data/Sandbox +104 -0
  33. data/TODO +3 -0
  34. data/TUNING +119 -0
  35. data/archive/.gitignore +3 -0
  36. data/archive/slrnpull.conf +4 -0
  37. data/bin/unicorn +126 -0
  38. data/bin/unicorn_rails +209 -0
  39. data/examples/big_app_gc.rb +2 -0
  40. data/examples/echo.ru +27 -0
  41. data/examples/init.sh +102 -0
  42. data/examples/logger_mp_safe.rb +25 -0
  43. data/examples/logrotate.conf +44 -0
  44. data/examples/nginx.conf +155 -0
  45. data/examples/unicorn.conf.minimal.rb +13 -0
  46. data/examples/unicorn.conf.rb +110 -0
  47. data/examples/unicorn.socket +11 -0
  48. data/examples/unicorn@.service +33 -0
  49. data/ext/unicorn_http/CFLAGS +13 -0
  50. data/ext/unicorn_http/c_util.h +124 -0
  51. data/ext/unicorn_http/common_field_optimization.h +111 -0
  52. data/ext/unicorn_http/ext_help.h +62 -0
  53. data/ext/unicorn_http/extconf.rb +11 -0
  54. data/ext/unicorn_http/global_variables.h +97 -0
  55. data/ext/unicorn_http/httpdate.c +78 -0
  56. data/ext/unicorn_http/unicorn_http.c +4274 -0
  57. data/ext/unicorn_http/unicorn_http.rl +980 -0
  58. data/ext/unicorn_http/unicorn_http_common.rl +76 -0
  59. data/lib/unicorn/app/old_rails/static.rb +59 -0
  60. data/lib/unicorn/app/old_rails.rb +35 -0
  61. data/lib/unicorn/cgi_wrapper.rb +147 -0
  62. data/lib/unicorn/configurator.rb +664 -0
  63. data/lib/unicorn/const.rb +21 -0
  64. data/lib/unicorn/http_request.rb +122 -0
  65. data/lib/unicorn/http_response.rb +60 -0
  66. data/lib/unicorn/http_server.rb +824 -0
  67. data/lib/unicorn/launcher.rb +62 -0
  68. data/lib/unicorn/oob_gc.rb +82 -0
  69. data/lib/unicorn/preread_input.rb +33 -0
  70. data/lib/unicorn/socket_helper.rb +195 -0
  71. data/lib/unicorn/stream_input.rb +146 -0
  72. data/lib/unicorn/tee_input.rb +133 -0
  73. data/lib/unicorn/tmpio.rb +27 -0
  74. data/lib/unicorn/util.rb +90 -0
  75. data/lib/unicorn/version.rb +1 -0
  76. data/lib/unicorn/worker.rb +140 -0
  77. data/lib/unicorn.rb +123 -0
  78. data/man/man1/unicorn.1 +221 -0
  79. data/man/man1/unicorn_rails.1 +212 -0
  80. data/setup.rb +1586 -0
  81. data/t/.gitignore +4 -0
  82. data/t/GNUmakefile +74 -0
  83. data/t/README +42 -0
  84. data/t/bin/content-md5-put +36 -0
  85. data/t/bin/sha1sum.rb +17 -0
  86. data/t/bin/unused_listen +40 -0
  87. data/t/broken-app.ru +12 -0
  88. data/t/detach.ru +11 -0
  89. data/t/env.ru +3 -0
  90. data/t/fails-rack-lint.ru +5 -0
  91. data/t/heartbeat-timeout.ru +12 -0
  92. data/t/hijack.ru +43 -0
  93. data/t/listener_names.ru +4 -0
  94. data/t/my-tap-lib.sh +201 -0
  95. data/t/oob_gc.ru +20 -0
  96. data/t/oob_gc_path.ru +20 -0
  97. data/t/pid.ru +3 -0
  98. data/t/preread_input.ru +17 -0
  99. data/t/rack-input-tests.ru +21 -0
  100. data/t/t0000-http-basic.sh +50 -0
  101. data/t/t0001-reload-bad-config.sh +53 -0
  102. data/t/t0002-config-conflict.sh +49 -0
  103. data/t/t0002-parser-error.sh +94 -0
  104. data/t/t0003-working_directory.sh +51 -0
  105. data/t/t0004-heartbeat-timeout.sh +69 -0
  106. data/t/t0004-working_directory_broken.sh +24 -0
  107. data/t/t0005-working_directory_app.rb.sh +40 -0
  108. data/t/t0006-reopen-logs.sh +83 -0
  109. data/t/t0006.ru +13 -0
  110. data/t/t0007-working_directory_no_embed_cli.sh +44 -0
  111. data/t/t0008-back_out_of_upgrade.sh +110 -0
  112. data/t/t0009-broken-app.sh +56 -0
  113. data/t/t0009-winch_ttin.sh +59 -0
  114. data/t/t0010-reap-logging.sh +55 -0
  115. data/t/t0011-active-unix-socket.sh +79 -0
  116. data/t/t0012-reload-empty-config.sh +85 -0
  117. data/t/t0013-rewindable-input-false.sh +24 -0
  118. data/t/t0013.ru +12 -0
  119. data/t/t0014-rewindable-input-true.sh +24 -0
  120. data/t/t0014.ru +12 -0
  121. data/t/t0015-configurator-internals.sh +25 -0
  122. data/t/t0018-write-on-close.sh +23 -0
  123. data/t/t0019-max_header_len.sh +49 -0
  124. data/t/t0020-at_exit-handler.sh +49 -0
  125. data/t/t0021-process_detach.sh +29 -0
  126. data/t/t0022-listener_names-preload_app.sh +32 -0
  127. data/t/t0100-rack-input-tests.sh +124 -0
  128. data/t/t0116-client_body_buffer_size.sh +80 -0
  129. data/t/t0116.ru +16 -0
  130. data/t/t0200-rack-hijack.sh +30 -0
  131. data/t/t0300-no-default-middleware.sh +20 -0
  132. data/t/t9000-preread-input.sh +48 -0
  133. data/t/t9001-oob_gc.sh +47 -0
  134. data/t/t9002-oob_gc-path.sh +75 -0
  135. data/t/test-lib.sh +128 -0
  136. data/t/write-on-close.ru +11 -0
  137. data/test/aggregate.rb +15 -0
  138. data/test/benchmark/README +50 -0
  139. data/test/benchmark/dd.ru +18 -0
  140. data/test/benchmark/stack.ru +8 -0
  141. data/test/exec/README +5 -0
  142. data/test/exec/test_exec.rb +1099 -0
  143. data/test/test_helper.rb +298 -0
  144. data/test/unit/test_configurator.rb +175 -0
  145. data/test/unit/test_droplet.rb +28 -0
  146. data/test/unit/test_http_parser.rb +886 -0
  147. data/test/unit/test_http_parser_ng.rb +633 -0
  148. data/test/unit/test_request.rb +182 -0
  149. data/test/unit/test_response.rb +111 -0
  150. data/test/unit/test_server.rb +268 -0
  151. data/test/unit/test_signals.rb +188 -0
  152. data/test/unit/test_socket_helper.rb +197 -0
  153. data/test/unit/test_stream_input.rb +203 -0
  154. data/test/unit/test_tee_input.rb +304 -0
  155. data/test/unit/test_upload.rb +306 -0
  156. data/test/unit/test_util.rb +105 -0
  157. data/unicorn.gemspec +50 -0
  158. metadata +310 -0
@@ -0,0 +1,122 @@
1
+ # -*- encoding: binary -*-
2
+ # :enddoc:
3
+ # no stable API here
4
+ require 'unicorn_http'
5
+
6
+ # TODO: remove redundant names
7
+ Unicorn.const_set(:HttpRequest, Unicorn::HttpParser)
8
+ class Unicorn::HttpParser
9
+
10
+ # default parameters we merge into the request env for Rack handlers
11
+ DEFAULTS = {
12
+ "rack.errors" => $stderr,
13
+ "rack.multiprocess" => true,
14
+ "rack.multithread" => false,
15
+ "rack.run_once" => false,
16
+ "rack.version" => [1, 2],
17
+ "rack.hijack?" => true,
18
+ "SCRIPT_NAME" => "",
19
+
20
+ # this is not in the Rack spec, but some apps may rely on it
21
+ "SERVER_SOFTWARE" => "Unicorn #{Unicorn::Const::UNICORN_VERSION}"
22
+ }
23
+
24
+ NULL_IO = StringIO.new("")
25
+
26
+ # :stopdoc:
27
+ # A frozen format for this is about 15% faster
28
+ # Drop these frozen strings when Ruby 2.2 becomes more prevalent,
29
+ # 2.2+ optimizes hash assignments when used with literal string keys
30
+ HTTP_RESPONSE_START = [ 'HTTP', '/1.1 ']
31
+ @@input_class = Unicorn::TeeInput
32
+ @@check_client_connection = false
33
+
34
+ # TCP_TIME_WAIT: 6, TCP_CLOSE: 7, TCP_CLOSE_WAIT: 8, TCP_LAST_ACK: 9
35
+ IGNORED_CHECK_CLIENT_SOCKET_STATES = (6..9)
36
+
37
+ def self.input_class
38
+ @@input_class
39
+ end
40
+
41
+ def self.input_class=(klass)
42
+ @@input_class = klass
43
+ end
44
+
45
+ def self.check_client_connection
46
+ @@check_client_connection
47
+ end
48
+
49
+ def self.check_client_connection=(bool)
50
+ @@check_client_connection = bool
51
+ end
52
+
53
+ # :startdoc:
54
+
55
+ # Does the majority of the IO processing. It has been written in
56
+ # Ruby using about 8 different IO processing strategies.
57
+ #
58
+ # It is currently carefully constructed to make sure that it gets
59
+ # the best possible performance for the common case: GET requests
60
+ # that are fully complete after a single read(2)
61
+ #
62
+ # Anyone who thinks they can make it faster is more than welcome to
63
+ # take a crack at it.
64
+ #
65
+ # returns an environment hash suitable for Rack if successful
66
+ # This does minimal exception trapping and it is up to the caller
67
+ # to handle any socket errors (e.g. user aborted upload).
68
+ def read(socket)
69
+ clear
70
+ e = env
71
+
72
+ # From http://www.ietf.org/rfc/rfc3875:
73
+ # "Script authors should be aware that the REMOTE_ADDR and
74
+ # REMOTE_HOST meta-variables (see sections 4.1.8 and 4.1.9)
75
+ # may not identify the ultimate source of the request. They
76
+ # identify the client for the immediate request to the server;
77
+ # that client may be a proxy, gateway, or other intermediary
78
+ # acting on behalf of the actual source client."
79
+ e['REMOTE_ADDR'] = socket.kgio_addr
80
+
81
+ # short circuit the common case with small GET requests first
82
+ socket.kgio_read!(16384, buf)
83
+ if parse.nil?
84
+ # Parser is not done, queue up more data to read and continue parsing
85
+ # an Exception thrown from the parser will throw us out of the loop
86
+ false until add_parse(socket.kgio_read!(16384))
87
+ end
88
+
89
+ # detect if the socket is valid by checking client connection.
90
+ if @@check_client_connection
91
+ if defined?(Raindrops::TCP_Info)
92
+ tcp_info = Raindrops::TCP_Info.new(socket)
93
+ if IGNORED_CHECK_CLIENT_SOCKET_STATES.cover?(tcp_info.state)
94
+ socket.close
95
+ raise Errno::EPIPE
96
+ end
97
+ elsif headers?
98
+ self.response_start_sent = true
99
+ HTTP_RESPONSE_START.each { |c| socket.write(c) }
100
+ end
101
+ end
102
+
103
+ e['rack.input'] = 0 == content_length ?
104
+ NULL_IO : @@input_class.new(socket, self)
105
+
106
+ # for Rack hijacking in Rack 1.5 and later
107
+ e['unicorn.socket'] = socket
108
+ e['rack.hijack'] = self
109
+
110
+ e.merge!(DEFAULTS)
111
+ end
112
+
113
+ # for rack.hijack, we respond to this method so no extra allocation
114
+ # of a proc object
115
+ def call
116
+ env['rack.hijack_io'] = env['unicorn.socket']
117
+ end
118
+
119
+ def hijacked?
120
+ env.include?('rack.hijack_io'.freeze)
121
+ end
122
+ end
@@ -0,0 +1,60 @@
1
+ # -*- encoding: binary -*-
2
+ # :enddoc:
3
+ # Writes a Rack response to your client using the HTTP/1.1 specification.
4
+ # You use it by simply doing:
5
+ #
6
+ # status, headers, body = rack_app.call(env)
7
+ # http_response_write(socket, status, headers, body)
8
+ #
9
+ # Most header correctness (including Content-Length and Content-Type)
10
+ # is the job of Rack, with the exception of the "Date" and "Status" header.
11
+ module Unicorn::HttpResponse
12
+
13
+ STATUS_CODES = defined?(Rack::Utils::HTTP_STATUS_CODES) ?
14
+ Rack::Utils::HTTP_STATUS_CODES : {}
15
+
16
+ # internal API, code will always be common-enough-for-even-old-Rack
17
+ def err_response(code, response_start_sent)
18
+ "#{response_start_sent ? '' : 'HTTP/1.1 '}" \
19
+ "#{code} #{STATUS_CODES[code]}\r\n\r\n"
20
+ end
21
+
22
+ # writes the rack_response to socket as an HTTP response
23
+ def http_response_write(socket, status, headers, body,
24
+ response_start_sent=false)
25
+ hijack = nil
26
+
27
+ if headers
28
+ code = status.to_i
29
+ msg = STATUS_CODES[code]
30
+ start = response_start_sent ? ''.freeze : 'HTTP/1.1 '.freeze
31
+ buf = "#{start}#{msg ? %Q(#{code} #{msg}) : status}\r\n" \
32
+ "Date: #{httpdate}\r\n" \
33
+ "Connection: close\r\n"
34
+ headers.each do |key, value|
35
+ case key
36
+ when %r{\A(?:Date|Connection)\z}i
37
+ next
38
+ when "rack.hijack"
39
+ # This should only be hit under Rack >= 1.5, as this was an illegal
40
+ # key in Rack < 1.5
41
+ hijack = value
42
+ else
43
+ if value =~ /\n/
44
+ # avoiding blank, key-only cookies with /\n+/
45
+ value.split(/\n+/).each { |v| buf << "#{key}: #{v}\r\n" }
46
+ else
47
+ buf << "#{key}: #{value}\r\n"
48
+ end
49
+ end
50
+ end
51
+ socket.write(buf << "\r\n".freeze)
52
+ end
53
+
54
+ if hijack
55
+ hijack.call(socket)
56
+ else
57
+ body.each { |chunk| socket.write(chunk) }
58
+ end
59
+ end
60
+ end