hatetepe 0.5.0 → 0.5.1
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.
- data/hatetepe.gemspec +1 -1
- data/lib/hatetepe/cli.rb +23 -24
- data/lib/hatetepe/connection.rb +13 -1
- data/lib/hatetepe/parser.rb +41 -29
- data/lib/hatetepe/server.rb +15 -9
- data/lib/hatetepe/version.rb +1 -1
- data/spec/integration/cli/start_spec.rb +1 -1
- data/spec/integration/client/timeout_spec.rb +4 -0
- data/spec/integration/server/timeout_spec.rb +6 -0
- data/spec/unit/connection_spec.rb +3 -3
- data/spec/unit/parser_spec.rb +1 -10
- metadata +3 -3
data/hatetepe.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
s.add_development_dependency "rspec"
|
23
23
|
s.add_development_dependency "yard"
|
24
|
-
s.add_development_dependency "
|
24
|
+
s.add_development_dependency "kramdown"
|
25
25
|
|
26
26
|
s.files = `git ls-files`.split("\n") - [".gitignore", ".rspec", ".travis.yml", ".yardopts"]
|
27
27
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/hatetepe/cli.rb
CHANGED
@@ -27,36 +27,35 @@ module Hatetepe
|
|
27
27
|
def start
|
28
28
|
require "hatetepe/server"
|
29
29
|
require "rack"
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
$stderr << "Booting from #{rackup}\n"
|
37
|
-
$stderr.flush
|
38
|
-
|
39
|
-
app = Rack::Builder.parse_file(rackup)[0]
|
30
|
+
|
31
|
+
config = config_for(options)
|
32
|
+
ENV["RACK_ENV"] = config[:env]
|
33
|
+
|
34
|
+
$stderr << "We're in #{config[:env]}\n"
|
35
|
+
$stderr << "Booting from #{config[:rackup]}\n"
|
40
36
|
|
41
37
|
EM.epoll
|
42
38
|
EM.synchrony do
|
39
|
+
$stderr << "Binding to #{config[:host]}:#{config[:port]}\n"
|
40
|
+
|
43
41
|
trap("INT") { EM.stop }
|
44
42
|
trap("TERM") { EM.stop }
|
45
|
-
|
46
|
-
host = options[:bind] || "127.0.0.1"
|
47
|
-
port = options[:port] || 3000
|
48
|
-
timeout = options[:timeout] || Hatetepe::Server::CONFIG_DEFAULTS[:timeout]
|
49
|
-
|
50
|
-
$stderr << "Binding to #{host}:#{port}\n"
|
51
|
-
$stderr.flush
|
52
|
-
|
53
|
-
Server.start({
|
54
|
-
app: app,
|
55
|
-
host: host,
|
56
|
-
port: port,
|
57
|
-
timeout: timeout
|
58
|
-
})
|
43
|
+
Server.start(config)
|
59
44
|
end
|
60
45
|
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def config_for(options)
|
50
|
+
rackup = File.expand_path(options[:rackup] || "config.ru")
|
51
|
+
{
|
52
|
+
env: options[:env] || ENV["RACK_ENV"] || "development",
|
53
|
+
host: options[:bind] || "127.0.0.1",
|
54
|
+
port: options[:port] || 3000,
|
55
|
+
timeout: options[:timeout],
|
56
|
+
app: Rack::Builder.parse_file(rackup)[0],
|
57
|
+
rackup: rackup
|
58
|
+
}
|
59
|
+
end
|
61
60
|
end
|
62
61
|
end
|
data/lib/hatetepe/connection.rb
CHANGED
@@ -2,7 +2,7 @@ module Hatetepe
|
|
2
2
|
module Connection
|
3
3
|
attr_accessor :processing_enabled
|
4
4
|
alias_method :processing_enabled?, :processing_enabled
|
5
|
-
|
5
|
+
|
6
6
|
def remote_address
|
7
7
|
sockaddr && sockaddr[1]
|
8
8
|
end
|
@@ -57,5 +57,17 @@ module Hatetepe
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
60
|
+
|
61
|
+
def comm_inactivity_timeout=(seconds)
|
62
|
+
unless defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
|
63
|
+
super
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def pending_connect_timeout=(seconds)
|
68
|
+
unless defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
|
69
|
+
super
|
70
|
+
end
|
71
|
+
end
|
60
72
|
end
|
61
73
|
end
|
data/lib/hatetepe/parser.rb
CHANGED
@@ -19,47 +19,32 @@ module Hatetepe
|
|
19
19
|
attr_reader :message
|
20
20
|
|
21
21
|
def initialize(&block)
|
22
|
+
initialize_parser
|
23
|
+
reset
|
24
|
+
|
25
|
+
if block
|
26
|
+
block.arity == 0 ? instance_eval(&block) : block.call(self)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize_parser
|
22
31
|
@parser = HTTP::Parser.new.tap do |p|
|
23
|
-
p.on_headers_complete = proc do
|
24
|
-
|
25
|
-
|
26
|
-
@message = Request.new(p.http_method, p.request_url,
|
27
|
-
p.headers, Body.new, version)
|
28
|
-
event! :request, message
|
29
|
-
else
|
30
|
-
@message = Response.new(p.status_code, p.headers, Body.new, version)
|
31
|
-
event! :response, message
|
32
|
-
end
|
33
|
-
|
34
|
-
event! :headers, message.headers
|
35
|
-
event! :body, message.body
|
32
|
+
p.on_headers_complete = proc do |headers|
|
33
|
+
headers_complete(p) if @headers_counter.even?
|
34
|
+
@headers_counter += 1
|
36
35
|
nil
|
37
36
|
end
|
38
37
|
|
39
|
-
p.on_body
|
40
|
-
message.body.write chunk unless message.body.closed_write?
|
41
|
-
end
|
42
|
-
|
38
|
+
p.on_body = method(:body)
|
43
39
|
p.on_message_complete = method(:complete)
|
44
40
|
end
|
45
|
-
|
46
|
-
reset
|
47
|
-
|
48
|
-
if block
|
49
|
-
block.arity == 0 ? instance_eval(&block) : block.call(self)
|
50
|
-
end
|
51
41
|
end
|
52
42
|
|
53
43
|
def reset
|
54
44
|
@parser.reset!
|
55
45
|
event! :reset
|
56
46
|
@message = nil
|
57
|
-
|
58
|
-
|
59
|
-
def complete
|
60
|
-
message.body.rewind!
|
61
|
-
message.body.close_write unless message.body.closed_write?
|
62
|
-
event! :complete
|
47
|
+
@headers_counter = 0
|
63
48
|
end
|
64
49
|
|
65
50
|
def <<(data)
|
@@ -67,5 +52,32 @@ module Hatetepe
|
|
67
52
|
rescue HTTP::Parser::Error => e
|
68
53
|
raise Hatetepe::ParserError, e.message, e.backtrace
|
69
54
|
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def headers_complete(parser)
|
59
|
+
args = [ parser.headers, Body.new, parser.http_version.join(".") ]
|
60
|
+
if parser.http_method
|
61
|
+
@message = Request.new(parser.http_method, parser.request_url, *args)
|
62
|
+
event! :request, @message
|
63
|
+
else
|
64
|
+
@message = Response.new(parser.status_code, *args)
|
65
|
+
event! :response, @message
|
66
|
+
end
|
67
|
+
|
68
|
+
event! :headers, message.headers
|
69
|
+
event! :body, message.body
|
70
|
+
end
|
71
|
+
|
72
|
+
def body(chunk)
|
73
|
+
message.body.write chunk unless message.body.closed_write?
|
74
|
+
end
|
75
|
+
|
76
|
+
def complete
|
77
|
+
message.body.rewind!
|
78
|
+
message.body.close_write unless message.body.closed_write?
|
79
|
+
event! :complete
|
80
|
+
@headers_counter += 1 if @headers_counter.odd?
|
81
|
+
end
|
70
82
|
end
|
71
83
|
end
|
data/lib/hatetepe/server.rb
CHANGED
@@ -36,15 +36,7 @@ module Hatetepe::Server
|
|
36
36
|
@builder.on_write &method(:send_data)
|
37
37
|
# @builder.on_write {|data| p "<--| #{data}" }
|
38
38
|
|
39
|
-
app =
|
40
|
-
if config[:app].respond_to?(:call)
|
41
|
-
[ *CONFIG_DEFAULTS[:app], config[:app] ]
|
42
|
-
else
|
43
|
-
config[:app].dup
|
44
|
-
end
|
45
|
-
@app = app.inject(app.pop) do |inner, outer|
|
46
|
-
outer.new(inner, self)
|
47
|
-
end
|
39
|
+
@app = build_app(config[:app])
|
48
40
|
|
49
41
|
self.comm_inactivity_timeout = config[:timeout]
|
50
42
|
end
|
@@ -93,4 +85,18 @@ module Hatetepe::Server
|
|
93
85
|
def stop!
|
94
86
|
close_connection_after_writing
|
95
87
|
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def build_app(app)
|
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)
|
100
|
+
end
|
101
|
+
end
|
96
102
|
end
|
data/lib/hatetepe/version.rb
CHANGED
@@ -35,7 +35,7 @@ describe Hatetepe::CLI do
|
|
35
35
|
Hatetepe::Server.should_receive(:start) do |config|
|
36
36
|
config[:host].should == "127.0.0.1"
|
37
37
|
config[:port].should equal(3000)
|
38
|
-
config[:timeout].should
|
38
|
+
config[:timeout].should be_nil
|
39
39
|
|
40
40
|
config[:app].should equal(rackup[0])
|
41
41
|
ENV["RACK_ENV"].should == "development"
|
@@ -3,6 +3,12 @@ require "hatetepe/client"
|
|
3
3
|
require "hatetepe/server"
|
4
4
|
|
5
5
|
describe Hatetepe::Server do
|
6
|
+
before do
|
7
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
|
8
|
+
pending "EventMachine timeouts are not available on JRuby"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
6
12
|
let :options do
|
7
13
|
{ host: "127.0.0.1", port: 3123 }
|
8
14
|
end
|
@@ -6,10 +6,10 @@ describe Hatetepe::Connection do
|
|
6
6
|
Object.new.extend Hatetepe::Connection
|
7
7
|
end
|
8
8
|
|
9
|
-
let(:peername) { "\x02\x00\x86\xF6\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" }
|
10
9
|
let(:address) { "127.0.0.1" }
|
11
|
-
let(:port) {
|
12
|
-
|
10
|
+
let(:port) { 34450 }
|
11
|
+
let(:peername) { Socket.pack_sockaddr_in(port, address) }
|
12
|
+
|
13
13
|
before { conn.stub :get_peername => peername }
|
14
14
|
|
15
15
|
describe "#remote_address" do
|
data/spec/unit/parser_spec.rb
CHANGED
@@ -164,20 +164,11 @@ describe Hatetepe::Parser do
|
|
164
164
|
context "#on_body {|body| ... }" do
|
165
165
|
it "evals the block when the body starts" do
|
166
166
|
block.should_receive(:call) {|body|
|
167
|
-
body.should
|
168
|
-
|
169
|
-
# we'd have to #close_write to get body#length
|
170
|
-
body.io.length.should == 0
|
167
|
+
Fiber.new { body.read.should eq("Hello!") }.resume
|
171
168
|
}
|
172
169
|
|
173
170
|
parser.on_body &block
|
174
171
|
do_request
|
175
|
-
|
176
|
-
parser.message.body.tap {|b|
|
177
|
-
b.rewind
|
178
|
-
b.length.should == 6
|
179
|
-
b.read.should == "Hello!"
|
180
|
-
}
|
181
172
|
end
|
182
173
|
|
183
174
|
it "changes the state to :body" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hatetepe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-09-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: http_parser.rb
|
@@ -124,7 +124,7 @@ dependencies:
|
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
|
-
name:
|
127
|
+
name: kramdown
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
none: false
|
130
130
|
requirements:
|