ruby_wolf 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 14d13bd7de3c5cca903738aefbe18c1d9e512a49
4
- data.tar.gz: e92866e154a80c358571348ebedbcc3fa7c0038b
3
+ metadata.gz: d60914f1d8dd41e9242834687e19f41409036932
4
+ data.tar.gz: 8a51798908bce2046da3d23bd7845af237df05d9
5
5
  SHA512:
6
- metadata.gz: 18c7b7288ab955e023beaf8de4a58fd763d68712fbe1b3589280b8c9899ee621a20bab20d1c6c666644597d1522428958a4397b373175c50a37586cf75ebb55b
7
- data.tar.gz: 238eadfe11529cae062586465abf71ec3b72df78d4f5cf24a8822265663158c9d2e67d4b132c6682643a7b4309e536d1ff1d61194432809ca80602d84ec61b08
6
+ metadata.gz: 5fc70290442f8fef6ff599bd3d21f2421851e8dd384a5cdb37333c765958d95d92a6f7bf040c24019d16984fe0cba16fc37a0b4fd4ed191b5f2eb28e08bac0de
7
+ data.tar.gz: 9ebfa97ef988cbe019d2a11e707d21f8245d0f8339e3ac580fdb7bea5065d493598d5fc7b525894e658c435e18785c7fd9c5574abdb753cddff49b8b749e7aec
@@ -1,13 +1,14 @@
1
1
  module RubyWolf
2
2
  class Connection
3
- attr_reader :socket, :read_data, :write_data
3
+ attr_reader :socket, :read_chunk, :write_chunk, :headers, :body, :path, :query, :method
4
4
 
5
5
  def initialize(socket)
6
6
  @socket = socket
7
- @read_data = ''
8
- @write_data = ''
9
-
7
+ @read_chunk = ''
8
+ @write_chunk = ''
10
9
  @reading = true
10
+
11
+ @headers = {}
11
12
  end
12
13
 
13
14
  def need_to_read?
@@ -15,23 +16,27 @@ module RubyWolf
15
16
  end
16
17
 
17
18
  def read
18
- @read_data << socket.read_nonblock(RubyWolf::READ_SIZE)
19
- @reading = false if @read_data.end_with?(RubyWolf::CRLF)
19
+ @read_chunk << socket.read_nonblock(RubyWolf::READ_SIZE)
20
+ if @content_length.nil?
21
+ read_headers
22
+ else
23
+ read_body
24
+ end
20
25
  rescue EOFError
21
26
  @reading = false
22
27
  end
23
28
 
24
29
  def enqueue_write(data)
25
- @write_data += data
30
+ @write_chunk += data
26
31
  end
27
32
 
28
33
  def write
29
- writen = socket.write_nonblock(@write_data)
30
- @write_data[0..writen] = ''
34
+ writen = socket.write_nonblock(@write_chunk)
35
+ @write_chunk = @write_chunk.byteslice(writen, @write_chunk.bytesize)
31
36
  end
32
37
 
33
38
  def need_to_write?
34
- !@write_data.length.zero?
39
+ !@write_chunk.bytesize.zero?
35
40
  end
36
41
 
37
42
  def to_io
@@ -41,5 +46,36 @@ module RubyWolf
41
46
  def close
42
47
  @socket.close
43
48
  end
49
+
50
+ private
51
+
52
+ def read_headers
53
+ header_ending = @read_chunk.index(RubyWolf::HEADER_ENDING)
54
+ return if header_ending.nil?
55
+
56
+ headers_chunk = @read_chunk.slice!(
57
+ 0, header_ending + RubyWolf::HEADER_ENDING.size
58
+ )
59
+ parse_headers(headers_chunk)
60
+ @content_length = @headers['Content-Length'].to_i
61
+ read_body
62
+ end
63
+
64
+ def parse_headers(headers_chunk)
65
+ parser = Http::Parser.new
66
+ parser.on_headers_complete = proc do
67
+ @headers = parser.headers
68
+ @method = parser.http_method
69
+ uri = URI.parse(parser.request_url)
70
+ @path = uri.path
71
+ @query = uri.query
72
+ :stop
73
+ end
74
+ parser << headers_chunk
75
+ end
76
+
77
+ def read_body
78
+ @reading = false if @read_chunk.bytesize >= @content_length
79
+ end
44
80
  end
45
81
  end
@@ -15,7 +15,6 @@ module RubyWolf
15
15
 
16
16
  def process
17
17
  prepare_rack_env
18
- parse_request
19
18
  generate_response
20
19
  callback.call(response) if callback
21
20
  response
@@ -24,37 +23,36 @@ module RubyWolf
24
23
  private
25
24
 
26
25
  def prepare_rack_env
27
- @env = ENV.to_h
28
- @env.delete 'HTTP_CONTENT_LENGTH'
29
- url_scheme = %w(yes on 1).include?(ENV[::Rack::HTTPS]) ? 'https' : 'http'
30
- @env.update(
31
- ::Rack::RACK_VERSION => ::Rack::VERSION,
32
- ::Rack::RACK_INPUT => STDIN,
33
- ::Rack::RACK_ERRORS => STDERR,
34
- ::Rack::RACK_MULTITHREAD => false,
35
- ::Rack::RACK_MULTIPROCESS => true,
36
- ::Rack::RACK_RUNONCE => true,
37
- ::Rack::RACK_URL_SCHEME => url_scheme,
38
- ::Rack::SERVER_PROTOCOL => 'HTTP/1.1'
39
- )
40
- end
26
+ @env = ENV.to_h.merge(
27
+ 'rack.version' => ::Rack::VERSION,
28
+ 'rack.errors' => STDERR,
29
+ 'rack.multithread' => false,
30
+ 'rack.multiprocess' => true,
31
+ 'rack.runonce' => true,
32
+ 'rack.url_scheme' => ENV['HTTPS'] ? 'https' : 'http',
41
33
 
42
- def parse_request
43
- parser = Http::Parser.new
44
- parser.on_headers_complete = proc do
45
- env[::Rack::HTTP_VERSION] = parser.http_version
46
- env[::Rack::REQUEST_METHOD] = parser.http_method
34
+ 'REQUEST_METHOD' => connection.method,
35
+ 'REQUEST_PATH' => connection.path,
36
+ 'PATH_INFO' => connection.path,
37
+ 'QUERY_STRING' => connection.query,
38
+
39
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
40
+ 'SERVER_NAME' => 'Ruby Wolf',
41
+ 'HTTP_VERSION' => 'HTTP/1.1',
42
+ 'HTTP_HOST' => connection.headers['Host'],
43
+ 'HTTP_USER_AGENT' => connection.headers['User-Agent'],
44
+ 'HTTP_ACCEPT' => connection.headers['Accept'],
45
+ 'CONTENT_LENGTH' => connection.headers['Content-Length'],
46
+ 'CONTENT_TYPE' => connection.headers['Content-Type'],
47
+
48
+ 'rack.input' => StringIO.new(connection.read_chunk)
49
+ )
47
50
 
48
- uri = URI.parse(parser.request_url)
49
- env[::Rack::REQUEST_PATH] = uri.path
50
- env[::Rack::QUERY_STRING] = uri.query
51
- end
52
- parser << connection.read_data
53
51
  RubyWolf.log(
54
52
  [
55
- "HTTP/#{env[::Rack::HTTP_VERSION].join('.')}",
56
- env[::Rack::REQUEST_METHOD],
57
- "#{env[::Rack::REQUEST_PATH]}?#{env[::Rack::QUERY_STRING]}"
53
+ 'HTTP/1.1',
54
+ connection.method,
55
+ "#{connection.path}?#{connection.query}"
58
56
  ].join(' ')
59
57
  )
60
58
  end
@@ -62,13 +60,13 @@ module RubyWolf
62
60
  def generate_response
63
61
  status, headers, body = app.call(env)
64
62
  RubyWolf.log(
65
- "Response #{env[::Rack::SERVER_PROTOCOL]} #{status}"
63
+ "Response HTTP/1.1 #{status}"
66
64
  )
67
65
  compose_response(status, headers, body)
68
66
  end
69
67
 
70
68
  def compose_response(status, headers, body)
71
- @response += "#{env[::Rack::SERVER_PROTOCOL]} #{status} #{RubyWolf::CRLF}"
69
+ @response += "HTTP/1.1 #{status} #{RubyWolf::CRLF}"
72
70
  headers.each do |key, value|
73
71
  @response += "#{key}: #{value}#{RubyWolf::CRLF}"
74
72
  end
@@ -1,3 +1,3 @@
1
1
  module RubyWolf
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/ruby_wolf.rb CHANGED
@@ -12,6 +12,7 @@ require 'ruby_wolf/cli'
12
12
  module RubyWolf
13
13
  MAIN_PID = Process.pid
14
14
  CRLF = "\r\n".freeze
15
+ HEADER_ENDING = "\r\n\r\n".freeze
15
16
  READ_SIZE = 16 * 1024
16
17
 
17
18
  def self.logger
data/ruby_wolf.gemspec CHANGED
@@ -20,9 +20,8 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = ['ruby_wolf']
21
21
  spec.require_paths = ['lib']
22
22
 
23
- spec.add_development_dependency 'rspec', '~>3.5.0', '>=3.5.0'
24
- spec.add_development_dependency 'byebug', '~>9.0.0', '>=8.0.0'
23
+ spec.add_development_dependency 'rspec', '~>3.5', '>=3.5.0'
24
+ spec.add_development_dependency 'byebug', '~>9.0', '>=9.0.0'
25
25
 
26
- spec.add_runtime_dependency 'rack', '~>2.0.0', '>=2.0.0'
27
- spec.add_runtime_dependency 'http_parser.rb', '~>0.6.0', '>=0.6.0'
26
+ spec.add_runtime_dependency 'http_parser.rb', '~>0.6', '>=0.6.0'
28
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_wolf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nguyễn Quang Minh
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 3.5.0
19
+ version: '3.5'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
22
  version: 3.5.0
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: 3.5.0
29
+ version: '3.5'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 3.5.0
@@ -36,47 +36,27 @@ dependencies:
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 9.0.0
39
+ version: '9.0'
40
40
  - - ">="
41
- - !ruby/object:Gem::Version
42
- version: 8.0.0
43
- type: :development
44
- prerelease: false
45
- version_requirements: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - "~>"
48
41
  - !ruby/object:Gem::Version
49
42
  version: 9.0.0
50
- - - ">="
51
- - !ruby/object:Gem::Version
52
- version: 8.0.0
53
- - !ruby/object:Gem::Dependency
54
- name: rack
55
- requirement: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - "~>"
58
- - !ruby/object:Gem::Version
59
- version: 2.0.0
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: 2.0.0
63
- type: :runtime
43
+ type: :development
64
44
  prerelease: false
65
45
  version_requirements: !ruby/object:Gem::Requirement
66
46
  requirements:
67
47
  - - "~>"
68
48
  - !ruby/object:Gem::Version
69
- version: 2.0.0
49
+ version: '9.0'
70
50
  - - ">="
71
51
  - !ruby/object:Gem::Version
72
- version: 2.0.0
52
+ version: 9.0.0
73
53
  - !ruby/object:Gem::Dependency
74
54
  name: http_parser.rb
75
55
  requirement: !ruby/object:Gem::Requirement
76
56
  requirements:
77
57
  - - "~>"
78
58
  - !ruby/object:Gem::Version
79
- version: 0.6.0
59
+ version: '0.6'
80
60
  - - ">="
81
61
  - !ruby/object:Gem::Version
82
62
  version: 0.6.0
@@ -86,7 +66,7 @@ dependencies:
86
66
  requirements:
87
67
  - - "~>"
88
68
  - !ruby/object:Gem::Version
89
- version: 0.6.0
69
+ version: '0.6'
90
70
  - - ">="
91
71
  - !ruby/object:Gem::Version
92
72
  version: 0.6.0