spider-gazelle 3.0.2 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1eb9ae4b8211936cdaf58a02132000044bb58ae3
4
- data.tar.gz: 7044a353674ec95eb7aea471e1fc619641b4ec15
3
+ metadata.gz: 89774225b2801a3f2556563940da21588a6fef70
4
+ data.tar.gz: 441d840391e7ccb87d98b4bd2830b80a2ed6b1e6
5
5
  SHA512:
6
- metadata.gz: deff3abf19ba3fdf58250e0b47b27658b4ec183cc5ee5d8f3860c47563314a144aeed2e4efd40de1157d4777976fbfd962fdd74c280d1882264c1b038306a24c
7
- data.tar.gz: 72d2d3b04dc181fd1f39d97425123664d2b5c4c2886f2e50d74cd58751231414b2a2de99ecfe82a77a5b711e0586eb775e14080e360ad5a3a8629412d6f0d37b
6
+ metadata.gz: 96c3c3b76bf21d2756db7e9b51a50f4125ed26a8b60f12ba8e789b0e73aff65ccdd0a933254485bb600f340ce82b42f9bc8c324deb27eec29a1f14002c762712
7
+ data.tar.gz: 1208f6382502b44b2f02099fd527441d0e923100c7c26801fd5582a48fb53c698d25672e7b85f4f95ddd159ca7c29d7570523bf514b389a64fdbf137855d75b4
@@ -62,13 +62,12 @@ module SpiderGazelle
62
62
  end
63
63
 
64
64
  PROTOCOLS = ['h2', 'http/1.1'].freeze
65
- FALLBACK = 'http/1.1'
66
65
  def self.configure_tls(opts)
67
66
  return false unless opts[:tls]
68
67
 
69
68
  tls = {
70
69
  protocols: PROTOCOLS,
71
- fallback: FALLBACK
70
+ fallback: 'http/1.1'
72
71
  }
73
72
  tls[:verify_peer] = true if opts[:verify_peer]
74
73
  tls[:ciphers] = opts[:ciphers] if opts[:ciphers]
@@ -31,11 +31,6 @@ module SpiderGazelle
31
31
  req.header.frozen? ? req.header = header : req.header << header
32
32
  end
33
33
 
34
- DASH = '-'
35
- UNDERSCORE = '_'
36
- HTTP_META = 'HTTP_'
37
- COMMA = ', '
38
-
39
34
  def on_header_value(parser, value)
40
35
  req = @connection.parsing
41
36
  if req.header.frozen?
@@ -43,11 +38,11 @@ module SpiderGazelle
43
38
  else
44
39
  header = req.header
45
40
  header.upcase!
46
- header.gsub!(DASH, UNDERSCORE)
47
- header.prepend(HTTP_META)
41
+ header.gsub!('-', '_')
42
+ header.prepend('HTTP_')
48
43
  header.freeze
49
44
  if req.env[header]
50
- req.env[header] << COMMA
45
+ req.env[header] << ', '
51
46
  req.env[header] << value
52
47
  else
53
48
  req.env[header] = String.new(value)
@@ -99,16 +94,13 @@ module SpiderGazelle
99
94
  def self.on_progress(data, socket); end
100
95
  DUMMY_PROGRESS = self.method :on_progress
101
96
 
102
- HTTP = 'http'
103
- HTTPS = 'https'
104
-
105
97
  def load(socket, port, app, tls)
106
98
  @socket = socket
107
99
  @port = port
108
100
  @app = app
109
101
 
110
102
  @remote_ip = socket.peername[0]
111
- @scheme = tls ? HTTPS : HTTP
103
+ @scheme = tls ? 'https' : 'http'
112
104
 
113
105
  set_on_close(socket)
114
106
  end
@@ -161,12 +153,10 @@ module SpiderGazelle
161
153
  @parsing = Request.new @thread, @app, @port, @remote_ip, @scheme, @socket
162
154
  end
163
155
 
164
- REQUEST_METHOD = 'REQUEST_METHOD'
165
156
  def headers_complete
166
- @parsing.env[REQUEST_METHOD] = @state.http_method.to_s
157
+ @parsing.env['REQUEST_METHOD'] = @state.http_method.to_s
167
158
  end
168
159
 
169
- ASYNC = "async.callback"
170
160
  def finished_parsing
171
161
  request = @parsing
172
162
  @parsing = nil
@@ -180,7 +170,7 @@ module SpiderGazelle
180
170
  # Process the async request in the same way as Mizuno
181
171
  # See: http://polycrystal.org/2012/04/15/asynchronous_responses_in_rack.html
182
172
  # Process a response that was marked as async.
183
- request.env[ASYNC] = proc { |data|
173
+ request.env['async.callback'] = proc { |data|
184
174
  @thread.schedule { request.defer.resolve([request, data]) }
185
175
  }
186
176
  request.upgrade = @state.upgrade?
@@ -235,16 +225,6 @@ module SpiderGazelle
235
225
  process_next
236
226
  end
237
227
 
238
-
239
- HEAD = 'HEAD'
240
- ETAG = 'ETag'
241
- HTTP_ETAG = 'HTTP_ETAG'
242
- CONTENT_LENGTH2 = 'Content-Length'
243
- TRANSFER_ENCODING = 'Transfer-Encoding'
244
- CHUNKED = 'chunked'
245
- ZERO = '0'
246
- NOT_MODIFIED_304 = "HTTP/1.1 304 Not Modified\r\n"
247
-
248
228
  def send_next_response
249
229
  request, result = @responses.shift
250
230
  @transmitting = request
@@ -262,7 +242,7 @@ module SpiderGazelle
262
242
  body.close if body.respond_to?(:close)
263
243
  else
264
244
  status, headers, body = result
265
- send_body = request.env[REQUEST_METHOD] != HEAD
245
+ send_body = request.env['REQUEST_METHOD'] != 'HEAD'
266
246
 
267
247
  # If a file, stream the body in a non-blocking fashion
268
248
  if body.respond_to? :to_path
@@ -280,17 +260,17 @@ module SpiderGazelle
280
260
  #if etag == request.env[HTTP_ETAG]
281
261
  # header = NOT_MODIFIED_304.dup
282
262
  # add_header(header, ETAG, etag)
283
- # header << LINE_END
263
+ # header << "\r\n"
284
264
  # @socket.write header
285
265
  # return
286
266
  #end
287
267
  #headers[ETAG] ||= etag
288
268
 
289
- if headers[CONTENT_LENGTH2]
269
+ if headers['Content-Length']
290
270
  type = :raw
291
271
  else
292
272
  type = :http
293
- headers[TRANSFER_ENCODING] = CHUNKED
273
+ headers['Transfer-Encoding'] = 'chunked'
294
274
  end
295
275
 
296
276
  data_written = true
@@ -339,7 +319,7 @@ module SpiderGazelle
339
319
  # Optimize the response
340
320
  begin
341
321
  if body.size < 2
342
- headers[CONTENT_LENGTH2] = body.size == 1 ? body[0].bytesize.to_s : ZERO
322
+ headers['Content-Length'] = body.size == 1 ? body[0].bytesize.to_s : '0'
343
323
  end
344
324
  rescue # just in case
345
325
  end
@@ -359,59 +339,51 @@ module SpiderGazelle
359
339
  end
360
340
  end
361
341
 
362
- CLOSE_CHUNKED = "0\r\n\r\n"
363
342
  def write_response(request, status, headers, body)
364
343
  keep_alive = request.keep_alive
365
344
 
366
- if headers[CONTENT_LENGTH2]
367
- headers[CONTENT_LENGTH2] = headers[CONTENT_LENGTH2].to_s
345
+ if headers['Content-Length']
346
+ headers['Content-Length'] = headers['Content-Length'].to_s
368
347
  write_headers keep_alive, status, headers
369
348
 
370
349
  # Stream the response (pass directly into @socket.write)
371
350
  body.each &@socket.method(:write)
372
351
  @socket.shutdown if keep_alive == false
373
352
  else
374
- headers[TRANSFER_ENCODING] = CHUNKED
353
+ headers['Transfer-Encoding'] = 'chunked'
375
354
  write_headers keep_alive, status, headers
376
355
 
377
356
  # Stream the response
378
357
  body.each &@write_chunk
379
358
 
380
- @socket.write CLOSE_CHUNKED
359
+ @socket.write "0\r\n\r\n"
381
360
  @socket.shutdown if keep_alive == false
382
361
  end
383
362
 
384
363
  body.close if body.respond_to?(:close)
385
364
  end
386
365
 
387
- COLON_SPACE = ': '
388
- LINE_END = "\r\n"
389
366
  def add_header(header, key, value)
390
367
  header << key
391
- header << COLON_SPACE
368
+ header << ': '
392
369
  header << value
393
- header << LINE_END
370
+ header << "\r\n"
394
371
  end
395
372
 
396
- CONNECTION = "Connection"
397
- NEWLINE = "\n"
398
- CLOSE = "close"
399
- RACK = "rack"
400
373
  def write_headers(keep_alive, status, headers)
401
- headers[CONNECTION] = CLOSE if keep_alive == false
374
+ headers['Connection'] = 'close' if keep_alive == false
402
375
 
403
376
  header = String.new("HTTP/1.1 #{status} #{fetch_code(status)}\r\n")
404
377
  headers.each do |key, value|
405
- next if key.start_with? RACK
406
- value.to_s.split(NEWLINE).each {|val| add_header(header, key, val)}
378
+ next if key.start_with? 'rack'
379
+ value.to_s.split("\n").each {|val| add_header(header, key, val)}
407
380
  end
408
- header << LINE_END
381
+ header << "\r\n"
409
382
  @socket.write header
410
383
  end
411
384
 
412
- HEX_ENCODED = 16
413
385
  def write_chunk(part)
414
- chunk = part.bytesize.to_s(HEX_ENCODED) << LINE_END << part << LINE_END
386
+ chunk = part.bytesize.to_s(16) << "\r\n" << part << "\r\n"
415
387
  @socket.write chunk
416
388
  end
417
389
 
@@ -446,19 +418,17 @@ module SpiderGazelle
446
418
  end
447
419
  end
448
420
 
449
- ERROR_400_RESPONSE = "HTTP/1.1 400 Bad Request\r\nConnection: close\r\nContent-Length: 0\r\n\r\n"
450
421
  def send_parsing_error
451
422
  @logger.info "Parsing error!"
452
423
  @socket.stop_read
453
- @socket.write ERROR_400_RESPONSE
424
+ @socket.write "HTTP/1.1 400 Bad Request\r\nConnection: close\r\nContent-Length: 0\r\n\r\n"
454
425
  @socket.shutdown
455
426
  end
456
427
 
457
- ERROR_500_RESPONSE = "HTTP/1.1 500 Internal Server Error\r\nConnection: close\r\nContent-Length: 0\r\n\r\n"
458
428
  def send_internal_error
459
429
  @logger.info "Internal error"
460
430
  @socket.stop_read
461
- @socket.write ERROR_500_RESPONSE
431
+ @socket.write "HTTP/1.1 500 Internal Server Error\r\nConnection: close\r\nContent-Length: 0\r\n\r\n"
462
432
  @socket.shutdown
463
433
  end
464
434
  end
@@ -5,46 +5,26 @@ require 'rack' # Ruby webserver abstraction
5
5
 
6
6
  module SpiderGazelle
7
7
  class Request < ::Libuv::Q::DeferredPromise
8
- RACK_VERSION = 'rack.version'
9
- RACK_ERRORS = 'rack.errors'
10
- RACK_MULTITHREAD = "rack.multithread"
11
- RACK_MULTIPROCESS = "rack.multiprocess"
12
- RACK_RUN_ONCE = "rack.run_once"
13
- SCRIPT_NAME = "SCRIPT_NAME"
14
- EMPTY = ''
15
- SERVER_PROTOCOL = "SERVER_PROTOCOL"
16
- HTTP_11 = "HTTP/1.1"
17
- SERVER_SOFTWARE = "SERVER_SOFTWARE"
18
- GATEWAY_INTERFACE = "GATEWAY_INTERFACE"
19
- CGI_VER = "CGI/1.2"
20
- SERVER = "SpiderGazelle"
21
- LOCALHOST = 'localhost'
22
-
23
8
 
24
9
  # TODO:: Add HTTP headers to the env and capitalise them and prefix them with HTTP_
25
10
  # convert - signs to underscores
26
11
  PROTO_ENV = {
27
- RACK_VERSION => ::Rack::VERSION, # Should be an array of integers
28
- RACK_ERRORS => $stderr, # An error stream that supports: puts, write and flush
29
- RACK_MULTITHREAD => true, # can the app be simultaneously invoked by another thread?
30
- RACK_MULTIPROCESS => true, # will the app be simultaneously be invoked in a separate process?
31
- RACK_RUN_ONCE => false, # this isn't CGI so will always be false
32
-
33
- SCRIPT_NAME => ENV['SCRIPT_NAME'] || EMPTY, # The virtual path of the app base (empty if root)
34
- SERVER_PROTOCOL => HTTP_11,
35
-
36
- GATEWAY_INTERFACE => CGI_VER,
37
- SERVER_SOFTWARE => SERVER
12
+ 'rack.version' => ::Rack::VERSION, # Should be an array of integers
13
+ 'rack.errors' => $stderr, # An error stream that supports: puts, write and flush
14
+ 'rack.multithread' => true, # can the app be simultaneously invoked by another thread?
15
+ 'rack.multiprocess' => false, # will the app be simultaneously be invoked in a separate process?
16
+ 'rack.run_once' => false, # this isn't CGI so will always be false
17
+ 'SCRIPT_NAME' => ENV['SCRIPT_NAME'] || '', # The virtual path of the app base (empty if root)
18
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
19
+
20
+ 'GATEWAY_INTERFACE' => 'CGI/1.2',
21
+ 'SERVER_SOFTWARE' => 'SpiderGazelle'
38
22
  }
39
23
 
40
24
  attr_accessor :env, :url, :header, :body, :keep_alive, :upgrade
41
25
  attr_reader :hijacked, :defer, :is_async
42
26
 
43
27
 
44
- SERVER_PORT = "SERVER_PORT"
45
- REMOTE_ADDR = "REMOTE_ADDR"
46
- RACK_URL_SCHEME = "rack.url_scheme"
47
-
48
28
  def initialize(thread, app, port, remote_ip, scheme, socket)
49
29
  super(thread, thread.defer)
50
30
 
@@ -54,81 +34,53 @@ module SpiderGazelle
54
34
  @header = String.new
55
35
  @url = String.new
56
36
  @env = PROTO_ENV.dup
57
- @env[SERVER_PORT] = port
58
- @env[REMOTE_ADDR] = remote_ip
59
- @env[RACK_URL_SCHEME] = scheme
37
+ @env['SERVER_PORT'] = port
38
+ @env['REMOTE_ADDR'] = remote_ip
39
+ @env['rack.url_scheme'] = scheme
60
40
  end
61
-
62
-
63
- CONTENT_LENGTH = "CONTENT_LENGTH"
64
- HTTP_CONTENT_LENGTH = "HTTP_CONTENT_LENGTH"
65
- CONTENT_TYPE = "CONTENT_TYPE"
66
- HTTP_CONTENT_TYPE = "HTTP_CONTENT_TYPE"
67
- DEFAULT_TYPE = "text/plain"
68
- REQUEST_URI= "REQUEST_URI"
69
- ASCII_8BIT = "ASCII-8BIT"
70
- RACK_INPUT = "rack.input"
71
- PATH_INFO = "PATH_INFO"
72
- REQUEST_PATH = "REQUEST_PATH"
73
- QUERY_STRING = "QUERY_STRING"
74
- HTTP_HOST = "HTTP_HOST"
75
- COLON = ":"
76
- SERVER_NAME = "SERVER_NAME"
77
- # Hijacking IO is supported
78
- HIJACK_P = "rack.hijack?"
79
- # Callback for indicating that this socket will be hijacked
80
- HIJACK = "rack.hijack"
81
- # The object for performing IO on after hijack is called
82
- HIJACK_IO = "rack.hijack_io"
83
- QUESTION_MARK = "?"
84
41
 
85
- HTTP_UPGRADE = 'HTTP_UPGRADE'
86
- USE_HTTP2 = 'h2c'
87
-
88
-
89
-
90
42
 
91
43
  def execute!
92
- @env[CONTENT_LENGTH] = @env.delete(HTTP_CONTENT_LENGTH) || @body.bytesize.to_s
93
- @env[CONTENT_TYPE] = @env.delete(HTTP_CONTENT_TYPE) || DEFAULT_TYPE
94
- @env[REQUEST_URI] = @url.freeze
44
+ @env['CONTENT_LENGTH'] = @env.delete('HTTP_CONTENT_LENGTH') || @body.bytesize.to_s
45
+ @env['CONTENT_TYPE'] = @env.delete('HTTP_CONTENT_TYPE') || 'text/plain'
46
+ @env['REQUEST_URI'] = @url.freeze
95
47
 
96
48
  # For Rack::Lint on 1.9, ensure that the encoding is always for spec
97
- @body.force_encoding(ASCII_8BIT)
98
- @env[RACK_INPUT] = StringIO.new @body
49
+ @body.force_encoding(Encoding::ASCII_8BIT)
50
+ @env['rack.input'] = StringIO.new @body
99
51
 
100
52
  # Break the request into its components
101
- query_start = @url.index QUESTION_MARK
53
+ query_start = @url.index '?'
102
54
  if query_start
103
55
  path = @url[0...query_start].freeze
104
- @env[PATH_INFO] = path
105
- @env[REQUEST_PATH] = path
106
- @env[QUERY_STRING] = @url[query_start + 1..-1].freeze
56
+ @env['PATH_INFO'] = path
57
+ @env['REQUEST_PATH'] = path
58
+ @env['QUERY_STRING'] = @url[query_start + 1..-1].freeze
107
59
  else
108
- @env[PATH_INFO] = @url
109
- @env[REQUEST_PATH] = @url
110
- @env[QUERY_STRING] = EMPTY
60
+ @env['PATH_INFO'] = @url
61
+ @env['REQUEST_PATH'] = @url
62
+ @env['QUERY_STRING'] = ''
111
63
  end
112
64
 
113
65
  # Grab the host name from the request
114
- if host = @env[HTTP_HOST]
115
- if colon = host.index(COLON)
116
- @env[SERVER_NAME] = host[0, colon]
117
- @env[SERVER_PORT] = host[colon + 1, host.bytesize]
66
+ if host = @env['HTTP_HOST']
67
+ if colon = host.index(':')
68
+ @env['SERVER_NAME'] = host[0, colon]
69
+ @env['SERVER_PORT'] = host[colon + 1, host.bytesize]
118
70
  else
119
- @env[SERVER_NAME] = host
71
+ @env['SERVER_NAME'] = host
120
72
  end
121
73
  else
122
- @env[SERVER_NAME] = LOCALHOST
74
+ @env['SERVER_NAME'] = 'localhost'
123
75
  end
124
76
 
125
- if @upgrade == true && @env[HTTP_UPGRADE] == USE_HTTP2
77
+ if @upgrade == true && @env['HTTP_UPGRADE'] == 'h2c'
126
78
  # TODO:: implement the upgrade process here
127
79
  end
128
80
 
129
81
  # Provide hijack options
130
- @env[HIJACK_P] = true
131
- @env[HIJACK] = proc { @env[HIJACK_IO] = @socket }
82
+ @env['rack.hijack?'] = true
83
+ @env['rack.hijack'] = proc { @env['rack.hijack_io'] = @socket }
132
84
 
133
85
  # Execute the request
134
86
  # NOTE:: Catch was overloaded by Promise so this does the trick now
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SpiderGazelle
4
- VERSION = '3.0.2'
4
+ VERSION = '3.0.3'
5
5
  EXEC_NAME = 'sg'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spider-gazelle
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.2
4
+ version: 3.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen von Takach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-14 00:00:00.000000000 Z
11
+ date: 2016-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http-parser