unicorn-shopify 5.2.0.4 → 5.2.0.5
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.
- checksums.yaml +4 -4
- data/lib/unicorn/http_request.rb +68 -5
- data/lib/unicorn/http_server.rb +1 -1
- data/lib/unicorn/socket_helper.rb +14 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15234ad243f343ca91236020b735d34a6600225e
|
4
|
+
data.tar.gz: 32175e0fa8ac820fd1b999ef31f4fa44f78ee547
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8da8bc2ea24a713f003675713dff5b319eff51a3d842933b6fe68701eb20d1ff8b1173d4440921265b9ed55e8828231861aacc3042a42d7005cd1d75b28c3c31
|
7
|
+
data.tar.gz: f3b841c4ac7199cebe533c8f0bc9f53afcdb833c6f5cd673c19230d1bef243d110f1f0db91380a79dfd9234bf8120b7536bb2b4d67414823d3d9fe52d9fcba90
|
data/lib/unicorn/http_request.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
# :enddoc:
|
3
3
|
# no stable API here
|
4
4
|
require 'unicorn_http'
|
5
|
+
require 'raindrops'
|
5
6
|
|
6
7
|
# TODO: remove redundant names
|
7
8
|
Unicorn.const_set(:HttpRequest, Unicorn::HttpParser)
|
@@ -25,8 +26,10 @@ class Unicorn::HttpParser
|
|
25
26
|
|
26
27
|
# :stopdoc:
|
27
28
|
HTTP_RESPONSE_START = [ 'HTTP'.freeze, '/1.1 '.freeze ]
|
29
|
+
EMPTY_ARRAY = [].freeze
|
28
30
|
@@input_class = Unicorn::TeeInput
|
29
31
|
@@check_client_connection = false
|
32
|
+
@@tcpi_inspect_ok = true
|
30
33
|
|
31
34
|
def self.input_class
|
32
35
|
@@input_class
|
@@ -80,11 +83,7 @@ class Unicorn::HttpParser
|
|
80
83
|
false until add_parse(socket.kgio_read!(16384))
|
81
84
|
end
|
82
85
|
|
83
|
-
|
84
|
-
if @@check_client_connection && headers?
|
85
|
-
self.response_start_sent = true
|
86
|
-
HTTP_RESPONSE_START.each { |c| socket.write(c) }
|
87
|
-
end
|
86
|
+
check_client_connection(socket) if @@check_client_connection
|
88
87
|
|
89
88
|
e['rack.input'] = 0 == content_length ?
|
90
89
|
NULL_IO : @@input_class.new(socket, self)
|
@@ -105,4 +104,68 @@ class Unicorn::HttpParser
|
|
105
104
|
def hijacked?
|
106
105
|
env.include?('rack.hijack_io'.freeze)
|
107
106
|
end
|
107
|
+
|
108
|
+
if defined?(Raindrops::TCP_Info)
|
109
|
+
def check_client_connection(socket) # :nodoc:
|
110
|
+
if Unicorn::TCPClient === socket
|
111
|
+
@@tcp_info ||= Raindrops::TCP_Info.new(socket)
|
112
|
+
@@tcp_info.get!(socket)
|
113
|
+
raise Errno::EPIPE, "client closed connection".freeze,
|
114
|
+
EMPTY_ARRAY if closed_state?(@@tcp_info.state)
|
115
|
+
else
|
116
|
+
write_http_header(socket)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def closed_state?(state) # :nodoc:
|
121
|
+
case state
|
122
|
+
when 1 # ESTABLISHED
|
123
|
+
false
|
124
|
+
when 8, 6, 7, 9, 11 # CLOSE_WAIT, TIME_WAIT, CLOSE, LAST_ACK, CLOSING
|
125
|
+
true
|
126
|
+
else
|
127
|
+
false
|
128
|
+
end
|
129
|
+
end
|
130
|
+
else
|
131
|
+
|
132
|
+
# Ruby 2.2+ can show struct tcp_info as a string Socket::Option#inspect.
|
133
|
+
# Not that efficient, but probably still better than doing unnecessary
|
134
|
+
# work after a client gives up.
|
135
|
+
def check_client_connection(socket) # :nodoc:
|
136
|
+
if Unicorn::TCPClient === socket && @@tcpi_inspect_ok
|
137
|
+
opt = socket.getsockopt(:IPPROTO_TCP, :TCP_INFO).inspect
|
138
|
+
if opt =~ /\bstate=(\S+)/
|
139
|
+
@@tcpi_inspect_ok = true
|
140
|
+
raise Errno::EPIPE, "client closed connection".freeze,
|
141
|
+
EMPTY_ARRAY if closed_state_str?($1)
|
142
|
+
else
|
143
|
+
@@tcpi_inspect_ok = false
|
144
|
+
write_http_header(socket)
|
145
|
+
end
|
146
|
+
opt.clear
|
147
|
+
else
|
148
|
+
write_http_header(socket)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def closed_state_str?(state)
|
153
|
+
case state
|
154
|
+
when 'ESTABLISHED'
|
155
|
+
false
|
156
|
+
# not a typo, ruby maps TCP_CLOSE (no 'D') to state=CLOSED (w/ 'D')
|
157
|
+
when 'CLOSE_WAIT', 'TIME_WAIT', 'CLOSED', 'LAST_ACK', 'CLOSING'
|
158
|
+
true
|
159
|
+
else
|
160
|
+
false
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def write_http_header(socket) # :nodoc:
|
166
|
+
if headers?
|
167
|
+
self.response_start_sent = true
|
168
|
+
HTTP_RESPONSE_START.each { |c| socket.write(c) }
|
169
|
+
end
|
170
|
+
end
|
108
171
|
end
|
data/lib/unicorn/http_server.rb
CHANGED
@@ -534,7 +534,7 @@ class Unicorn::HttpServer
|
|
534
534
|
def handle_error(client, e)
|
535
535
|
code = case e
|
536
536
|
when EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::ENOTCONN
|
537
|
-
Unicorn.log_error(@logger, "client disconnected", e)
|
537
|
+
Unicorn.log_error(@logger, "client disconnected", e.class.new)
|
538
538
|
# client disconnected on us and there's nothing we can do
|
539
539
|
when Unicorn::RequestURITooLongError
|
540
540
|
414
|
@@ -3,6 +3,18 @@
|
|
3
3
|
require 'socket'
|
4
4
|
|
5
5
|
module Unicorn
|
6
|
+
|
7
|
+
# Instead of using a generic Kgio::Socket for everything,
|
8
|
+
# tag TCP sockets so we can use TCP_INFO under Linux without
|
9
|
+
# incurring extra syscalls for Unix domain sockets.
|
10
|
+
# TODO: remove these when we remove kgio
|
11
|
+
TCPClient = Class.new(Kgio::Socket) # :nodoc:
|
12
|
+
class TCPSrv < Kgio::TCPServer # :nodoc:
|
13
|
+
def kgio_tryaccept # :nodoc:
|
14
|
+
super(TCPClient)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
6
18
|
module SocketHelper
|
7
19
|
|
8
20
|
# internal interface
|
@@ -148,7 +160,7 @@ module Unicorn
|
|
148
160
|
end
|
149
161
|
sock.bind(Socket.pack_sockaddr_in(port, addr))
|
150
162
|
sock.autoclose = false
|
151
|
-
|
163
|
+
TCPSrv.for_fd(sock.fileno)
|
152
164
|
end
|
153
165
|
|
154
166
|
# returns rfc2732-style (e.g. "[::1]:666") addresses for IPv6
|
@@ -185,7 +197,7 @@ module Unicorn
|
|
185
197
|
def server_cast(sock)
|
186
198
|
begin
|
187
199
|
Socket.unpack_sockaddr_in(sock.getsockname)
|
188
|
-
|
200
|
+
TCPSrv.for_fd(sock.fileno)
|
189
201
|
rescue ArgumentError
|
190
202
|
Kgio::UNIXServer.for_fd(sock.fileno)
|
191
203
|
end
|