hatetepe 0.4.0 → 0.4.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/Gemfile CHANGED
@@ -4,6 +4,3 @@ gemspec
4
4
 
5
5
  gem "rake"
6
6
  gem "awesome_print"
7
-
8
- gem "yard"
9
- gem "rdiscount"
data/README.md CHANGED
@@ -11,7 +11,7 @@ Install it via `gem install hatetepe` or add `gem "hatetepe"` to your Gemfile.
11
11
  Hatetepe only implements core HTTP functionality. If you need stuff like
12
12
  automatic JSON or form-data encoding, have a look at
13
13
  [Faraday](https://github.com/technoweenie/faraday), there's also an
14
- [Hatetepe adapter](https://github.com/lgierth/faraday/tree/hatetepe-support)
14
+ [Hatetepe adapter](https://github.com/technoweenie/faraday/pull/108)
15
15
  for it being worked on.
16
16
 
17
17
  [![Build status](https://secure.travis-ci.org/lgierth/hatetepe.png?branch=master)](http://travis-ci.org/lgierth/hatetepe)
@@ -39,8 +39,10 @@ Getting Started (Client)
39
39
  The `Hatetepe::Client` class can be used to make requests to an HTTP server.
40
40
 
41
41
  client = Hatetepe::Client.start(:host => "example.org", :port => 80)
42
+
42
43
  request = Hatetepe::Request.new(:post, "/search", {}, :q => "herp derp")
43
44
  client << request
45
+
44
46
  request.callback do |response|
45
47
  puts "Results:"
46
48
  puts response.body.read
data/hatetepe.gemspec CHANGED
@@ -21,6 +21,8 @@ Gem::Specification.new do |s|
21
21
 
22
22
  s.add_development_dependency "rspec"
23
23
  s.add_development_dependency "fakefs"
24
+ s.add_development_dependency "yard"
25
+ s.add_development_dependency "rdiscount"
24
26
 
25
27
  s.files = `git ls-files`.split("\n") - [".gitignore", ".rspec", ".travis.yml", ".yardopts"]
26
28
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -10,32 +10,6 @@ class Hatetepe::Client
10
10
  # i think it doesn't matter if we send it as we don't wait
11
11
  # for the first response to see if we're talking to an HTTP/1.1
12
12
  # server. we're sending more requests anyway.
13
-
14
- # priority
15
- # 1. if X-Hatetepe-Single then Connection header, Client#request closes
16
- # 2. if req.Connection == close then Connection header and close
17
- # 3. if res.Connection == close then close
18
- def call(request)
19
- req, conn = request, request.connection
20
-
21
- single = req.headers.delete("X-Hatetepe-Single")
22
- req.headers["Connection"] ||= if single
23
- "close"
24
- else
25
- "keep-alive"
26
- end
27
- close = req.headers["Connection"] == "close"
28
-
29
- # stop processing further requests as early as possible
30
- conn.processing_enabled = false if close
31
-
32
- app.call(request).tap do |response|
33
- if !single && response.headers["Connection"] == "close"
34
- conn.processing_enabled = false
35
- end
36
- end
37
- end
38
-
39
13
  def call(request)
40
14
  req, conn = request, request.connection
41
15
 
@@ -76,6 +76,8 @@ class Hatetepe::Client
76
76
  end
77
77
 
78
78
  def <<(request)
79
+ request.headers["Host"] ||= "#{config[:host]}:#{config[:port]}"
80
+
79
81
  request.connection = self
80
82
  unless processing_enabled?
81
83
  request.fail
@@ -101,18 +103,17 @@ class Hatetepe::Client
101
103
  end
102
104
 
103
105
  def request(verb, uri, headers = {}, body = nil, http_version = "1.1")
104
- headers["Host"] ||= "#{config[:host]}:#{config[:port]}"
105
106
  headers["User-Agent"] ||= "hatetepe/#{Hatetepe::VERSION}"
106
107
 
107
108
  body = wrap_body(body)
108
- if headers["Content-Type"] == "application/x-www-form-urlencoded"
109
- enum = Enumerator.new(body)
110
- headers["Content-Length"] = enum.inject(0) {|a, e| a + e.length }
111
- end
109
+ headers, body = encode_body(headers.dup, body)
112
110
 
113
111
  request = Hatetepe::Request.new(verb, uri, headers, body, http_version)
114
112
  self << request
113
+
114
+ # XXX shouldn't this happen in ::request ?
115
115
  self.processing_enabled = false
116
+
116
117
  EM::Synchrony.sync request
117
118
 
118
119
  request.response.body.close_write if request.verb == "HEAD"
@@ -161,6 +162,37 @@ class Hatetepe::Client
161
162
  end
162
163
  end
163
164
 
165
+ def encode_body(headers, body)
166
+ multipart, urlencoded = false, false
167
+ if Hash === body
168
+ query = lambda do |value|
169
+ case value
170
+ when Array
171
+ value.each &query
172
+ when Hash
173
+ value.values.each &query
174
+ when Rack::Multipart::UploadedFile
175
+ multipart = true
176
+ end
177
+ end
178
+ body.values.each &query
179
+ urlencoded = !multipart
180
+ end
181
+
182
+ body = if multipart
183
+ boundary = Rack::Multipart::MULTIPART_BOUNDARY
184
+ headers["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
185
+ [Rack::Multipart.build_multipart(body)]
186
+ elsif urlencoded
187
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
188
+ [Rack::Utils.build_nested_query(body)]
189
+ else
190
+ body
191
+ end
192
+
193
+ [headers, body]
194
+ end
195
+
164
196
  class << self
165
197
  def start(config)
166
198
  EM.connect config[:host], config[:port], self, config
@@ -1,3 +1,3 @@
1
1
  module Hatetepe
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
@@ -154,6 +154,13 @@ describe Hatetepe::Client do
154
154
  Fiber.stub(:new) {|blk| blk.call; fiber }
155
155
  end
156
156
 
157
+ it "sets a Host header if none is set" do
158
+ app.should_receive :call do |req|
159
+ req.headers["Host"].should == "example.net:8080"
160
+ end
161
+ client << request
162
+ end
163
+
157
164
  it "sets the request's connection" do
158
165
  request.should_receive(:connection=).with client
159
166
  client << request
@@ -218,25 +225,11 @@ describe Hatetepe::Client do
218
225
  end
219
226
 
220
227
  describe "#request(verb, uri, headers, body)" do
221
- let :config do
222
- {
223
- :host => "example.org",
224
- :port => 8080
225
- }
226
- end
227
-
228
228
  before do
229
229
  EM::Synchrony.stub :sync
230
230
  client.stub :<<
231
231
  end
232
232
 
233
- it "sets a Host header if none is set" do
234
- client.should_receive :<< do |request|
235
- request.headers["Host"].should == "example.org:8080"
236
- end
237
- client.request :get, uri
238
- end
239
-
240
233
  it "sets the User-Agent header" do
241
234
  client.should_receive :<< do |request|
242
235
  request.headers["User-Agent"].should == "hatetepe/#{Hatetepe::VERSION}"
@@ -252,35 +245,9 @@ describe Hatetepe::Client do
252
245
  end
253
246
  client.request :get, uri, "User-Agent" => user_agent
254
247
  end
255
-
256
- describe "with Content-Type: application/x-www-form-urlencoded" do
257
- let :headers do
258
- {"Content-Type" => "application/x-www-form-urlencoded"}
259
- end
260
-
261
- let :body do
262
- [
263
- stub("body#1", :length => 12),
264
- stub("body#2", :length => 13),
265
- stub("body#3", :length => 14)
266
- ]
267
- end
268
-
269
- it "computes the body's length" do
270
- client.should_receive :<< do |request|
271
- request.headers["Content-Length"].should equal(39)
272
- end
273
- client.request :get, uri, headers, body
274
- end
275
-
276
- it "sets Content-Length to 0 if no body was passed" do
277
- client.should_receive :<< do |request|
278
- request.headers["Content-Length"].should equal(0)
279
- end
280
- client.request :get, uri, headers
281
- end
282
- end
283
-
248
+
249
+ it "passes the body through #encode_body"
250
+
284
251
  it "doesn't close the body" do
285
252
  body.should_not_receive :close_write
286
253
  client.request :get, uri, {}, body
@@ -350,6 +317,10 @@ describe Hatetepe::Client do
350
317
  client.wrap_body(nil).should == []
351
318
  end
352
319
  end
320
+
321
+ describe "#encode_body(headers, body)" do
322
+ it ""
323
+ end
353
324
 
354
325
  describe ".start(config)" do
355
326
  let(:config) { {:host => "0.0.0.0", :port => 1234} }
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.4.0
4
+ version: 0.4.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-05 00:00:00.000000000 Z
12
+ date: 2012-01-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: http_parser.rb
16
- requirement: &86213170 !ruby/object:Gem::Requirement
16
+ requirement: &69946770 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.5.3
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *86213170
24
+ version_requirements: *69946770
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: eventmachine
27
- requirement: &86212940 !ruby/object:Gem::Requirement
27
+ requirement: &69946160 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *86212940
35
+ version_requirements: *69946160
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: em-synchrony
38
- requirement: &86212670 !ruby/object:Gem::Requirement
38
+ requirement: &69945450 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '1.0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *86212670
46
+ version_requirements: *69945450
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rack
49
- requirement: &86212370 !ruby/object:Gem::Requirement
49
+ requirement: &69944990 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *86212370
57
+ version_requirements: *69944990
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: async-rack
60
- requirement: &86212030 !ruby/object:Gem::Requirement
60
+ requirement: &69944610 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *86212030
68
+ version_requirements: *69944610
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: thor
71
- requirement: &86211710 !ruby/object:Gem::Requirement
71
+ requirement: &69883990 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *86211710
79
+ version_requirements: *69883990
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &86211400 !ruby/object:Gem::Requirement
82
+ requirement: &69883740 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *86211400
90
+ version_requirements: *69883740
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: fakefs
93
- requirement: &86211060 !ruby/object:Gem::Requirement
93
+ requirement: &69883520 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,29 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *86211060
101
+ version_requirements: *69883520
102
+ - !ruby/object:Gem::Dependency
103
+ name: yard
104
+ requirement: &69883290 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *69883290
113
+ - !ruby/object:Gem::Dependency
114
+ name: rdiscount
115
+ requirement: &69883080 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *69883080
102
124
  description:
103
125
  email:
104
126
  - lars.gierth@gmail.com