unicorn-rupcio 6.1.0

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 (145) 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 +144 -0
  8. data/.olddoc.yml +25 -0
  9. data/Application_Timeouts +77 -0
  10. data/CONTRIBUTORS +39 -0
  11. data/COPYING +674 -0
  12. data/DESIGN +99 -0
  13. data/Documentation/.gitignore +3 -0
  14. data/Documentation/unicorn.1 +222 -0
  15. data/Documentation/unicorn_rails.1 +207 -0
  16. data/FAQ +70 -0
  17. data/GIT-VERSION-FILE +1 -0
  18. data/GIT-VERSION-GEN +39 -0
  19. data/GNUmakefile +318 -0
  20. data/HACKING +117 -0
  21. data/ISSUES +102 -0
  22. data/KNOWN_ISSUES +79 -0
  23. data/LICENSE +67 -0
  24. data/Links +58 -0
  25. data/PHILOSOPHY +139 -0
  26. data/README +165 -0
  27. data/Rakefile +17 -0
  28. data/SIGNALS +123 -0
  29. data/Sandbox +104 -0
  30. data/TODO +1 -0
  31. data/TUNING +119 -0
  32. data/archive/.gitignore +3 -0
  33. data/archive/slrnpull.conf +4 -0
  34. data/bin/unicorn +129 -0
  35. data/bin/unicorn_rails +210 -0
  36. data/examples/big_app_gc.rb +3 -0
  37. data/examples/echo.ru +27 -0
  38. data/examples/init.sh +102 -0
  39. data/examples/logger_mp_safe.rb +26 -0
  40. data/examples/logrotate.conf +44 -0
  41. data/examples/nginx.conf +156 -0
  42. data/examples/unicorn.conf.minimal.rb +14 -0
  43. data/examples/unicorn.conf.rb +111 -0
  44. data/examples/unicorn.socket +11 -0
  45. data/examples/unicorn@.service +40 -0
  46. data/ext/unicorn_http/CFLAGS +13 -0
  47. data/ext/unicorn_http/c_util.h +115 -0
  48. data/ext/unicorn_http/common_field_optimization.h +128 -0
  49. data/ext/unicorn_http/epollexclusive.h +128 -0
  50. data/ext/unicorn_http/ext_help.h +38 -0
  51. data/ext/unicorn_http/extconf.rb +40 -0
  52. data/ext/unicorn_http/global_variables.h +97 -0
  53. data/ext/unicorn_http/httpdate.c +91 -0
  54. data/ext/unicorn_http/unicorn_http.c +4348 -0
  55. data/ext/unicorn_http/unicorn_http.rl +1054 -0
  56. data/ext/unicorn_http/unicorn_http_common.rl +76 -0
  57. data/lib/unicorn/app/old_rails/static.rb +60 -0
  58. data/lib/unicorn/app/old_rails.rb +36 -0
  59. data/lib/unicorn/cgi_wrapper.rb +148 -0
  60. data/lib/unicorn/configurator.rb +749 -0
  61. data/lib/unicorn/const.rb +22 -0
  62. data/lib/unicorn/http_request.rb +180 -0
  63. data/lib/unicorn/http_response.rb +95 -0
  64. data/lib/unicorn/http_server.rb +860 -0
  65. data/lib/unicorn/launcher.rb +63 -0
  66. data/lib/unicorn/oob_gc.rb +82 -0
  67. data/lib/unicorn/preread_input.rb +34 -0
  68. data/lib/unicorn/select_waiter.rb +7 -0
  69. data/lib/unicorn/socket_helper.rb +186 -0
  70. data/lib/unicorn/stream_input.rb +152 -0
  71. data/lib/unicorn/tee_input.rb +132 -0
  72. data/lib/unicorn/tmpio.rb +34 -0
  73. data/lib/unicorn/util.rb +91 -0
  74. data/lib/unicorn/version.rb +1 -0
  75. data/lib/unicorn/worker.rb +166 -0
  76. data/lib/unicorn.rb +137 -0
  77. data/man/man1/unicorn.1 +222 -0
  78. data/man/man1/unicorn_rails.1 +207 -0
  79. data/setup.rb +1587 -0
  80. data/t/.gitignore +4 -0
  81. data/t/GNUmakefile +5 -0
  82. data/t/README +49 -0
  83. data/t/active-unix-socket.t +110 -0
  84. data/t/back-out-of-upgrade.t +44 -0
  85. data/t/bin/unused_listen +40 -0
  86. data/t/client_body_buffer_size.ru +15 -0
  87. data/t/client_body_buffer_size.t +79 -0
  88. data/t/detach.ru +12 -0
  89. data/t/env.ru +4 -0
  90. data/t/fails-rack-lint.ru +6 -0
  91. data/t/heartbeat-timeout.ru +13 -0
  92. data/t/heartbeat-timeout.t +60 -0
  93. data/t/integration.ru +129 -0
  94. data/t/integration.t +509 -0
  95. data/t/lib.perl +309 -0
  96. data/t/listener_names.ru +5 -0
  97. data/t/my-tap-lib.sh +201 -0
  98. data/t/oob_gc.ru +18 -0
  99. data/t/oob_gc_path.ru +18 -0
  100. data/t/pid.ru +4 -0
  101. data/t/preread_input.ru +23 -0
  102. data/t/reload-bad-config.t +49 -0
  103. data/t/reopen-logs.ru +14 -0
  104. data/t/reopen-logs.t +36 -0
  105. data/t/t0010-reap-logging.sh +55 -0
  106. data/t/t0012-reload-empty-config.sh +86 -0
  107. data/t/t0013-rewindable-input-false.sh +24 -0
  108. data/t/t0013.ru +13 -0
  109. data/t/t0014-rewindable-input-true.sh +24 -0
  110. data/t/t0014.ru +13 -0
  111. data/t/t0015-configurator-internals.sh +25 -0
  112. data/t/t0020-at_exit-handler.sh +49 -0
  113. data/t/t0021-process_detach.sh +29 -0
  114. data/t/t0022-listener_names-preload_app.sh +32 -0
  115. data/t/t0300-no-default-middleware.sh +20 -0
  116. data/t/t0301-no-default-middleware-ignored-in-config.sh +25 -0
  117. data/t/t0301.ru +14 -0
  118. data/t/t9001-oob_gc.sh +47 -0
  119. data/t/t9002-oob_gc-path.sh +75 -0
  120. data/t/test-lib.sh +125 -0
  121. data/t/winch_ttin.t +64 -0
  122. data/t/working_directory.t +86 -0
  123. data/test/aggregate.rb +16 -0
  124. data/test/benchmark/README +60 -0
  125. data/test/benchmark/dd.ru +19 -0
  126. data/test/benchmark/ddstream.ru +51 -0
  127. data/test/benchmark/readinput.ru +41 -0
  128. data/test/benchmark/stack.ru +9 -0
  129. data/test/benchmark/uconnect.perl +66 -0
  130. data/test/exec/README +5 -0
  131. data/test/exec/test_exec.rb +1030 -0
  132. data/test/test_helper.rb +307 -0
  133. data/test/unit/test_configurator.rb +176 -0
  134. data/test/unit/test_droplet.rb +29 -0
  135. data/test/unit/test_http_parser.rb +885 -0
  136. data/test/unit/test_http_parser_ng.rb +715 -0
  137. data/test/unit/test_server.rb +245 -0
  138. data/test/unit/test_signals.rb +189 -0
  139. data/test/unit/test_socket_helper.rb +160 -0
  140. data/test/unit/test_stream_input.rb +211 -0
  141. data/test/unit/test_tee_input.rb +304 -0
  142. data/test/unit/test_util.rb +132 -0
  143. data/test/unit/test_waiter.rb +35 -0
  144. data/unicorn.gemspec +49 -0
  145. metadata +266 -0
@@ -0,0 +1,76 @@
1
+ %%{
2
+
3
+ machine unicorn_http_common;
4
+
5
+ #### HTTP PROTOCOL GRAMMAR
6
+ # line endings
7
+ CRLF = ("\r\n" | "\n");
8
+
9
+ # character types
10
+ CTL = (cntrl | 127);
11
+ safe = ("$" | "-" | "_" | ".");
12
+ extra = ("!" | "*" | "'" | "(" | ")" | ",");
13
+ reserved = (";" | "/" | "?" | ":" | "@" | "&" | "=" | "+");
14
+ sorta_safe = ("\"" | "<" | ">");
15
+ unsafe = (CTL | " " | "#" | "%" | sorta_safe);
16
+ national = any -- (alpha | digit | reserved | extra | safe | unsafe);
17
+ unreserved = (alpha | digit | safe | extra | national);
18
+ escape = ("%" xdigit xdigit);
19
+ uchar = (unreserved | escape | sorta_safe);
20
+ pchar = (uchar | ":" | "@" | "&" | "=" | "+");
21
+ tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t");
22
+ lws = (" " | "\t");
23
+ content = ((any -- CTL) | lws);
24
+
25
+ # elements
26
+ token = (ascii -- (CTL | tspecials));
27
+
28
+ # URI schemes and absolute paths
29
+ scheme = ( "http"i ("s"i)? ) $downcase_char >mark %scheme;
30
+ hostname = ((alnum | "-" | "." | "_")+ | ("[" (":" | xdigit)+ "]"));
31
+ host_with_port = (hostname (":" digit*)?) >mark %host;
32
+ userinfo = ((unreserved | escape | ";" | ":" | "&" | "=" | "+")+ "@")*;
33
+
34
+ path = ( pchar+ ( "/" pchar* )* ) ;
35
+ query = ( uchar | reserved )* %query_string ;
36
+ param = ( pchar | "/" )* ;
37
+ params = ( param ( ";" param )* ) ;
38
+ rel_path = (path? (";" params)? %request_path) ("?" %start_query query)?;
39
+ absolute_path = ( "/"+ rel_path );
40
+ path_uri = absolute_path > mark %request_uri;
41
+ Absolute_URI = (scheme "://" userinfo host_with_port path_uri);
42
+
43
+ Request_URI = ((absolute_path | "*") >mark %request_uri) | Absolute_URI;
44
+ Fragment = ( uchar | reserved )* >mark %fragment;
45
+ Method = (token){1,20} >mark %request_method;
46
+ GetOnly = "GET" >mark %request_method;
47
+
48
+ http_number = ( digit+ "." digit+ ) ;
49
+ HTTP_Version = ( "HTTP/" http_number ) >mark %http_version ;
50
+ Request_Line = ( Method " " Request_URI ("#" Fragment){0,1} " " HTTP_Version CRLF ) ;
51
+
52
+ field_name = ( token -- ":" )+ >start_field $upcase_field %write_field;
53
+
54
+ field_value = content* >start_value %write_value;
55
+
56
+ value_cont = lws+ content* >start_value %write_cont_value;
57
+
58
+ message_header = ((field_name ":" lws* field_value)|value_cont) :> CRLF;
59
+ chunk_ext_val = token*;
60
+ chunk_ext_name = token*;
61
+ chunk_extension = ( ";" " "* chunk_ext_name ("=" chunk_ext_val)? )*;
62
+ last_chunk = "0"+ chunk_extension CRLF;
63
+ chunk_size = (xdigit* [1-9a-fA-F] xdigit*) $add_to_chunk_size;
64
+ chunk_end = CRLF;
65
+ chunk_body = any >skip_chunk_data;
66
+ chunk_begin = chunk_size chunk_extension CRLF;
67
+ chunk = chunk_begin chunk_body chunk_end;
68
+ ChunkedBody := chunk* last_chunk @end_chunked_body;
69
+ Trailers := (message_header)* CRLF @end_trailers;
70
+
71
+ FullRequest = Request_Line (message_header)* CRLF @header_done;
72
+ SimpleRequest = GetOnly " " Request_URI ("#"Fragment){0,1} CRLF @header_done;
73
+
74
+ main := FullRequest | SimpleRequest;
75
+
76
+ }%%
@@ -0,0 +1,60 @@
1
+ # -*- encoding: binary -*-
2
+ # frozen_string_literal: false
3
+ # :enddoc:
4
+ # This code is based on the original Rails handler in Mongrel
5
+ # Copyright (c) 2005 Zed A. Shaw
6
+ # Copyright (c) 2009 Eric Wong
7
+ # You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
8
+ # the GPLv3
9
+
10
+ # Static file handler for Rails < 2.3. This handler is only provided
11
+ # as a convenience for developers. Performance-minded deployments should
12
+ # use nginx (or similar) for serving static files.
13
+ #
14
+ # This supports page caching directly and will try to resolve a
15
+ # request in the following order:
16
+ #
17
+ # * If the requested exact PATH_INFO exists as a file then serve it.
18
+ # * If it exists at PATH_INFO+rest_operator+".html" exists
19
+ # then serve that.
20
+ #
21
+ # This means that if you are using page caching it will actually work
22
+ # with Unicorn and you should see a decent speed boost (but not as
23
+ # fast as if you use a static server like nginx).
24
+ class Unicorn::App::OldRails::Static < Struct.new(:app, :root, :file_server)
25
+ FILE_METHODS = { 'GET' => true, 'HEAD' => true }
26
+
27
+ # avoid allocating new strings for hash lookups
28
+ REQUEST_METHOD = 'REQUEST_METHOD'
29
+ REQUEST_URI = 'REQUEST_URI'
30
+ PATH_INFO = 'PATH_INFO'
31
+
32
+ def initialize(app)
33
+ self.app = app
34
+ self.root = "#{::RAILS_ROOT}/public"
35
+ self.file_server = ::Rack::File.new(root)
36
+ end
37
+
38
+ def call(env)
39
+ # short circuit this ASAP if serving non-file methods
40
+ FILE_METHODS.include?(env[REQUEST_METHOD]) or return app.call(env)
41
+
42
+ # first try the path as-is
43
+ path_info = env[PATH_INFO].chomp("/")
44
+ if File.file?("#{root}/#{::Rack::Utils.unescape(path_info)}")
45
+ # File exists as-is so serve it up
46
+ env[PATH_INFO] = path_info
47
+ return file_server.call(env)
48
+ end
49
+
50
+ # then try the cached version:
51
+ path_info << ActionController::Base.page_cache_extension
52
+
53
+ if File.file?("#{root}/#{::Rack::Utils.unescape(path_info)}")
54
+ env[PATH_INFO] = path_info
55
+ return file_server.call(env)
56
+ end
57
+
58
+ app.call(env) # call OldRails
59
+ end
60
+ end if defined?(Unicorn::App::OldRails)
@@ -0,0 +1,36 @@
1
+ # -*- encoding: binary -*-
2
+ # frozen_string_literal: false
3
+
4
+ # :enddoc:
5
+ # This code is based on the original Rails handler in Mongrel
6
+ # Copyright (c) 2005 Zed A. Shaw
7
+ # Copyright (c) 2009 Eric Wong
8
+ # You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
9
+ # the GPLv2+ (GPLv3+ preferred)
10
+ # Additional work donated by contributors. See CONTRIBUTORS for more info.
11
+ require 'unicorn/cgi_wrapper'
12
+ require 'dispatcher'
13
+
14
+ module Unicorn; module App; end; end
15
+
16
+ # Implements a handler that can run Rails.
17
+ class Unicorn::App::OldRails
18
+
19
+ autoload :Static, "unicorn/app/old_rails/static"
20
+
21
+ def call(env)
22
+ cgi = Unicorn::CGIWrapper.new(env)
23
+ begin
24
+ Dispatcher.dispatch(cgi,
25
+ ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS,
26
+ cgi.body)
27
+ rescue => e
28
+ err = env['rack.errors']
29
+ err.write("#{e} #{e.message}\n")
30
+ e.backtrace.each { |line| err.write("#{line}\n") }
31
+ end
32
+ cgi.out # finalize the response
33
+ cgi.rack_response
34
+ end
35
+
36
+ end
@@ -0,0 +1,148 @@
1
+ # -*- encoding: binary -*-
2
+ # frozen_string_literal: false
3
+
4
+ # :enddoc:
5
+ # This code is based on the original CGIWrapper from Mongrel
6
+ # Copyright (c) 2005 Zed A. Shaw
7
+ # Copyright (c) 2009 Eric Wong
8
+ # You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
9
+ # the GPLv2+ (GPLv3+ preferred)
10
+ #
11
+ # Additional work donated by contributors. See CONTRIBUTORS for more info.
12
+
13
+ require 'cgi'
14
+
15
+ module Unicorn; end
16
+
17
+ # The beginning of a complete wrapper around Unicorn's internal HTTP
18
+ # processing system but maintaining the original Ruby CGI module. Use
19
+ # this only as a crutch to get existing CGI based systems working. It
20
+ # should handle everything, but please notify us if you see special
21
+ # warnings. This work is still very alpha so we need testers to help
22
+ # work out the various corner cases.
23
+ class Unicorn::CGIWrapper < ::CGI
24
+ undef_method :env_table
25
+ attr_reader :env_table
26
+ attr_reader :body
27
+
28
+ # these are stripped out of any keys passed to CGIWrapper.header function
29
+ NPH = 'nph'.freeze # Completely ignored, Unicorn outputs the date regardless
30
+ CONNECTION = 'connection'.freeze # Completely ignored. Why is CGI doing this?
31
+ CHARSET = 'charset'.freeze # this gets appended to Content-Type
32
+ COOKIE = 'cookie'.freeze # maps (Hash,Array,String) to "Set-Cookie" headers
33
+ STATUS = 'status'.freeze # stored as @status
34
+ Status = 'Status'.freeze # code + human-readable text, Rails sets this
35
+
36
+ # some of these are common strings, but this is the only module
37
+ # using them and the reason they're not in Unicorn::Const
38
+ SET_COOKIE = 'Set-Cookie'.freeze
39
+ CONTENT_TYPE = 'Content-Type'.freeze
40
+ CONTENT_LENGTH = 'Content-Length'.freeze # this is NOT Const::CONTENT_LENGTH
41
+ RACK_INPUT = 'rack.input'.freeze
42
+ RACK_ERRORS = 'rack.errors'.freeze
43
+
44
+ # this maps CGI header names to HTTP header names
45
+ HEADER_MAP = {
46
+ 'status' => Status,
47
+ 'type' => CONTENT_TYPE,
48
+ 'server' => 'Server'.freeze,
49
+ 'language' => 'Content-Language'.freeze,
50
+ 'expires' => 'Expires'.freeze,
51
+ 'length' => CONTENT_LENGTH,
52
+ }
53
+
54
+ # Takes an a Rackable environment, plus any additional CGI.new
55
+ # arguments These are used internally to create a wrapper around the
56
+ # real CGI while maintaining Rack/Unicorn's view of the world. This
57
+ # this will NOT deal well with large responses that take up a lot of
58
+ # memory, but neither does the CGI nor the original CGIWrapper from
59
+ # Mongrel...
60
+ def initialize(rack_env, *args)
61
+ @env_table = rack_env
62
+ @status = nil
63
+ @head = {}
64
+ @headv = Hash.new { |hash,key| hash[key] = [] }
65
+ @body = StringIO.new("")
66
+ super(*args)
67
+ end
68
+
69
+ # finalizes the response in a way Rack applications would expect
70
+ def rack_response
71
+ # @head[CONTENT_LENGTH] ||= @body.size
72
+ @headv[SET_COOKIE].concat(@output_cookies) if @output_cookies
73
+ @headv.each_pair do |key,value|
74
+ @head[key] ||= value.join("\n") unless value.empty?
75
+ end
76
+
77
+ # Capitalized "Status:", with human-readable status code (e.g. "200 OK")
78
+ @status ||= @head.delete(Status)
79
+
80
+ [ @status || 500, @head, [ @body.string ] ]
81
+ end
82
+
83
+ # The header is typically called to send back the header. In our case we
84
+ # collect it into a hash for later usage. This can be called multiple
85
+ # times to set different cookies.
86
+ def header(options = "text/html")
87
+ # if they pass in a string then just write the Content-Type
88
+ if String === options
89
+ @head[CONTENT_TYPE] ||= options
90
+ else
91
+ HEADER_MAP.each_pair do |from, to|
92
+ from = options.delete(from) or next
93
+ @head[to] = from.to_s
94
+ end
95
+
96
+ @head[CONTENT_TYPE] ||= "text/html"
97
+ if charset = options.delete(CHARSET)
98
+ @head[CONTENT_TYPE] << "; charset=#{charset}"
99
+ end
100
+
101
+ # lots of ways to set cookies
102
+ if cookie = options.delete(COOKIE)
103
+ set_cookies = @headv[SET_COOKIE]
104
+ case cookie
105
+ when Array
106
+ cookie.each { |c| set_cookies << c.to_s }
107
+ when Hash
108
+ cookie.each_value { |c| set_cookies << c.to_s }
109
+ else
110
+ set_cookies << cookie.to_s
111
+ end
112
+ end
113
+ @status ||= options.delete(STATUS) # all lower-case
114
+
115
+ # drop the keys we don't want anymore
116
+ options.delete(NPH)
117
+ options.delete(CONNECTION)
118
+
119
+ # finally, set the rest of the headers as-is, allowing duplicates
120
+ options.each_pair { |k,v| @headv[k] << v }
121
+ end
122
+
123
+ # doing this fakes out the cgi library to think the headers are empty
124
+ # we then do the real headers in the out function call later
125
+ ""
126
+ end
127
+
128
+ # The dumb thing is people can call header or this or both and in
129
+ # any order. So, we just reuse header and then finalize the
130
+ # HttpResponse the right way. This will have no effect if called
131
+ # the second time if the first "outputted" anything.
132
+ def out(options = "text/html")
133
+ header(options)
134
+ @body.size == 0 or return
135
+ @body << yield if block_given?
136
+ end
137
+
138
+ # Used to wrap the normal stdinput variable used inside CGI.
139
+ def stdinput
140
+ @env_table[RACK_INPUT]
141
+ end
142
+
143
+ # return a pointer to the StringIO body since it's STDOUT-like
144
+ def stdoutput
145
+ @body
146
+ end
147
+
148
+ end