julien51-em-http-request 0.1.9 → 0.1.10

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.
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'em-http-request'
3
- s.version = '0.1.9'
3
+ s.version = '0.1.10'
4
4
  s.date = '2009-03-20'
5
5
  s.summary = 'EventMachine based HTTP Request interface'
6
6
  s.description = s.summary
@@ -20,6 +20,16 @@ module EventMachine
20
20
 
21
21
  # The status code (as a string!)
22
22
  attr_accessor :http_status
23
+
24
+ # E-Tag
25
+ def etag
26
+ self["ETag"]
27
+ end
28
+
29
+ def last_modified
30
+ time = self["Last-Modified"]
31
+ Time.parse(time) if time
32
+ end
23
33
 
24
34
  # HTTP response status as an integer
25
35
  def status
@@ -98,12 +108,16 @@ module EventMachine
98
108
  end
99
109
 
100
110
  def encode_query(path, query)
101
- return path unless query
102
- if query.kind_of? String
103
- return "#{path}?#{query}"
111
+ encoded_query = if query.kind_of?(Hash)
112
+ query.map { |k, v| encode_param(k, v) }.join('&')
104
113
  else
105
- return path + "?" + query.map { |k, v| encode_param(k, v) }.join('&')
114
+ query.to_s
106
115
  end
116
+ if !@uri.query.to_s.empty?
117
+ encoded_query = [encoded_query, @uri.query].reject {|part| part.empty?}.join("&")
118
+ end
119
+ return path if encoded_query.to_s.empty?
120
+ "#{path}?#{encoded_query}"
107
121
  end
108
122
 
109
123
  # URL encodes query parameters:
@@ -181,12 +195,12 @@ module EventMachine
181
195
  # start HTTP request once we establish connection to host
182
196
  def connection_completed
183
197
  ssl = @options[:tls] || @options[:ssl] || {}
184
- start_tls(ssl) if @uri.scheme == "https" or @uri.port == 443
198
+ start_tls(ssl) if @uri.scheme == "https" #or @uri.port == 443 # A user might not want https even on port 443.
185
199
 
186
200
  send_request_header
187
201
  send_request_body
188
202
  end
189
-
203
+
190
204
  # request is done, invoke the callback
191
205
  def on_request_complete
192
206
  begin
@@ -196,11 +210,14 @@ module EventMachine
196
210
  end
197
211
  unbind
198
212
  end
199
-
213
+
200
214
  # request failed, invoke errback
201
- def on_error(msg)
215
+ def on_error(msg, dns_error = false)
202
216
  @errors = msg
203
- unbind
217
+
218
+ # no connection signature on DNS failures
219
+ # fail the connection directly
220
+ dns_error == true ? fail : unbind
204
221
  end
205
222
 
206
223
  # assign a stream processing block
@@ -281,7 +298,11 @@ module EventMachine
281
298
  end
282
299
 
283
300
  def unbind
284
- (@state == :finished) ? succeed(self) : fail
301
+ if @state == :finished
302
+ succeed(self)
303
+ else
304
+ fail(self)
305
+ end
285
306
  close_connection
286
307
  end
287
308
 
@@ -339,11 +360,22 @@ module EventMachine
339
360
  return false
340
361
  end
341
362
 
363
+ # shortcircuit on HEAD requests
364
+ if @method == "HEAD"
365
+ @state = :finished
366
+ on_request_complete
367
+ end
368
+
342
369
  if @response_header.chunked_encoding?
343
370
  @state = :chunk_header
344
371
  else
345
- @state = :body
346
- @bytes_remaining = @response_header.content_length
372
+ if @response_header.content_length > 0
373
+ @state = :body
374
+ @bytes_remaining = @response_header.content_length
375
+ else
376
+ @state = :finished
377
+ on_request_complete
378
+ end
347
379
  end
348
380
 
349
381
  if @inflate.include?(response_header[CONTENT_ENCODING]) &&
@@ -50,13 +50,14 @@ module EventMachine
50
50
  # Host: header
51
51
 
52
52
  def get options = {}; send_request(:get, options); end
53
+ def head options = {}; send_request(:head, options); end
53
54
  def post options = {}; send_request(:post, options); end
54
55
 
55
56
  protected
56
57
 
57
58
  def send_request(method, options)
58
59
  raise ArgumentError, "invalid request path" unless /^\// === @uri.path
59
-
60
+
60
61
  method = method.to_s.upcase
61
62
  begin
62
63
  host = options[:host] || @uri.host
@@ -69,7 +70,7 @@ module EventMachine
69
70
  rescue RuntimeError => e
70
71
  raise e unless e.message == "no connection"
71
72
  conn = EventMachine::HttpClient.new("")
72
- conn.on_error("no connection")
73
+ conn.on_error("no connection", true)
73
74
  conn
74
75
  end
75
76
  end
data/test/stallion.rb CHANGED
@@ -83,6 +83,9 @@ Stallion.saddle :spec do |stable|
83
83
  elsif stable.request.path_info == '/echo_content_length'
84
84
  stable.response.write stable.request.content_length
85
85
 
86
+ elsif stable.request.head?
87
+ stable.response.status = 200
88
+
86
89
  elsif stable.request.post?
87
90
  stable.response.write stable.request.body.read
88
91
 
@@ -131,7 +134,11 @@ Stallion.saddle :spec do |stable|
131
134
  end
132
135
 
133
136
  Thread.new do
134
- Stallion.run :Host => '127.0.0.1', :Port => 8080
137
+ begin
138
+ Stallion.run :Host => '127.0.0.1', :Port => 8080
139
+ rescue Exception => e
140
+ print e
141
+ end
135
142
  end
136
143
 
137
- sleep(2)
144
+ sleep(1)
data/test/test_hash.rb CHANGED
@@ -10,9 +10,10 @@ describe Hash do
10
10
  it "should transform a more complex hash into HTTP POST Params" do
11
11
  {:a => "a", :b => ["c", "d", "e"]}.to_params.should == "a=a&b[0]=c&b[1]=d&b[2]=e"
12
12
  end
13
-
14
- it "should transform a very complex hash into HTTP POST Params" do
15
- {:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]}.to_params.should == "a=a&b[0][d]=d&b[0][c]=c&b[1][f]=f&b[1][e]=e"
16
- end
13
+
14
+ # Ruby 1.8 Hash is not sorted, so this test breaks randomly. Maybe once we're all on 1.9. ;-)
15
+ # it "should transform a very complex hash into HTTP POST Params" do
16
+ # {:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]}.to_params.should == "a=a&b[0][d]=d&b[0][c]=c&b[1][f]=f&b[1][e]=e"
17
+ # end
17
18
  end
18
19
  end
data/test/test_request.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  require 'test/helper'
2
2
  require 'test/stallion'
3
-
3
+
4
4
  describe EventMachine::HttpRequest do
5
5
 
6
6
  def failed
7
7
  EventMachine.stop
8
8
  fail
9
9
  end
10
-
10
+
11
11
  it "should fail GET on DNS timeout" do
12
12
  EventMachine.run {
13
13
  http = EventMachine::HttpRequest.new('http://127.1.1.1/').get
@@ -68,12 +68,26 @@ describe EventMachine::HttpRequest do
68
68
  }
69
69
  end
70
70
 
71
+ it "should perform successfull HEAD with a URI passed as argument" do
72
+ EventMachine.run {
73
+ uri = URI.parse('http://127.0.0.1:8080/')
74
+ http = EventMachine::HttpRequest.new(uri).head
75
+
76
+ http.errback { failed }
77
+ http.callback {
78
+ http.response_header.status.should == 200
79
+ http.response.should == ""
80
+ EventMachine.stop
81
+ }
82
+ }
83
+ end
84
+
71
85
  it "should return 404 on invalid path" do
72
86
  EventMachine.run {
73
87
  http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/fail').get
74
88
 
75
89
  http.errback { failed }
76
- http.callback {
90
+ http.callback {
77
91
  http.response_header.status.should == 404
78
92
  EventMachine.stop
79
93
  }
@@ -247,10 +261,10 @@ describe EventMachine::HttpRequest do
247
261
  it "should timeout after 10 seconds" do
248
262
  EventMachine.run {
249
263
  t = Time.now.to_i
250
- http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/timeout').get :timeout => 2
264
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/timeout').get :timeout => 1
251
265
 
252
266
  http.errback {
253
- (Time.now.to_i - t).should == 2
267
+ (Time.now.to_i - t).should >= 2
254
268
  EventMachine.stop
255
269
  }
256
270
  http.callback { failed }
@@ -340,5 +354,5 @@ describe EventMachine::HttpRequest do
340
354
  }
341
355
  }
342
356
  end
343
-
344
- end
357
+
358
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: julien51-em-http-request
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Grigorik