rbkb-http 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,86 @@
1
+
2
+ module Rbkb::Http
3
+ # A Response encapsulates all the entities in a HTTP response,
4
+ # including the status header, general headers, and body.
5
+ class Response < Base
6
+ attr_accessor :status
7
+
8
+ alias first_entity status
9
+ alias first_entity= status=
10
+
11
+ # Returns a raw HTTP response for this instance. Must have a status
12
+ # element defined at a bare minimum.
13
+ def to_raw(raw_body=nil)
14
+ raise "this response has no status" unless first_entity()
15
+ self.headers ||= default_headers_obj()
16
+ self.body = raw_body if raw_body
17
+
18
+ if do_chunked_encoding?(@headers)
19
+ unless @body.is_a? ChunkedBody
20
+ @body = ChunkedBody.new(@body, @body.opts)
21
+ end
22
+ @headers.delete_header("Content-Length")
23
+ elsif not opts[:ignore_content_length]
24
+ unless @body.is_a? BoundBody
25
+ @body = BoundBody.new(@body, @body.opts)
26
+ end
27
+ @headers.delete_header("Transfer-Encoding")
28
+ else
29
+ @body = Body.new(@body, @body.opts)
30
+ end
31
+ @body.base = self
32
+
33
+ yield(self) if block_given?
34
+
35
+ bstr = @body.to_raw
36
+ hdrs = @headers.to_raw_array.unshift(self.first_entity.to_raw)
37
+ return "#{hdrs.join("\r\n")}\r\n\r\n#{bstr}"
38
+ end
39
+
40
+ # Parses a raw HTTP response and captures data into the current instance.
41
+ def capture(str)
42
+ raise "arg 0 must be a string" unless String === str
43
+ hstr, bstr = str.split(/\s*\r?\n\r?\n/, 2)
44
+
45
+ capture_headers(hstr)
46
+
47
+ yield(self, bstr) if block_given?
48
+
49
+ unless @body and @body.capture_complete?
50
+ @body =
51
+ if do_chunked_encoding?
52
+ ChunkedBody.new {|b| b.base = self }
53
+ elsif content_length()
54
+ BoundBody.new {|b| b.base = self }
55
+ else
56
+ Body.new {|b| b.base = self }
57
+ end
58
+ end
59
+
60
+ capture_body(bstr)
61
+
62
+ return self
63
+ end
64
+
65
+ # Indicates whether to use chunked encoding based on presence of
66
+ # the "Transfer-Encoding: chunked" header or the :ignore_chunked_encoding
67
+ # opts parameter.
68
+ def do_chunked_encoding?(hdrs=@headers)
69
+ ( (not @opts[:ignore_chunked_encoding]) and
70
+ (hdrs.get_header_value("Transfer-Encoding").to_s =~ /(?:^|\W)chunked(?:\W|$)/) )
71
+ end
72
+
73
+ # Returns a new Headers object extended as ResponseHeaders. This is the
74
+ # default object which will be used when composing fresh Response header
75
+ # entities.
76
+ def default_headers_obj(*args)
77
+ Headers.new(*args).extend(ResponseHeaders)
78
+ end
79
+
80
+ # Returns a new BoundBody object. This is the default object which will
81
+ # be used when composing fresh Response body entities.
82
+ def default_body_obj(*args)
83
+ BoundBody.new(*args)
84
+ end
85
+ end
86
+ end
data/lib/rbkb/http.rb ADDED
@@ -0,0 +1,22 @@
1
+ begin ; require 'rubygems' ; rescue LoadError ; end
2
+
3
+ require 'rbkb'
4
+
5
+ # ???Why???? would anyone create their own HTTP implementation in ruby with
6
+ # so many options out there? Short answer: Net::HTTP and others just don't cut
7
+ # it in lots of edge cases. I needed something I could control completely.
8
+
9
+ module Rbkb::Http
10
+ # nop
11
+ end
12
+
13
+ require 'time' # gives us Time.httpdate parser and output methods
14
+
15
+ require "rbkb/http/common.rb"
16
+ require "rbkb/http/base.rb"
17
+ require "rbkb/http/request.rb"
18
+ require "rbkb/http/response.rb"
19
+ require "rbkb/http/headers.rb"
20
+ require "rbkb/http/body.rb"
21
+ require "rbkb/http/parameters.rb"
22
+
data/rbkb-http.gemspec ADDED
@@ -0,0 +1,74 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rbkb-http}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Eric Monti"]
12
+ s.date = %q{2009-11-12}
13
+ s.description = %q{HTTP libraries and tools based on and complementary to Ruby BlackBag}
14
+ s.email = %q{emonti@matasano.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "History.txt",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/rbkb/http.rb",
28
+ "lib/rbkb/http/base.rb",
29
+ "lib/rbkb/http/body.rb",
30
+ "lib/rbkb/http/common.rb",
31
+ "lib/rbkb/http/headers.rb",
32
+ "lib/rbkb/http/parameters.rb",
33
+ "lib/rbkb/http/request.rb",
34
+ "lib/rbkb/http/response.rb",
35
+ "rbkb-http.gemspec",
36
+ "spec/rbkb-http_spec.rb",
37
+ "spec/spec_helper.rb",
38
+ "test/test_helper.rb",
39
+ "test/test_http.rb",
40
+ "test/test_http_helper.rb",
41
+ "test/test_http_request.rb",
42
+ "test/test_http_response.rb"
43
+ ]
44
+ s.homepage = %q{http://github.com/emonti/rbkb-http}
45
+ s.rdoc_options = ["--charset=UTF-8"]
46
+ s.require_paths = ["lib"]
47
+ s.rubygems_version = %q{1.3.5}
48
+ s.summary = %q{HTTP protocol add-ons for Ruby BlackBag}
49
+ s.test_files = [
50
+ "spec/rbkb-http_spec.rb",
51
+ "spec/spec_helper.rb",
52
+ "test/test_helper.rb",
53
+ "test/test_http.rb",
54
+ "test/test_http_helper.rb",
55
+ "test/test_http_request.rb",
56
+ "test/test_http_response.rb"
57
+ ]
58
+
59
+ if s.respond_to? :specification_version then
60
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
61
+ s.specification_version = 3
62
+
63
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
64
+ s.add_development_dependency(%q<rspec>, [">= 0"])
65
+ s.add_runtime_dependency(%q<rbkb>, [">= 0"])
66
+ else
67
+ s.add_dependency(%q<rspec>, [">= 0"])
68
+ s.add_dependency(%q<rbkb>, [">= 0"])
69
+ end
70
+ else
71
+ s.add_dependency(%q<rspec>, [">= 0"])
72
+ s.add_dependency(%q<rbkb>, [">= 0"])
73
+ end
74
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "RbkbHttp" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rbkb/http'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'rbkb/http'
7
+
8
+ class Test::Unit::TestCase
9
+ end
data/test/test_http.rb ADDED
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/test_http_helper.rb'
2
+
3
+ class TestHttp < Test::Unit::TestCase
4
+ include Rbkb::Http
5
+
6
+ def test_names
7
+ assert_equal CommonInterface, Rbkb::Http::CommonInterface
8
+ assert_equal Base, Rbkb::Http::Base
9
+
10
+ assert_equal Response, Rbkb::Http::Response
11
+ assert_equal Request, Rbkb::Http::Request
12
+ assert_equal Parameters, Rbkb::Http::Parameters
13
+ assert_equal FormUrlencodedParams, Rbkb::Http::FormUrlencodedParams
14
+
15
+ assert_equal Headers, Rbkb::Http::Headers
16
+ assert_equal RequestHeaders, Rbkb::Http::RequestHeaders
17
+ assert_equal RequestAction, Rbkb::Http::RequestAction
18
+ assert_equal ResponseHeaders, Rbkb::Http::ResponseHeaders
19
+ assert_equal ResponseStatus, Rbkb::Http::ResponseStatus
20
+
21
+ assert_equal Body, Rbkb::Http::Body
22
+ assert_equal BoundBody, Rbkb::Http::BoundBody
23
+ assert_equal ChunkedBody, Rbkb::Http::ChunkedBody
24
+ end
25
+
26
+ end
27
+
@@ -0,0 +1,59 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper.rb')
2
+
3
+ module HttpTestHelper
4
+ # contains various test cases to test common interface features
5
+ module CommonInterfaceTests
6
+
7
+ def setup()
8
+ raise "Helper stub called. Override setup() in TestCase"
9
+ end
10
+
11
+ def do_type_tests(x)
12
+ raise "Helper stub called. Override do_type_tests() in TestCase"
13
+ end
14
+
15
+ def do_type_tests(x)
16
+ raise "Helper stub called. Override do_capture_value_tests() in TestCase"
17
+ end
18
+
19
+ def test_init_parse
20
+ req = @obj_klass.new(@rawdat, @obj_opts)
21
+ do_capture_value_tests(req)
22
+ do_type_tests(req)
23
+ end
24
+
25
+ def test_parse
26
+ req = @obj_klass.parse(@rawdat, @obj_opts)
27
+ do_capture_value_tests(req)
28
+ do_type_tests(req)
29
+ end
30
+
31
+ def test_capture
32
+ req = @obj.capture(@rawdat)
33
+ do_capture_value_tests(req)
34
+ do_type_tests(req)
35
+ end
36
+
37
+ def test_back_to_raw
38
+ req = @obj.capture(@rawdat)
39
+ assert_equal @rawdat_crlf, req.to_raw
40
+ end
41
+
42
+ def test_capture_and_reuse_nondestructive
43
+ @obj.capture(@rawdat_crlf)
44
+ @obj.reset_capture
45
+ @obj.capture(@rawdat_crlf)
46
+ do_capture_value_tests(@obj)
47
+ do_type_tests(@obj)
48
+ end
49
+
50
+ def test_capture_and_reuse_destructive
51
+ @obj.capture(@rawdat_crlf)
52
+ @obj.reset_capture!
53
+ @obj.capture(@rawdat_crlf)
54
+ do_capture_value_tests(@obj)
55
+ do_type_tests(@obj)
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,136 @@
1
+ require File.dirname(__FILE__) + '/test_http_helper.rb'
2
+
3
+ class TestHttpRequest < Test::Unit::TestCase
4
+ include HttpTestHelper::CommonInterfaceTests
5
+
6
+ include Rbkb::Http
7
+
8
+ def setup
9
+ @obj_klass = Request
10
+ @obj = @obj_klass.new
11
+
12
+ @rawdat =<<_EOF_
13
+ GET /csi?v=3&s=webhp&action=&tran=undefined HTTP/1.1
14
+ Host: www.google.com
15
+ User-Agent: Mozilla/5.0
16
+ Accept: image/png,image/*;q=0.8,*/*;q=0.5
17
+ Accept-Language: en-us,en;q=0.5
18
+ Accept-Encoding: gzip,deflate
19
+ Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
20
+ Keep-Alive: 300
21
+ Proxy-Connection: keep-alive
22
+ Referer: http://www.google.com/
23
+ Cookie: PREFID=NNNN:LM=1237996892:S=YYYYY; NID=111
24
+
25
+ _EOF_
26
+
27
+ @hstr, @body = @rawdat.split(/^\n/, 2)
28
+ @rawdat_crlf = @hstr.gsub("\n", "\r\n") + "\r\n" + @body
29
+
30
+ @verb = "GET"
31
+ @uri = "/csi?v=3&s=webhp&action=&tran=undefined"
32
+ @path, @query = @uri.split('?',2)
33
+ @req_parameters = [
34
+ ["v", "3"],
35
+ ["s", "webhp"],
36
+ ["action", ""],
37
+ ["tran", "undefined"]
38
+ ]
39
+ @version = "HTTP/1.1"
40
+
41
+ @headers = [
42
+ ["Host", "www.google.com"],
43
+ ["User-Agent", "Mozilla/5.0"],
44
+ ["Accept", "image/png,image/*;q=0.8,*/*;q=0.5"],
45
+ ["Accept-Language", "en-us,en;q=0.5"],
46
+ ["Accept-Encoding", "gzip,deflate"],
47
+ ["Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7"],
48
+ ["Keep-Alive", "300"],
49
+ ["Proxy-Connection", "keep-alive"],
50
+ ["Referer", "http://www.google.com/"],
51
+ ["Cookie", "PREFID=NNNN:LM=1237996892:S=YYYYY; NID=111"],
52
+ ]
53
+ end
54
+
55
+ def do_type_tests(req)
56
+ assert_kind_of Request, req
57
+ assert_kind_of Headers, req.headers
58
+ assert_kind_of Body, req.body
59
+ assert_kind_of RequestAction, req.action
60
+ assert_kind_of RequestHeaders, req.headers
61
+ end
62
+
63
+ def do_capture_value_tests(req)
64
+ assert_equal @headers, req.headers
65
+ assert_equal @body, req.body.to_s
66
+ assert_equal @uri, req.action.uri.to_s
67
+ assert_equal @path, req.action.uri.path
68
+ assert_equal @query, req.action.uri.query
69
+ assert_equal @verb, req.action.verb
70
+ assert_equal @version, req.action.version
71
+ assert_equal @req_parameters, req.action_parameters
72
+ end
73
+
74
+ def test_capture_crlf_headers
75
+ req = @obj.capture(@rawdat_crlf)
76
+ do_capture_value_tests(req)
77
+ do_type_tests(req)
78
+ assert_equal @rawdat_crlf, req.to_raw
79
+ end
80
+
81
+ def test_captured_body_type
82
+ @obj.capture(@rawdat)
83
+ assert_kind_of Body, @obj.body
84
+ end
85
+
86
+ end
87
+
88
+
89
+ class TestHttpPostRequest < TestHttpRequest
90
+
91
+ def setup
92
+ @obj_klass = Request
93
+ @obj = @obj_klass.new
94
+
95
+ @rawdat =<<_EOF_
96
+ POST /path/script.cgi?qtype=foo HTTP/1.0
97
+ From: frog@jmarshall.com
98
+ HasColon: this_has_a_colon:yikes
99
+ User-Agent: HTTPTool/1.0
100
+ Content-Type: application/x-www-form-urlencoded
101
+ Content-Length: 32
102
+
103
+ home=Cosby&favorite+flavor=flies
104
+ _EOF_
105
+ @rawdat.chomp!
106
+
107
+ @hstr, @body = @rawdat.split(/^\n/, 2)
108
+ @rawdat_crlf = @hstr.gsub("\n", "\r\n") + "\r\n" + @body
109
+
110
+ @verb = "POST"
111
+ @uri = "/path/script.cgi?qtype=foo"
112
+ @path, @query = @uri.split('?',2)
113
+ @req_parameters = [
114
+ ["qtype", "foo"],
115
+ ]
116
+ @version = "HTTP/1.0"
117
+
118
+ @headers = [
119
+ ["From", "frog@jmarshall.com"],
120
+ ["HasColon", "this_has_a_colon:yikes"],
121
+ ["User-Agent", "HTTPTool/1.0"],
122
+ ["Content-Type", "application/x-www-form-urlencoded"],
123
+ ["Content-Length", "32"],
124
+ ]
125
+
126
+ @post_parameters = [["home", "Cosby"], ["favorite+flavor", "flies"]]
127
+ end
128
+
129
+ def test_captured_body_type
130
+ @obj.capture(@rawdat)
131
+ assert_kind_of BoundBody, @obj.body
132
+ end
133
+
134
+
135
+ end
136
+
@@ -0,0 +1,222 @@
1
+ require File.dirname(__FILE__) + '/test_http_helper.rb'
2
+
3
+ class TestHttpResponse < Test::Unit::TestCase
4
+ include HttpTestHelper::CommonInterfaceTests
5
+
6
+ include Rbkb::Http
7
+
8
+ def setup
9
+ @obj_klass = Response
10
+ @obj_opts = nil
11
+ @obj = @obj_klass.new(nil, @obj_opts)
12
+
13
+ @rawdat =<<_EOF_
14
+ HTTP/1.0 404 Not Found
15
+ Date: Thu, 26 Mar 2009 01:18:52 GMT
16
+ Server: Apache
17
+ Content-Type: text/html; charset=iso-8859-1
18
+ Content-Length: 190
19
+ Connection: Keep-Alive
20
+
21
+ <html><head>
22
+ <title>Error report</title></head>
23
+ <body><h1>HTTP Status 404</h1><HR size="1" noshade><p><u>The requested resource is not available.</u></p><HR size="1" noshade>
24
+ </body></html>
25
+ _EOF_
26
+
27
+ @hstr, @body = @rawdat.split(/^\n/, 2)
28
+ @rawdat_crlf = @hstr.gsub("\n", "\r\n") + "\r\n" + @body
29
+
30
+ @code = 404
31
+ @text = "Not Found"
32
+ @version = "HTTP/1.0"
33
+
34
+ @headers = [
35
+ ["Date", "Thu, 26 Mar 2009 01:18:52 GMT"],
36
+ ["Server", "Apache"],
37
+ ["Content-Type", "text/html; charset=iso-8859-1"],
38
+ ["Content-Length", "190"],
39
+ ["Connection", "Keep-Alive"]
40
+ ]
41
+
42
+ @content_length = 190
43
+ end
44
+
45
+ def do_type_tests(rsp)
46
+ assert_kind_of Response, rsp
47
+ assert_kind_of Headers, rsp.headers
48
+ assert_kind_of Body, rsp.body
49
+ assert_kind_of ResponseStatus, rsp.status
50
+ assert_kind_of ResponseHeaders, rsp.headers
51
+ end
52
+
53
+ def do_capture_value_tests(rsp)
54
+ assert_equal @headers, rsp.headers
55
+ assert_equal @body, rsp.body
56
+ assert_equal @code, rsp.status.code
57
+ assert_equal @text, rsp.status.text
58
+ assert_equal @version, rsp.status.version
59
+ assert_equal @content_length, rsp.content_length
60
+ end
61
+
62
+ def test_capture_crlf_headers
63
+ @obj.capture(@rawdat_crlf)
64
+ do_capture_value_tests(@obj)
65
+ do_type_tests(@obj)
66
+ assert_equal @rawdat_crlf, @obj.to_raw
67
+ end
68
+
69
+ def test_captured_body_type
70
+ @obj.capture(@rawdat)
71
+ assert_kind_of BoundBody, @obj.body
72
+ end
73
+ end
74
+
75
+
76
+ class TestHttpResponseChunked < TestHttpResponse
77
+ include Rbkb::Http
78
+
79
+ def setup
80
+ @obj_klass = Response
81
+ @obj_opts = {}
82
+ @obj = @obj_klass.new
83
+
84
+ @rawdat =<<_EOF_
85
+ HTTP/1.1 200 OK
86
+ Date: Thu, 26 Mar 2009 01:18:52 GMT
87
+ Server: Apache
88
+ Content-Type: text/html; charset=iso-8859-1
89
+ Transfer-Encoding: chunked
90
+ Connection: Keep-Alive
91
+
92
+ 20
93
+ This is a test of a chunked-enco
94
+
95
+ 10
96
+ ded HTTP request
97
+
98
+ 0
99
+ _EOF_
100
+
101
+ @hstr, @rawbody = @rawdat.split(/^\n/, 2)
102
+ @rawdat_crlf = @rawdat.gsub("\n", "\r\n")
103
+ @hdrs_crlf = @hstr.gsub("\n", "\r\n")
104
+
105
+ @body = "This is a test of a chunked-encoded HTTP request"
106
+
107
+ @code = 200
108
+ @text = "OK"
109
+ @version = "HTTP/1.1"
110
+
111
+ @headers = [
112
+ ["Date", "Thu, 26 Mar 2009 01:18:52 GMT"],
113
+ ["Server", "Apache"],
114
+ ["Content-Type", "text/html; charset=iso-8859-1"],
115
+ ["Transfer-Encoding", "chunked"],
116
+ ["Connection", "Keep-Alive"]
117
+ ]
118
+
119
+ @content_length = nil
120
+ @tc_chunk_size = 0x20
121
+ end
122
+
123
+ def test_captured_body_type
124
+ @obj.capture(@rawdat)
125
+ assert_kind_of ChunkedBody, @obj.body
126
+ end
127
+
128
+ def test_back_to_raw
129
+ @obj.capture(@rawdat)
130
+ do_capture_value_tests(@obj)
131
+ do_type_tests(@obj)
132
+ @obj.body.opts[:output_chunk_size] = @tc_chunk_size
133
+ assert_equal @rawdat_crlf, @obj.to_raw
134
+ end
135
+
136
+ def test_capture_crlf_headers
137
+ @obj.capture(@rawdat_crlf)
138
+ do_capture_value_tests(@obj)
139
+ do_type_tests(@obj)
140
+ @obj.body.opts[:output_chunk_size] = @tc_chunk_size
141
+ assert_equal @rawdat_crlf, @obj.to_raw
142
+ end
143
+
144
+ def test_default_chunk_size
145
+ if @body.size > ChunkedBody::DEFAULT_CHUNK_SIZE
146
+ assert "TESTCASE ERROR!!!", "make the setup() @body < DEFAULT_CHUNK_SIZE"
147
+ end
148
+ raw_tc = "#{@hdrs_crlf}\r\n#{@body.size.to_s(16)}\r\n#{@body}\r\n\r\n0\r\n"
149
+ @obj.capture(@rawdat_crlf)
150
+ do_capture_value_tests(@obj)
151
+ do_type_tests(@obj)
152
+ assert_equal raw_tc, @obj.to_raw
153
+ end
154
+ end
155
+
156
+ # This test-case simulates a HTTP response to a HEAD request. This type of
157
+ # response is special since it returns Content-Length: NNN or
158
+ # Transfer-Encoding: chunked headers without any actual body data.
159
+ # To handle this special situation, we use the 'ignore_content_length' and
160
+ # 'ignore_chunked_encoding' options.
161
+ class TestHttpResponseToHead < TestHttpResponse
162
+ def setup
163
+ @obj_klass = Response
164
+
165
+ # Technically, a server should only respond to HEAD with one of
166
+ # content length *or* chunked encoding. However, we ignore them both.
167
+ @obj_opts = {
168
+ :ignore_content_length => true,
169
+ :ignore_chunked_encoding => true
170
+ }
171
+ @obj = @obj_klass.new(nil, @obj_opts)
172
+
173
+ # Note, our test-case includes both content length and chunked encoding.
174
+ # A real server probably wouldn't do this, but we want to make sure
175
+ # we handle both.
176
+ @rawdat =<<_EOF_
177
+ HTTP/1.1 200 OK
178
+ Cache-Control: private, max-age=0
179
+ Date: Fri, 27 Mar 2009 04:27:27 GMT
180
+ Expires: -1
181
+ Content-Length: 9140
182
+ Content-Type: text/html; charset=ISO-8859-1
183
+ Server: Booble
184
+ Transfer-Encoding: chunked
185
+
186
+ _EOF_
187
+
188
+ @hstr, @body = @rawdat.split(/^\n/, 2)
189
+ @rawdat_crlf = @hstr.gsub("\n", "\r\n") + "\r\n" + @body
190
+
191
+ @code = 200
192
+ @text = "OK"
193
+ @version = "HTTP/1.1"
194
+
195
+ @headers = [
196
+ ["Cache-Control", "private, max-age=0"],
197
+ ["Date", "Fri, 27 Mar 2009 04:27:27 GMT"],
198
+ ["Expires", "-1"],
199
+ ["Content-Length", "9140"],
200
+ ["Content-Type", "text/html; charset=ISO-8859-1"],
201
+ ["Server", "Booble"],
202
+ ["Transfer-Encoding", "chunked"]
203
+ ]
204
+
205
+ # Content length should get ignored
206
+ @content_length = nil
207
+ end
208
+
209
+ def test_capture_crlf_headers
210
+ @obj.capture(@rawdat_crlf)
211
+ do_capture_value_tests(@obj)
212
+ do_type_tests(@obj)
213
+ assert_equal @rawdat_crlf, @obj.to_raw
214
+ end
215
+
216
+ def test_captured_body_type
217
+ @obj.capture(@rawdat)
218
+ assert_kind_of Body, @obj.body
219
+ end
220
+
221
+ end
222
+