minhttp 0.0.8 → 0.0.9
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/VERSION +1 -1
- data/lib/chunk.rb +32 -0
- data/lib/chunk.rb~ +33 -0
- data/lib/exception.rb +4 -0
- data/lib/exception.rb~ +4 -0
- data/lib/minhttp.rb +13 -0
- data/test/simple_test.rb +59 -1
- metadata +13 -14
- data/examples/synchronous_example.rb~ +0 -20
- data/lib/minparser.rb~ +0 -20
- data/lib/rawparser.rb~ +0 -23
- data/test/simple_test.rb~ +0 -10
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.0.
|
|
1
|
+
0.0.9
|
data/lib/chunk.rb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module MinHttp
|
|
2
|
+
class Chunk
|
|
3
|
+
def initialize(body)
|
|
4
|
+
@body = body
|
|
5
|
+
@newbody = ""
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def read_chunk_size
|
|
9
|
+
chunk_info, @body = @body.split("\r\n", 2)
|
|
10
|
+
chunk_info.to_i(16)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def read_chunk
|
|
14
|
+
@newbody << @body[0, @chunk_size]
|
|
15
|
+
new_body_len = @body.length - @chunk_size
|
|
16
|
+
@body = @body[@chunk_size+2, new_body_len-2]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def parse
|
|
20
|
+
@length = 0
|
|
21
|
+
@chunk_size = read_chunk_size
|
|
22
|
+
|
|
23
|
+
while (@chunk_size > 0)
|
|
24
|
+
read_chunk
|
|
25
|
+
@length = @length + @chunk_size
|
|
26
|
+
@chunk_size = read_chunk_size
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
return @newbody
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/chunk.rb~
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module MinHttp
|
|
2
|
+
|
|
3
|
+
class Chunk
|
|
4
|
+
def initialize(header, body)
|
|
5
|
+
@header = header
|
|
6
|
+
@body = body
|
|
7
|
+
@newbody = ""
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def read_chunk_size
|
|
11
|
+
chunk_info, @body = @body.split("\r\n", 2)
|
|
12
|
+
chunk_info.to_i(16)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def read_chunk
|
|
16
|
+
@newbody << @body[0, @chunk_size]
|
|
17
|
+
new_body_len = @body.length - @chunk_size
|
|
18
|
+
@body = @body[@chunk_size+2, new_body_len-2]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def parse
|
|
22
|
+
@length = 0
|
|
23
|
+
@chunk_size = read_chunk_size
|
|
24
|
+
while (@chunk_size > 0)
|
|
25
|
+
read_chunk
|
|
26
|
+
@length = @length + @chunk_size
|
|
27
|
+
@chunk_size = read_chunk_size
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
return @header, @newbody
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/exception.rb
ADDED
data/lib/exception.rb~
ADDED
data/lib/minhttp.rb
CHANGED
|
@@ -2,6 +2,8 @@ require 'http/parser'
|
|
|
2
2
|
require 'eventmachine'
|
|
3
3
|
require 'logger'
|
|
4
4
|
require_relative "ssl_validator"
|
|
5
|
+
require_relative "chunk"
|
|
6
|
+
require_relative "exception"
|
|
5
7
|
|
|
6
8
|
#
|
|
7
9
|
# The minimal HTTP client
|
|
@@ -32,6 +34,9 @@ module Http
|
|
|
32
34
|
|
|
33
35
|
def self.connect(host, data, port=80, ssl=false, &callback)
|
|
34
36
|
configure unless configured?
|
|
37
|
+
unless (data =~ /\A[^\r\n]+HTTP\/1\.0/ || data =~ /Connection[^\r\n]+close/)
|
|
38
|
+
raise MinHttp::PersistentConnectionException.new("MinHTTP does not support persistent connections, so the request data must indicate HTTP 1.0 or it must include a 'Connection: close' header")
|
|
39
|
+
end
|
|
35
40
|
|
|
36
41
|
EventMachine.connect(host, port, self) do |c|
|
|
37
42
|
# this code runs after 'post_init', before 'connection_completed'
|
|
@@ -81,6 +86,14 @@ module Http
|
|
|
81
86
|
def unbind
|
|
82
87
|
begin
|
|
83
88
|
@@connections -= 1
|
|
89
|
+
|
|
90
|
+
# combine the chunks of a chunked response
|
|
91
|
+
if @parser.headers["Transfer-Encoding"] == "chunked"
|
|
92
|
+
headers, body = @response_data.split("\r\n\r\n", 2)
|
|
93
|
+
body = MinHttp::Chunk.new(body).parse
|
|
94
|
+
@response_data = "#{headers}\r\n\r\n#{body}"
|
|
95
|
+
end
|
|
96
|
+
|
|
84
97
|
@callback.call(@response_data, @parser)
|
|
85
98
|
rescue Exception => e
|
|
86
99
|
@@logger.error("Error in unbind: #{e}")
|
data/test/simple_test.rb
CHANGED
|
@@ -2,6 +2,7 @@ require 'minitest/autorun'
|
|
|
2
2
|
require_relative "../lib/minhttp"
|
|
3
3
|
|
|
4
4
|
class SimpleTest < MiniTest::Unit::TestCase
|
|
5
|
+
|
|
5
6
|
def test_simple_google
|
|
6
7
|
data = <<-HTTP
|
|
7
8
|
GET / HTTP/1.0\r
|
|
@@ -12,11 +13,68 @@ HTTP
|
|
|
12
13
|
EventMachine::run do
|
|
13
14
|
Http::Min.connect("www.google.com", data) do |raw_response, parsed_response|
|
|
14
15
|
assert(parsed_response.status_code == 200, "Response from google should be 200 but is #{parsed_response.status_code}")
|
|
15
|
-
assert(raw_response.length > 0, "Raw response from google should
|
|
16
|
+
assert(raw_response.length > 0, "Raw response from google should have size larger than 0")
|
|
16
17
|
EM::stop
|
|
17
18
|
end
|
|
18
19
|
end
|
|
20
|
+
end
|
|
19
21
|
|
|
22
|
+
def test_chunked
|
|
23
|
+
data = <<-HTTP
|
|
24
|
+
GET /httpgallery/chunked/ HTTP/1.1\r
|
|
25
|
+
Host: www.httpwatch.com\r
|
|
26
|
+
Connection: close
|
|
27
|
+
|
|
28
|
+
HTTP
|
|
29
|
+
|
|
30
|
+
EventMachine::run do
|
|
31
|
+
Http::Min.connect("www.httpwatch.com", data) do |raw_response, parsed_response|
|
|
32
|
+
assert(parsed_response.status_code == 200, "Response from httpwatch should be 200 but is #{parsed_response.status_code}")
|
|
33
|
+
assert(raw_response.length > 0, "Raw response from httpwatch should have size larger than 0")
|
|
34
|
+
EM::stop
|
|
35
|
+
end
|
|
36
|
+
end
|
|
20
37
|
end
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# MinHttp does not support persistent HTTP connections
|
|
41
|
+
def test_http11_with_connection_close
|
|
42
|
+
data = <<-HTTP
|
|
43
|
+
GET / HTTP/1.1\r
|
|
44
|
+
Host: www.google.com\r
|
|
45
|
+
Connection: close
|
|
46
|
+
|
|
47
|
+
HTTP
|
|
48
|
+
|
|
49
|
+
EventMachine::run do
|
|
50
|
+
Http::Min.connect("www.google.com", data) do |raw_response, parsed_response|
|
|
51
|
+
assert(parsed_response.status_code == 200, "Response from google should be 200 but is #{parsed_response.status_code}")
|
|
52
|
+
assert(raw_response.length > 0, "Raw response from google should have size larger than 0")
|
|
53
|
+
EM::stop
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# When the 'connection: close' header is not present, the
|
|
60
|
+
# connection is presumed to be persistent. MinHTTP does
|
|
61
|
+
# not support persistent connections so it throws an
|
|
62
|
+
# exception
|
|
63
|
+
def test_http11_without_connection_close
|
|
64
|
+
data = <<-HTTP
|
|
65
|
+
GET / HTTP/1.1\r
|
|
66
|
+
Host: www.google.com\r
|
|
67
|
+
|
|
68
|
+
HTTP
|
|
69
|
+
|
|
70
|
+
assert_raises(MinHttp::PersistentConnectionException) do
|
|
71
|
+
EventMachine::run do
|
|
72
|
+
Http::Min.connect("www.google.com", data) do |raw_response, parsed_response|
|
|
73
|
+
EM::stop
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
21
79
|
end
|
|
22
80
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: minhttp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.9
|
|
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: 2011-
|
|
12
|
+
date: 2011-10-21 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: http_parser.rb
|
|
16
|
-
requirement: &
|
|
16
|
+
requirement: &70258984044100 !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
19
|
- - ! '>='
|
|
@@ -21,10 +21,10 @@ dependencies:
|
|
|
21
21
|
version: '0'
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
|
-
version_requirements: *
|
|
24
|
+
version_requirements: *70258984044100
|
|
25
25
|
- !ruby/object:Gem::Dependency
|
|
26
26
|
name: eventmachine
|
|
27
|
-
requirement: &
|
|
27
|
+
requirement: &70258984043140 !ruby/object:Gem::Requirement
|
|
28
28
|
none: false
|
|
29
29
|
requirements:
|
|
30
30
|
- - ! '>='
|
|
@@ -32,7 +32,7 @@ dependencies:
|
|
|
32
32
|
version: '0'
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
|
-
version_requirements: *
|
|
35
|
+
version_requirements: *70258984043140
|
|
36
36
|
description: MinHTTP allows one to send and receive raw HTTP requests. It's a very
|
|
37
37
|
thin wrapper around EventMachine's connect method with some SSL validation added.
|
|
38
38
|
email:
|
|
@@ -46,14 +46,14 @@ files:
|
|
|
46
46
|
- Gemfile
|
|
47
47
|
- Rakefile
|
|
48
48
|
- cacert.pem
|
|
49
|
-
- examples/synchronous_example.rb
|
|
50
|
-
- examples/synchronous_example.rb~
|
|
51
49
|
- examples/readme_example.rb
|
|
52
|
-
-
|
|
53
|
-
- lib/
|
|
50
|
+
- examples/synchronous_example.rb
|
|
51
|
+
- lib/chunk.rb
|
|
52
|
+
- lib/chunk.rb~
|
|
53
|
+
- lib/exception.rb
|
|
54
|
+
- lib/exception.rb~
|
|
54
55
|
- lib/minhttp.rb
|
|
55
|
-
- lib/
|
|
56
|
-
- test/simple_test.rb~
|
|
56
|
+
- lib/ssl_validator.rb
|
|
57
57
|
- test/simple_test.rb
|
|
58
58
|
homepage: http://github.com/ahfarmer/minhttp
|
|
59
59
|
licenses: []
|
|
@@ -75,10 +75,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
75
75
|
version: '0'
|
|
76
76
|
requirements: []
|
|
77
77
|
rubyforge_project: minhttp
|
|
78
|
-
rubygems_version: 1.8.
|
|
78
|
+
rubygems_version: 1.8.11
|
|
79
79
|
signing_key:
|
|
80
80
|
specification_version: 3
|
|
81
81
|
summary: An HTTP library for the minimalist.
|
|
82
82
|
test_files:
|
|
83
|
-
- test/simple_test.rb~
|
|
84
83
|
- test/simple_test.rb
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
require_relative '../lib/minhttp'
|
|
2
|
-
require 'em-synchrony'
|
|
3
|
-
|
|
4
|
-
data = <<-HTTP
|
|
5
|
-
GET / HTTP/1.0\r
|
|
6
|
-
Host: www.google.com\r
|
|
7
|
-
|
|
8
|
-
HTTP
|
|
9
|
-
|
|
10
|
-
EventMachine::run do
|
|
11
|
-
Http::Min.connect("www.google.com", data) do |raw_response, parsed_response|
|
|
12
|
-
puts "Received #{parsed_response.status_code} status from Google"
|
|
13
|
-
puts "First 100 characters of raw HTTP response:"
|
|
14
|
-
puts raw_response[0..100]
|
|
15
|
-
# EM::stop
|
|
16
|
-
Fiber.yield
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
fiber.resume
|
data/lib/minparser.rb~
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
require 'http/parser'
|
|
2
|
-
require 'eventmachine'
|
|
3
|
-
require 'logger'
|
|
4
|
-
require_relative "ssl_validator"
|
|
5
|
-
|
|
6
|
-
#
|
|
7
|
-
# The minimal HTTP client
|
|
8
|
-
# Sends a raw http request (bytes)
|
|
9
|
-
# Parses the response and provides both the parsed and the raw response
|
|
10
|
-
# Supports ssl
|
|
11
|
-
#
|
|
12
|
-
module Http
|
|
13
|
-
class MinParser
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
parser = Http::Parser.new
|
|
17
|
-
parser.on_headers_complete = proc{ :stop }
|
|
18
|
-
|
|
19
|
-
offset = parser << request_data
|
|
20
|
-
body = request_data[offset..-1]
|
data/lib/rawparser.rb~
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
require 'http/parser'
|
|
2
|
-
require 'eventmachine'
|
|
3
|
-
require 'logger'
|
|
4
|
-
require_relative "ssl_validator"
|
|
5
|
-
|
|
6
|
-
#
|
|
7
|
-
# The minimal HTTP parser
|
|
8
|
-
# Simple wrapper around http_parser.rb that supplies access to the raw
|
|
9
|
-
#
|
|
10
|
-
module Http
|
|
11
|
-
class RawParser
|
|
12
|
-
def initialize
|
|
13
|
-
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def <<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
parser = Http::Parser.new
|
|
20
|
-
parser.on_headers_complete = proc{ :stop }
|
|
21
|
-
|
|
22
|
-
offset = parser << request_data
|
|
23
|
-
body = request_data[offset..-1]
|