hatetepe 0.5.2 → 0.6.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.rspec +3 -0
- data/.travis.yml +4 -0
- data/.yardopts +1 -0
- data/Gemfile +9 -4
- data/Gemfile.devtools +55 -0
- data/LICENSE.txt +22 -0
- data/README.md +39 -192
- data/Rakefile +3 -2
- data/bin/hatetepe +35 -2
- data/config/devtools.yml +2 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +3 -0
- data/config/reek.yml +103 -0
- data/config/rubocop.yml +58 -0
- data/config/yardstick.yml +2 -0
- data/hatetepe.gemspec +23 -27
- data/lib/hatetepe/client/keep_alive.rb +59 -0
- data/lib/hatetepe/client/timeouts.rb +19 -0
- data/lib/hatetepe/client.rb +54 -302
- data/lib/hatetepe/connection/eventmachine.rb +61 -0
- data/lib/hatetepe/connection/status.rb +28 -0
- data/lib/hatetepe/errors.rb +7 -0
- data/lib/hatetepe/promise.rb +86 -0
- data/lib/hatetepe/request.rb +15 -39
- data/lib/hatetepe/response.rb +82 -22
- data/lib/hatetepe/serializer/encoding.rb +58 -0
- data/lib/hatetepe/serializer.rb +61 -0
- data/lib/hatetepe/server/keep_alive.rb +53 -13
- data/lib/hatetepe/server/timeouts.rb +17 -0
- data/lib/hatetepe/server.rb +37 -85
- data/lib/hatetepe/support/handlers.rb +19 -0
- data/lib/hatetepe/support/keep_alive.rb +14 -0
- data/lib/hatetepe/support/message.rb +40 -0
- data/lib/hatetepe/version.rb +3 -1
- data/lib/hatetepe.rb +29 -7
- data/spec/integration/error_handling_spec.rb +7 -0
- data/spec/integration/keep_alive_spec.rb +106 -0
- data/spec/integration/smoke_spec.rb +21 -0
- data/spec/integration/streaming_spec.rb +61 -0
- data/spec/integration/timeouts_spec.rb +82 -0
- data/spec/shared/integration/server_client_pair.rb +26 -0
- data/spec/spec_helper.rb +41 -10
- data/spec/support/handler.rb +55 -0
- data/spec/support/helper.rb +74 -0
- data/spec/unit/client_spec.rb +115 -156
- data/spec/unit/connection/eventmachine_spec.rb +146 -0
- data/spec/unit/request_spec.rb +35 -0
- data/spec/unit/response_spec.rb +42 -0
- data/spec/unit/server_spec.rb +65 -100
- data/spec/unit/support/keep_alive_spec.rb +52 -0
- data/spec/unit/support/message_spec.rb +41 -0
- metadata +68 -103
- data/Gemfile.lock +0 -46
- data/LICENSE +0 -19
- data/Procfile +0 -1
- data/config.ru +0 -7
- data/examples/parallel_requests.rb +0 -32
- data/lib/hatetepe/body.rb +0 -182
- data/lib/hatetepe/builder.rb +0 -171
- data/lib/hatetepe/cli.rb +0 -61
- data/lib/hatetepe/connection.rb +0 -73
- data/lib/hatetepe/events.rb +0 -35
- data/lib/hatetepe/message.rb +0 -13
- data/lib/hatetepe/parser.rb +0 -83
- data/lib/hatetepe/server/pipeline.rb +0 -20
- data/lib/hatetepe/server/rack_app.rb +0 -39
- data/lib/rack/handler/hatetepe.rb +0 -33
- data/spec/integration/cli/start_spec.rb +0 -113
- data/spec/integration/client/keep_alive_spec.rb +0 -23
- data/spec/integration/client/timeout_spec.rb +0 -97
- data/spec/integration/server/keep_alive_spec.rb +0 -27
- data/spec/integration/server/timeout_spec.rb +0 -51
- data/spec/unit/body_spec.rb +0 -205
- data/spec/unit/builder_spec.rb +0 -372
- data/spec/unit/connection_spec.rb +0 -62
- data/spec/unit/events_spec.rb +0 -96
- data/spec/unit/parser_spec.rb +0 -209
- data/spec/unit/rack_handler_spec.rb +0 -60
data/lib/hatetepe/response.rb
CHANGED
@@ -1,28 +1,88 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
3
|
module Hatetepe
|
4
|
-
class Response
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def failure?
|
17
|
-
status.between? 400, 599
|
18
|
-
end
|
19
|
-
|
20
|
-
def to_a
|
21
|
-
[status, headers, body]
|
4
|
+
class Response
|
5
|
+
include Promise::Attribute
|
6
|
+
promise :finished
|
7
|
+
|
8
|
+
attr_reader :status, :headers, :body
|
9
|
+
attr_accessor :http_version
|
10
|
+
|
11
|
+
def initialize(status, headers = {}, body = '')
|
12
|
+
@status, @headers, @body = status, headers, body
|
13
|
+
@http_version = 1.1
|
14
|
+
super()
|
22
15
|
end
|
23
|
-
|
24
|
-
def
|
25
|
-
|
16
|
+
|
17
|
+
def status_name
|
18
|
+
STATUS_NAMES[status.to_i] || UNKNOWN_STATUS
|
26
19
|
end
|
20
|
+
|
21
|
+
UNKNOWN_STATUS = 'Unknown Status'.freeze
|
22
|
+
|
23
|
+
STATUS_NAMES =
|
24
|
+
{ 100 => 'Continue'.freeze,
|
25
|
+
101 => 'Switching Protocols'.freeze,
|
26
|
+
102 => 'Processing'.freeze,
|
27
|
+
200 => 'OK'.freeze,
|
28
|
+
201 => 'Created'.freeze,
|
29
|
+
202 => 'Accepted'.freeze,
|
30
|
+
203 => 'Non-Authoritative Information'.freeze,
|
31
|
+
204 => 'No Content'.freeze,
|
32
|
+
205 => 'Reset Content'.freeze,
|
33
|
+
206 => 'Partial Content'.freeze,
|
34
|
+
207 => 'Multi-Status'.freeze,
|
35
|
+
208 => 'Already Reported'.freeze,
|
36
|
+
226 => 'IM Used'.freeze,
|
37
|
+
300 => 'Multiple Choices'.freeze,
|
38
|
+
301 => 'Moved Permanently'.freeze,
|
39
|
+
302 => 'Found'.freeze,
|
40
|
+
303 => 'See Other'.freeze,
|
41
|
+
304 => 'Not Modified'.freeze,
|
42
|
+
305 => 'Use Proxy'.freeze,
|
43
|
+
306 => 'Reserved'.freeze,
|
44
|
+
307 => 'Temporary Redirect'.freeze,
|
45
|
+
308 => 'Permanent Redirect'.freeze,
|
46
|
+
400 => 'Bad Request'.freeze,
|
47
|
+
401 => 'Unauthorized'.freeze,
|
48
|
+
402 => 'Payment Required'.freeze,
|
49
|
+
403 => 'Forbidden'.freeze,
|
50
|
+
404 => 'Not Found'.freeze,
|
51
|
+
405 => 'Method Not Allowed'.freeze,
|
52
|
+
406 => 'Not Acceptable'.freeze,
|
53
|
+
407 => 'Proxy Authentication Required'.freeze,
|
54
|
+
408 => 'Request Timeout'.freeze,
|
55
|
+
409 => 'Conflict'.freeze,
|
56
|
+
410 => 'Gone'.freeze,
|
57
|
+
411 => 'Length Required'.freeze,
|
58
|
+
412 => 'Precondition Failed'.freeze,
|
59
|
+
413 => 'Request Entity Too Large'.freeze,
|
60
|
+
414 => 'Request-URI Too Long'.freeze,
|
61
|
+
415 => 'Unsupported Media Type'.freeze,
|
62
|
+
416 => 'Requested Range Not Satisfiable'.freeze,
|
63
|
+
417 => 'Expectation Failed'.freeze,
|
64
|
+
422 => 'Unprocessable Entity'.freeze,
|
65
|
+
423 => 'Locked'.freeze,
|
66
|
+
424 => 'Failed Dependency'.freeze,
|
67
|
+
425 =>
|
68
|
+
'Reserved for WebDAV advanced collections expired proposal'.freeze,
|
69
|
+
426 => 'Upgrade Required'.freeze,
|
70
|
+
427 => 'Unassigned'.freeze,
|
71
|
+
428 => 'Precondition Required'.freeze,
|
72
|
+
429 => 'Too Many Requests'.freeze,
|
73
|
+
430 => 'Unassigned'.freeze,
|
74
|
+
431 => 'Request Header Fields Too Large'.freeze,
|
75
|
+
500 => 'Internal Server Error'.freeze,
|
76
|
+
501 => 'Not Implemented'.freeze,
|
77
|
+
502 => 'Bad Gateway'.freeze,
|
78
|
+
503 => 'Service Unavailable'.freeze,
|
79
|
+
504 => 'Gateway Timeout'.freeze,
|
80
|
+
505 => 'HTTP Version Not Supported'.freeze,
|
81
|
+
506 => 'Variant Also Negotiates (Experimental)'.freeze,
|
82
|
+
507 => 'Insufficient Storage'.freeze,
|
83
|
+
508 => 'Loop Detected'.freeze,
|
84
|
+
509 => 'Unassigned'.freeze,
|
85
|
+
510 => 'Not Extended'.freeze,
|
86
|
+
511 => 'Network Authentication Required'.freeze }
|
27
87
|
end
|
28
88
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Hatetepe
|
4
|
+
class Serializer
|
5
|
+
module Encoding
|
6
|
+
TRANSFER_ENCODING = 'Transfer-Encoding'.freeze
|
7
|
+
CHUNKED = 'chunked'.freeze
|
8
|
+
CHUNK = "%d\r\n%s\r\n".freeze
|
9
|
+
CONTENT_LENGTH = 'Content-Length'.freeze
|
10
|
+
|
11
|
+
def setup_body
|
12
|
+
if finished.pending?
|
13
|
+
setup_chunked_encoding
|
14
|
+
setup_chunked_streaming
|
15
|
+
else
|
16
|
+
setup_identity_encoding
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def setup_chunked_encoding
|
21
|
+
headers.delete(CONTENT_LENGTH)
|
22
|
+
headers[TRANSFER_ENCODING] = CHUNKED
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup_chunked_streaming
|
26
|
+
finished.on_progress do |chunk|
|
27
|
+
write_chunk(chunk)
|
28
|
+
end
|
29
|
+
finished.then { |_| write_chunk!('') }
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup_identity_encoding
|
33
|
+
headers.delete(TRANSFER_ENCODING)
|
34
|
+
headers[CONTENT_LENGTH] = body.bytesize
|
35
|
+
end
|
36
|
+
|
37
|
+
def write_body
|
38
|
+
if finished.pending?
|
39
|
+
write_chunk(body)
|
40
|
+
else
|
41
|
+
write(body)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def write_chunk(chunk)
|
46
|
+
write_chunk!(chunk) unless chunk.empty?
|
47
|
+
end
|
48
|
+
|
49
|
+
def write_chunk!(chunk)
|
50
|
+
write(body_chunk(chunk))
|
51
|
+
end
|
52
|
+
|
53
|
+
def body_chunk(chunk)
|
54
|
+
sprintf(CHUNK, chunk.bytesize, chunk)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Hatetepe
|
6
|
+
class Serializer
|
7
|
+
REQUEST_LINE = "%s %s HTTP/%.1f\r\n".freeze
|
8
|
+
RESPONSE_LINE = "HTTP/%.1f %d %s\r\n".freeze
|
9
|
+
HEADER = "%s: %s\r\n".freeze
|
10
|
+
CRLF = "\r\n".freeze
|
11
|
+
|
12
|
+
include Encoding
|
13
|
+
|
14
|
+
extend Forwardable
|
15
|
+
def_delegator :@message, :headers
|
16
|
+
def_delegator :@message, :body
|
17
|
+
def_delegator :@message, :finished
|
18
|
+
|
19
|
+
def initialize(message, writer)
|
20
|
+
@message = message
|
21
|
+
@writer = writer
|
22
|
+
end
|
23
|
+
|
24
|
+
def serialize
|
25
|
+
setup_body
|
26
|
+
|
27
|
+
write(banana_line)
|
28
|
+
write(header_block)
|
29
|
+
|
30
|
+
write_body
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def write(data)
|
36
|
+
@writer.call(data)
|
37
|
+
end
|
38
|
+
|
39
|
+
def banana_line
|
40
|
+
if Request === @message
|
41
|
+
request_line
|
42
|
+
else
|
43
|
+
response_line
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def request_line
|
48
|
+
sprintf(REQUEST_LINE,
|
49
|
+
@message.http_method.upcase, @message.uri, @message.http_version)
|
50
|
+
end
|
51
|
+
|
52
|
+
def response_line
|
53
|
+
sprintf(RESPONSE_LINE,
|
54
|
+
@message.http_version, @message.status, @message.status_name)
|
55
|
+
end
|
56
|
+
|
57
|
+
def header_block
|
58
|
+
headers.reduce('') { |a, e| a << sprintf(HEADER, *e) } + CRLF
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,23 +1,63 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Hatetepe
|
4
|
+
class Server::KeepAlive
|
5
|
+
CONNECTION = 'Connection'.freeze
|
6
|
+
CLOSE = 'close'.freeze
|
7
|
+
KEEP_ALIVE = 'keep-alive'.freeze
|
8
|
+
|
9
|
+
include Support::KeepAlive
|
10
|
+
|
11
|
+
def initialize(config, server, connection)
|
12
|
+
@config, @server = config, server
|
13
|
+
@connection = connection
|
14
|
+
@requests = []
|
5
15
|
end
|
6
16
|
|
7
|
-
def
|
8
|
-
@
|
9
|
-
|
10
|
-
|
17
|
+
def serve(request)
|
18
|
+
@requests << request
|
19
|
+
end
|
20
|
+
|
21
|
+
def respond(request, response)
|
22
|
+
synchronize_responses(request, response)
|
23
|
+
|
24
|
+
version = request.http_version
|
25
|
+
header = connection_header(request, response)
|
26
|
+
|
27
|
+
if close_connection?(version, header)
|
28
|
+
response.headers[CONNECTION] = CLOSE
|
29
|
+
close_connection(response)
|
30
|
+
else
|
31
|
+
response.headers[CONNECTION] = KEEP_ALIVE
|
11
32
|
end
|
12
33
|
end
|
13
34
|
|
14
|
-
|
15
|
-
version = request.http_version.to_f
|
16
|
-
header = request.headers["Connection"] || response.headers["Connection"]
|
35
|
+
private
|
17
36
|
|
18
|
-
|
19
|
-
|
37
|
+
def synchronize_responses(request, response)
|
38
|
+
wait_for_previous(request)
|
39
|
+
|
40
|
+
callback = proc { @requests.delete(request) }
|
41
|
+
response.finished.then(callback, callback)
|
42
|
+
end
|
43
|
+
|
44
|
+
def wait_for_previous(request)
|
45
|
+
previous = @requests[@requests.index(request) - 1]
|
46
|
+
if previous
|
47
|
+
response = previous.served.sync
|
48
|
+
response.finished.sync
|
20
49
|
end
|
21
50
|
end
|
51
|
+
|
52
|
+
def connection_header(request, response)
|
53
|
+
header = request.headers[CONNECTION] || response.headers[CONNECTION]
|
54
|
+
header.to_s.downcase
|
55
|
+
end
|
56
|
+
|
57
|
+
def close_connection(response)
|
58
|
+
callback = proc { |arg| @server.close }
|
59
|
+
# XXX possible race condition with other locations waiting for this
|
60
|
+
response.finished.then(callback, callback)
|
61
|
+
end
|
22
62
|
end
|
23
63
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Hatetepe
|
4
|
+
# @see EM.heartbeat_interval
|
5
|
+
class Server::Timeouts
|
6
|
+
def initialize(config, server, connection)
|
7
|
+
@config, @server = config, server
|
8
|
+
@connection = connection
|
9
|
+
|
10
|
+
@config[:timeout] ||= 2.0
|
11
|
+
end
|
12
|
+
|
13
|
+
def post_init
|
14
|
+
@connection.comm_inactivity_timeout = @config[:timeout]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/hatetepe/server.rb
CHANGED
@@ -1,102 +1,54 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
require "hatetepe/version"
|
11
|
-
|
12
|
-
module Hatetepe::Server
|
13
|
-
include Hatetepe::Connection
|
14
|
-
|
15
|
-
attr_reader :config, :requests
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Hatetepe
|
4
|
+
class Server
|
5
|
+
def self.start(config)
|
6
|
+
callback = proc { |connection| new(config, connection) }
|
7
|
+
EM.start_server(config[:address], config[:port],
|
8
|
+
Connection::EventMachine, callback)
|
9
|
+
end
|
16
10
|
|
17
|
-
|
18
|
-
|
19
|
-
:app => [ Pipeline, KeepAlive, RackApp ]
|
20
|
-
}
|
11
|
+
include Support::Handlers
|
12
|
+
include Connection::Status
|
21
13
|
|
22
|
-
|
23
|
-
def self.start(config)
|
24
|
-
EM.start_server(config[:host], config[:port], self, config)
|
25
|
-
end
|
14
|
+
attr_reader :config
|
26
15
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
16
|
+
def initialize(config, connection)
|
17
|
+
@config = config
|
18
|
+
@connection = connection
|
31
19
|
|
32
|
-
|
33
|
-
|
34
|
-
@parser, @builder = Hatetepe::Parser.new, Hatetepe::Builder.new
|
35
|
-
@parser.on_request &method(:process_request)
|
36
|
-
@builder.on_write &method(:send_data)
|
37
|
-
# @builder.on_write {|data| p "<--| #{data}" }
|
20
|
+
setup_handlers
|
21
|
+
setup_connection
|
38
22
|
|
39
|
-
|
23
|
+
notify_handlers(:post_init)
|
24
|
+
end
|
40
25
|
|
41
|
-
|
42
|
-
|
26
|
+
def serve(request)
|
27
|
+
request.served.then { |response| respond(request, response) }
|
43
28
|
|
44
|
-
|
45
|
-
|
46
|
-
# p "-->| #{data}"
|
47
|
-
@parser << data
|
48
|
-
rescue Object => ex
|
49
|
-
puts [ex.message, *ex.backtrace].join("\n\t")
|
50
|
-
close_connection
|
51
|
-
end
|
52
|
-
|
53
|
-
# @api private
|
54
|
-
def process_request(request)
|
55
|
-
Fiber.new do
|
56
|
-
@app.call(request) do |response|
|
57
|
-
send_response(request, response)
|
29
|
+
fiber = Fiber.new do
|
30
|
+
notify_handlers(:serve, request)
|
58
31
|
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
# @api private
|
63
|
-
def send_response(request, response)
|
64
|
-
self.comm_inactivity_timeout = 0
|
65
|
-
@builder.response(response.to_a)
|
66
|
-
self.comm_inactivity_timeout = config[:timeout]
|
67
|
-
|
68
|
-
if response.failure?
|
69
|
-
request.fail(response)
|
70
|
-
else
|
71
|
-
request.succeed(response)
|
32
|
+
fiber.resume
|
72
33
|
end
|
73
|
-
end
|
74
34
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
35
|
+
def respond(request, response)
|
36
|
+
notify_handlers(:respond, request, response)
|
37
|
+
@connection.serialize(response)
|
38
|
+
end
|
79
39
|
|
80
|
-
|
81
|
-
|
82
|
-
|
40
|
+
def close
|
41
|
+
@connection.close
|
42
|
+
end
|
83
43
|
|
84
|
-
|
85
|
-
def stop!
|
86
|
-
close_connection_after_writing
|
87
|
-
end
|
44
|
+
private
|
88
45
|
|
89
|
-
|
46
|
+
def setup_connection
|
47
|
+
@connection.parse(method(:serve))
|
48
|
+
@connection.closed.then(method(:shutdown))
|
49
|
+
end
|
90
50
|
|
91
|
-
|
92
|
-
app =
|
93
|
-
if app.respond_to?(:call)
|
94
|
-
[ *CONFIG_DEFAULTS[:app], app ]
|
95
|
-
else
|
96
|
-
app.dup
|
97
|
-
end
|
98
|
-
app.inject(app.pop) do |inner, outer|
|
99
|
-
outer.new(inner, self)
|
51
|
+
def shutdown(_)
|
100
52
|
end
|
101
53
|
end
|
102
54
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Hatetepe
|
4
|
+
module Support
|
5
|
+
module Handlers
|
6
|
+
def setup_handlers
|
7
|
+
@handlers = @config[:handlers].map do |klass|
|
8
|
+
klass.new(@config, self, @connection)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def notify_handlers(hook, *args)
|
13
|
+
@handlers.each do |handler|
|
14
|
+
handler.send(hook, *args) if handler.respond_to?(hook)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Hatetepe
|
4
|
+
module Support
|
5
|
+
module KeepAlive
|
6
|
+
CLOSE = 'close'.freeze
|
7
|
+
KEEP_ALIVE = 'keep-alive'.freeze
|
8
|
+
|
9
|
+
def close_connection?(version, header)
|
10
|
+
(version < 1.1 && header != KEEP_ALIVE) || header == CLOSE
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Hatetepe
|
4
|
+
module Support
|
5
|
+
class Message
|
6
|
+
def self.build(parser)
|
7
|
+
if parser.http_method
|
8
|
+
build_request(parser)
|
9
|
+
else
|
10
|
+
build_response(parser)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def self.build_request(parser)
|
17
|
+
request = Request.new(http_method_from(parser),
|
18
|
+
parser.request_url,
|
19
|
+
parser.headers)
|
20
|
+
request.http_version = http_version_from(parser)
|
21
|
+
request
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.build_response(parser)
|
25
|
+
response = Response.new(parser.status_code,
|
26
|
+
parser.headers)
|
27
|
+
response.http_version = http_version_from(parser)
|
28
|
+
response
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.http_method_from(parser)
|
32
|
+
parser.http_method.downcase.to_sym
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.http_version_from(parser)
|
36
|
+
parser.http_version.join('.').to_f
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/hatetepe/version.rb
CHANGED
data/lib/hatetepe.rb
CHANGED
@@ -1,7 +1,29 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'eventmachine'
|
4
|
+
require 'fiber'
|
5
|
+
require 'promise'
|
6
|
+
require 'http/parser'
|
7
|
+
|
8
|
+
require 'hatetepe/version'
|
9
|
+
|
10
|
+
require 'hatetepe/errors'
|
11
|
+
require 'hatetepe/support/handlers'
|
12
|
+
require 'hatetepe/support/keep_alive'
|
13
|
+
require 'hatetepe/support/message'
|
14
|
+
|
15
|
+
require 'hatetepe/promise'
|
16
|
+
require 'hatetepe/request'
|
17
|
+
require 'hatetepe/response'
|
18
|
+
|
19
|
+
require 'hatetepe/connection/eventmachine'
|
20
|
+
require 'hatetepe/connection/status'
|
21
|
+
require 'hatetepe/serializer/encoding'
|
22
|
+
require 'hatetepe/serializer'
|
23
|
+
|
24
|
+
require 'hatetepe/client'
|
25
|
+
require 'hatetepe/client/keep_alive'
|
26
|
+
require 'hatetepe/client/timeouts'
|
27
|
+
require 'hatetepe/server'
|
28
|
+
require 'hatetepe/server/keep_alive'
|
29
|
+
require 'hatetepe/server/timeouts'
|