net-http-server 0.2.2 → 0.2.4
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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/ChangeLog.md +17 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +1 -1
- data/README.md +26 -18
- data/Rakefile +11 -28
- data/examples/config.ru +3 -0
- data/examples/test_app.rb +21 -0
- data/gemspec.yml +10 -4
- data/lib/net/http/server/chunked_stream.rb +4 -5
- data/lib/net/http/server/daemon.rb +17 -17
- data/lib/net/http/server/parser.rb +7 -7
- data/lib/net/http/server/requests.rb +1 -1
- data/lib/net/http/server/server.rb +16 -13
- data/lib/net/http/server/stream.rb +1 -1
- data/lib/net/http/server/version.rb +1 -1
- data/lib/rack/handler/http.rb +9 -9
- data/net-http-server.gemspec +40 -109
- data/spec/net/http/server/chunked_stream_spec.rb +11 -11
- data/spec/net/http/server/daemon_spec.rb +4 -4
- data/spec/net/http/server/parser_spec.rb +23 -23
- data/spec/net/http/server/requests_spec.rb +12 -12
- data/spec/net/http/server/responses_spec.rb +17 -17
- data/spec/net/http/server/stream_spec.rb +7 -7
- data/spec/rack/handler/helpers/test_request.rb +12 -3
- data/spec/rack/handler/http_spec.rb +27 -26
- data/spec/spec_helper.rb +0 -1
- metadata +37 -55
- data/.gemtest +0 -0
data/net-http-server.gemspec
CHANGED
@@ -2,130 +2,61 @@
|
|
2
2
|
|
3
3
|
require 'yaml'
|
4
4
|
|
5
|
-
Gem::Specification.new do |
|
6
|
-
|
7
|
-
lib_dir = File.join(root,'lib')
|
8
|
-
files = if File.directory?('.git')
|
9
|
-
`git ls-files`.split($/)
|
10
|
-
elsif File.directory?('.hg')
|
11
|
-
`hg manifest`.split($/)
|
12
|
-
elsif File.directory?('.svn')
|
13
|
-
`svn ls -R`.split($/).select { |path| File.file?(path) }
|
14
|
-
else
|
15
|
-
Dir['{**/}{.*,*}'].select { |path| File.file?(path) }
|
16
|
-
end
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gemspec = YAML.load_file('gemspec.yml')
|
17
7
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
when String
|
23
|
-
(files & Dir[paths])
|
24
|
-
end
|
25
|
-
}
|
26
|
-
|
27
|
-
version = {
|
28
|
-
:file => 'net/http/server/version.rb',
|
29
|
-
:constant => 'Net::HTTP::Server::VERSION'
|
30
|
-
}
|
31
|
-
|
32
|
-
defaults = {
|
33
|
-
'name' => File.basename(File.dirname(__FILE__)),
|
34
|
-
'files' => files,
|
35
|
-
'executables' => filter_files['bin/*'].map { |path| File.basename(path) },
|
36
|
-
'test_files' => filter_files['{test/{**/}*_test.rb,spec/{**/}*_spec.rb}'],
|
37
|
-
'extra_doc_files' => filter_files['*.{txt,rdoc,md,markdown,tt,textile}'],
|
38
|
-
}
|
8
|
+
gem.name = gemspec.fetch('name')
|
9
|
+
gem.version = gemspec.fetch('version') do
|
10
|
+
lib_dir = File.join(File.dirname(__FILE__),'lib')
|
11
|
+
$LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
|
39
12
|
|
40
|
-
|
13
|
+
require 'net/http/server/version'
|
14
|
+
Net::HTTP::Server::VERSION
|
15
|
+
end
|
41
16
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
17
|
+
gem.summary = gemspec['summary']
|
18
|
+
gem.description = gemspec['description']
|
19
|
+
gem.licenses = Array(gemspec['license'])
|
20
|
+
gem.authors = Array(gemspec['authors'])
|
21
|
+
gem.email = gemspec['email']
|
22
|
+
gem.homepage = gemspec['homepage']
|
23
|
+
gem.metadata = gemspec['metadata'] if gemspec['metadata']
|
47
24
|
|
48
|
-
|
49
|
-
eval(version[:constant])
|
50
|
-
end
|
25
|
+
glob = lambda { |patterns| gem.files & Dir[*patterns] }
|
51
26
|
|
52
|
-
|
53
|
-
|
27
|
+
gem.files = `git ls-files`.split($/)
|
28
|
+
gem.files = glob[gemspec['files']] if gemspec['files']
|
54
29
|
|
55
|
-
|
56
|
-
|
57
|
-
gemspec.licenses = metadata['license']
|
58
|
-
when String
|
59
|
-
gemspec.license = metadata['license']
|
30
|
+
gem.executables = gemspec.fetch('executables') do
|
31
|
+
glob['bin/*'].map { |path| File.basename(path) }
|
60
32
|
end
|
33
|
+
gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
|
61
34
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
gemspec.author = metadata['authors']
|
67
|
-
end
|
68
|
-
|
69
|
-
gemspec.email = metadata['email']
|
70
|
-
gemspec.homepage = metadata['homepage']
|
35
|
+
gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
|
36
|
+
gem.test_files = glob[gemspec['test_files'] || \
|
37
|
+
'{test/{**/}*_test.rb,spec/{**/}*_spec.rb}']
|
38
|
+
gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
|
71
39
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
when String
|
76
|
-
gemspec.require_path = metadata['require_paths']
|
77
|
-
end
|
40
|
+
gem.require_paths = Array(gemspec.fetch('require_paths') {
|
41
|
+
%w[ext lib].select { |dir| File.directory?(dir) }
|
42
|
+
})
|
78
43
|
|
79
|
-
|
44
|
+
gem.requirements = gemspec['requirements']
|
45
|
+
gem.required_ruby_version = gemspec['required_ruby_version']
|
46
|
+
gem.required_rubygems_version = gemspec['required_rubygems_version']
|
47
|
+
gem.post_install_message = gemspec['post_install_message']
|
80
48
|
|
81
|
-
|
82
|
-
gemspec.extensions = metadata['extensions']
|
83
|
-
|
84
|
-
if Gem::VERSION < '1.7.'
|
85
|
-
gemspec.default_executable = gemspec.executables.first
|
86
|
-
end
|
87
|
-
|
88
|
-
gemspec.test_files = filter_files[metadata['test_files']]
|
89
|
-
|
90
|
-
unless gemspec.files.include?('.document')
|
91
|
-
gemspec.extra_rdoc_files = metadata['extra_doc_files']
|
92
|
-
end
|
93
|
-
|
94
|
-
gemspec.post_install_message = metadata['post_install_message']
|
95
|
-
gemspec.requirements = metadata['requirements']
|
96
|
-
|
97
|
-
if gemspec.respond_to?(:required_ruby_version=)
|
98
|
-
gemspec.required_ruby_version = metadata['required_ruby_version']
|
99
|
-
end
|
100
|
-
|
101
|
-
if gemspec.respond_to?(:required_rubygems_version=)
|
102
|
-
gemspec.required_rubygems_version = metadata['required_ruby_version']
|
103
|
-
end
|
104
|
-
|
105
|
-
parse_versions = lambda { |versions|
|
106
|
-
case versions
|
107
|
-
when Array
|
108
|
-
versions.map { |v| v.to_s }
|
109
|
-
when String
|
110
|
-
versions.split(/,\s*/)
|
111
|
-
end
|
112
|
-
}
|
113
|
-
|
114
|
-
if metadata['dependencies']
|
115
|
-
metadata['dependencies'].each do |name,versions|
|
116
|
-
gemspec.add_dependency(name,parse_versions[versions])
|
117
|
-
end
|
118
|
-
end
|
49
|
+
split = lambda { |string| string.split(/,\s*/) }
|
119
50
|
|
120
|
-
if
|
121
|
-
|
122
|
-
|
51
|
+
if gemspec['dependencies']
|
52
|
+
gemspec['dependencies'].each do |name,versions|
|
53
|
+
gem.add_dependency(name,split[versions])
|
123
54
|
end
|
124
55
|
end
|
125
56
|
|
126
|
-
if
|
127
|
-
|
128
|
-
|
57
|
+
if gemspec['development_dependencies']
|
58
|
+
gemspec['development_dependencies'].each do |name,versions|
|
59
|
+
gem.add_development_dependency(name,split[versions])
|
129
60
|
end
|
130
61
|
end
|
131
62
|
end
|
@@ -11,39 +11,39 @@ describe Net::HTTP::Server::ChunkedStream do
|
|
11
11
|
socket = StringIO.new("%x\r\n%s\r\n0\r\n\r\n" % [data.length, data])
|
12
12
|
stream = described_class.new(socket)
|
13
13
|
|
14
|
-
stream.read.
|
14
|
+
expect(stream.read).to eq(data)
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should ignore any extension data, after the length field" do
|
18
18
|
socket = StringIO.new("%x;lol\r\n%s\r\n0\r\n\r\n" % [data.length, data])
|
19
19
|
stream = described_class.new(socket)
|
20
20
|
|
21
|
-
stream.read.
|
21
|
+
expect(stream.read).to eq(data)
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should read an amount of data from a socket, directly into a buffer" do
|
25
25
|
length = 3
|
26
|
-
buffer =
|
26
|
+
buffer = String.new(encoding: Encoding::UTF_8)
|
27
27
|
|
28
28
|
socket = StringIO.new("%x\r\n%s\r\n0\r\n\r\n" % [data.length, data])
|
29
29
|
stream = described_class.new(socket)
|
30
30
|
|
31
|
-
stream.read(length,buffer).
|
31
|
+
expect(stream.read(length,buffer)).to eq(data[0,length])
|
32
32
|
end
|
33
33
|
|
34
34
|
it "should buffer unread data from the previously read chunk" do
|
35
35
|
socket = StringIO.new("%x\r\n%s\r\n0\r\n\r\n" % [data.length, data])
|
36
36
|
stream = described_class.new(socket)
|
37
37
|
|
38
|
-
stream.read(4).
|
39
|
-
stream.read.
|
38
|
+
expect(stream.read(4)).to eq(data[0,4])
|
39
|
+
expect(stream.read).to eq(data[4..-1])
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should return nil after it reads the last chunk" do
|
43
43
|
socket = StringIO.new("0\r\n\r\n")
|
44
44
|
stream = described_class.new(socket)
|
45
45
|
|
46
|
-
stream.read.
|
46
|
+
expect(stream.read).to be_nil
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -52,7 +52,7 @@ describe Net::HTTP::Server::ChunkedStream do
|
|
52
52
|
socket = StringIO.new
|
53
53
|
stream = described_class.new(socket)
|
54
54
|
|
55
|
-
stream.write('foo').
|
55
|
+
expect(stream.write('foo')).to eq(3)
|
56
56
|
end
|
57
57
|
|
58
58
|
it "should write a length-line along with the data" do
|
@@ -61,7 +61,7 @@ describe Net::HTTP::Server::ChunkedStream do
|
|
61
61
|
|
62
62
|
stream.write('foo')
|
63
63
|
|
64
|
-
socket.string.
|
64
|
+
expect(socket.string).to eq("3\r\nfoo\r\n")
|
65
65
|
end
|
66
66
|
|
67
67
|
it "should not write empty Strings" do
|
@@ -70,7 +70,7 @@ describe Net::HTTP::Server::ChunkedStream do
|
|
70
70
|
|
71
71
|
stream.write('')
|
72
72
|
|
73
|
-
socket.string.
|
73
|
+
expect(socket.string).to be_empty
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
@@ -81,7 +81,7 @@ describe Net::HTTP::Server::ChunkedStream do
|
|
81
81
|
|
82
82
|
stream.close
|
83
83
|
|
84
|
-
socket.string.
|
84
|
+
expect(socket.string).to eq("0\r\n\r\n")
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
@@ -8,17 +8,17 @@ describe Net::HTTP::Server::Daemon do
|
|
8
8
|
subject { described_class.new { |request,response| } }
|
9
9
|
|
10
10
|
it "should have a default host" do
|
11
|
-
subject.host.
|
11
|
+
expect(subject.host).to eq(described_class::DEFAULT_HOST)
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should have a default port" do
|
15
|
-
subject.port.
|
15
|
+
expect(subject.port).to eq(described_class::DEFAULT_PORT)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should require a HTTP Request handler" do
|
19
|
-
|
19
|
+
expect {
|
20
20
|
described_class.new
|
21
|
-
}.
|
21
|
+
}.to raise_error(ArgumentError,"no HTTP Request Handler block given")
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -5,86 +5,86 @@ describe Net::HTTP::Server::Parser do
|
|
5
5
|
it "should not parse garbage" do
|
6
6
|
garbage = (1..255).map { |b| b.chr }.join * 100
|
7
7
|
|
8
|
-
|
8
|
+
expect {
|
9
9
|
subject.parse(garbage)
|
10
|
-
}.
|
10
|
+
}.to raise_error(Parslet::ParseFailed)
|
11
11
|
end
|
12
12
|
|
13
13
|
describe "request line" do
|
14
14
|
it "should parse non-standard request methods" do
|
15
15
|
request = subject.parse("FOO / HTTP/1.1\r\n\r\n")
|
16
16
|
|
17
|
-
request[:method].
|
17
|
+
expect(request[:method]).to eq('FOO')
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should allow '*' as the path" do
|
21
21
|
request = subject.parse("OPTIONS * HTTP/1.1\r\n\r\n")
|
22
22
|
|
23
|
-
request[:uri].
|
23
|
+
expect(request[:uri]).to eq('*')
|
24
24
|
end
|
25
25
|
|
26
26
|
it "should not confuse the '/*' path with '*'" do
|
27
27
|
request = subject.parse("OPTIONS /* HTTP/1.1\r\n\r\n")
|
28
28
|
|
29
|
-
request[:uri][:path].
|
29
|
+
expect(request[:uri][:path]).to eq('/*')
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should parse absolute paths" do
|
33
33
|
request = subject.parse("GET /absolute/path HTTP/1.1\r\n\r\n")
|
34
34
|
|
35
|
-
request[:uri][:path].
|
35
|
+
expect(request[:uri][:path]).to eq('/absolute/path')
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should parse the params in the path" do
|
39
39
|
request = subject.parse("GET /path;q=1;p=2 HTTP/1.1\r\n\r\n")
|
40
40
|
|
41
|
-
request[:uri][:path].
|
42
|
-
request[:uri][:params].
|
41
|
+
expect(request[:uri][:path]).to eq('/path')
|
42
|
+
expect(request[:uri][:params]).to eq('q=1;p=2')
|
43
43
|
end
|
44
44
|
|
45
45
|
it "should parse the query-string in the path" do
|
46
46
|
request = subject.parse("GET /path?q=1&p=2 HTTP/1.1\r\n\r\n")
|
47
47
|
|
48
|
-
request[:uri][:path].
|
49
|
-
request[:uri][:query].
|
48
|
+
expect(request[:uri][:path]).to eq('/path')
|
49
|
+
expect(request[:uri][:query]).to eq('q=1&p=2')
|
50
50
|
end
|
51
51
|
|
52
52
|
it "should parse absolute URIs paths" do
|
53
53
|
request = subject.parse("GET http://www.example.com:8080/path HTTP/1.1\r\n\r\n")
|
54
54
|
|
55
|
-
request[:uri][:scheme].
|
56
|
-
request[:uri][:host].
|
57
|
-
request[:uri][:port].
|
58
|
-
request[:uri][:path].
|
55
|
+
expect(request[:uri][:scheme]).to eq('http')
|
56
|
+
expect(request[:uri][:host]).to eq('www.example.com')
|
57
|
+
expect(request[:uri][:port]).to eq('8080')
|
58
|
+
expect(request[:uri][:path]).to eq('/path')
|
59
59
|
end
|
60
60
|
|
61
61
|
it "should parse non-http URIs" do
|
62
62
|
request = subject.parse("GET xmpp://alice:secret@example.com/path HTTP/1.1\r\n\r\n")
|
63
63
|
|
64
|
-
request[:uri][:scheme].
|
65
|
-
request[:uri][:user_info].
|
66
|
-
request[:uri][:host].
|
67
|
-
request[:uri][:path].
|
64
|
+
expect(request[:uri][:scheme]).to eq('xmpp')
|
65
|
+
expect(request[:uri][:user_info]).to eq('alice:secret')
|
66
|
+
expect(request[:uri][:host]).to eq('example.com')
|
67
|
+
expect(request[:uri][:path]).to eq('/path')
|
68
68
|
end
|
69
69
|
|
70
70
|
it "should parse the HTTP version" do
|
71
71
|
request = subject.parse("GET /path HTTP/1.1\r\n\r\n")
|
72
72
|
|
73
|
-
request[:version].
|
73
|
+
expect(request[:version]).to eq('1.1')
|
74
74
|
end
|
75
75
|
|
76
76
|
it "should allow future HTTP versions" do
|
77
77
|
request = subject.parse("GET /path HTTP/2.0\r\n\r\n")
|
78
78
|
|
79
|
-
request[:version].
|
79
|
+
expect(request[:version]).to eq('2.0')
|
80
80
|
end
|
81
81
|
|
82
82
|
it "should parse simple GET requests" do
|
83
83
|
request = subject.parse("GET / HTTP/1.1\r\n\r\n")
|
84
84
|
|
85
|
-
request[:method].
|
86
|
-
request[:uri][:path].
|
87
|
-
request[:version].
|
85
|
+
expect(request[:method]).to eq('GET')
|
86
|
+
expect(request[:uri][:path]).to eq('/')
|
87
|
+
expect(request[:version]).to eq('1.1')
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
@@ -10,20 +10,20 @@ describe Net::HTTP::Server::Requests do
|
|
10
10
|
it "should ignore requests that do not contain an HTTP version" do
|
11
11
|
stream = StringIO.new("GET /\r\n")
|
12
12
|
|
13
|
-
read_request(stream).
|
13
|
+
expect(read_request(stream)).to be_nil
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should ignore requests with malformed headers" do
|
17
17
|
stream = StringIO.new("GET / HTTP/1.1\r\nFoo: Bar\r\nBAZ\r\n\r\n")
|
18
18
|
|
19
|
-
read_request(stream).
|
19
|
+
expect(read_request(stream)).to be_nil
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should read requests with an HTTP Version and Headers" do
|
23
23
|
request = "GET / HTTP/1.1\r\nFoo: Bar\r\n\r\n"
|
24
24
|
stream = StringIO.new(request)
|
25
25
|
|
26
|
-
read_request(stream).
|
26
|
+
expect(read_request(stream)).to eq(request)
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should not read the body of the request" do
|
@@ -33,7 +33,7 @@ describe Net::HTTP::Server::Requests do
|
|
33
33
|
|
34
34
|
read_request(stream)
|
35
35
|
|
36
|
-
stream.read.
|
36
|
+
expect(stream.read).to eq(body)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -42,21 +42,21 @@ describe Net::HTTP::Server::Requests do
|
|
42
42
|
request = {:uri => {:scheme => 'https'}}
|
43
43
|
normalize_uri(request)
|
44
44
|
|
45
|
-
request[:uri][:port].
|
45
|
+
expect(request[:uri][:port]).to eq(443)
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should convert :port to an Integer" do
|
49
49
|
request = {:uri => {:scheme => 'http', :port => '80'}}
|
50
50
|
normalize_uri(request)
|
51
51
|
|
52
|
-
request[:uri][:port].
|
52
|
+
expect(request[:uri][:port]).to eq(80)
|
53
53
|
end
|
54
54
|
|
55
55
|
it "should replace a '*' URI with an empty Hash" do
|
56
56
|
request = {:uri => '*'}
|
57
57
|
normalize_uri(request)
|
58
58
|
|
59
|
-
request[:uri].
|
59
|
+
expect(request[:uri]).to eq({})
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -65,7 +65,7 @@ describe Net::HTTP::Server::Requests do
|
|
65
65
|
request = {:headers => []}
|
66
66
|
normalize_headers(request)
|
67
67
|
|
68
|
-
request[:headers].
|
68
|
+
expect(request[:headers]).to eq({})
|
69
69
|
end
|
70
70
|
|
71
71
|
it "should convert header names and values into a Hash" do
|
@@ -75,10 +75,10 @@ describe Net::HTTP::Server::Requests do
|
|
75
75
|
]}
|
76
76
|
normalize_headers(request)
|
77
77
|
|
78
|
-
request[:headers].
|
78
|
+
expect(request[:headers]).to eq({
|
79
79
|
'Content-Type' => 'text/html',
|
80
80
|
'Content-Length' => '5'
|
81
|
-
}
|
81
|
+
})
|
82
82
|
end
|
83
83
|
|
84
84
|
it "should group duplicate header names into the same Hash key" do
|
@@ -88,9 +88,9 @@ describe Net::HTTP::Server::Requests do
|
|
88
88
|
]}
|
89
89
|
normalize_headers(request)
|
90
90
|
|
91
|
-
request[:headers].
|
91
|
+
expect(request[:headers]).to eq({
|
92
92
|
'Content-Type' => ['text/html', 'UTF8']
|
93
|
-
}
|
93
|
+
})
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
@@ -17,23 +17,23 @@ describe Net::HTTP::Server::Responses do
|
|
17
17
|
it "should write the HTTP Version" do
|
18
18
|
parts = @stream.string.split(' ')
|
19
19
|
|
20
|
-
parts[0].
|
20
|
+
expect(parts[0]).to match(/HTTP\/1.1/)
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should write the Status Code" do
|
24
24
|
parts = @stream.string.split(' ')
|
25
25
|
|
26
|
-
parts[1].
|
26
|
+
expect(parts[1]).to eq(status.to_s)
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should write the Reason String" do
|
30
30
|
parts = @stream.string.split(' ')
|
31
31
|
|
32
|
-
parts[2].
|
32
|
+
expect(parts[2]).to eq(reason)
|
33
33
|
end
|
34
34
|
|
35
35
|
it "should end the line with a '\\r\\n'" do
|
36
|
-
@stream.string[-2..-1].
|
36
|
+
expect(@stream.string[-2..-1]).to eq("\r\n")
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -41,57 +41,57 @@ describe Net::HTTP::Server::Responses do
|
|
41
41
|
it "should separate header names and values with a ': '" do
|
42
42
|
write_headers(@stream, 'Foo' => 'Bar')
|
43
43
|
|
44
|
-
@stream.string.
|
44
|
+
expect(@stream.string).to include(': ')
|
45
45
|
end
|
46
46
|
|
47
47
|
it "should terminate each header with a '\\r\\n'" do
|
48
48
|
write_headers(@stream, 'Foo' => 'Bar', 'Baz' => 'Qix')
|
49
49
|
|
50
|
-
@stream.string.split("\r\n").
|
50
|
+
expect(@stream.string.split("\r\n")).to match_array([
|
51
51
|
'Foo: Bar',
|
52
52
|
'Baz: Qix'
|
53
|
-
]
|
53
|
+
])
|
54
54
|
end
|
55
55
|
|
56
56
|
it "should end the headers with a '\\r\\n'" do
|
57
57
|
write_headers(@stream, {})
|
58
58
|
|
59
|
-
@stream.string.
|
59
|
+
expect(@stream.string).to eq("\r\n")
|
60
60
|
end
|
61
61
|
|
62
62
|
it "should write String headers" do
|
63
63
|
write_headers(@stream, 'Content-Type' => 'text/html')
|
64
64
|
|
65
|
-
@stream.string.split("\r\n").
|
65
|
+
expect(@stream.string.split("\r\n")).to eq([
|
66
66
|
'Content-Type: text/html'
|
67
|
-
]
|
67
|
+
])
|
68
68
|
end
|
69
69
|
|
70
70
|
it "should write multiple headers for multi-line String values" do
|
71
71
|
write_headers(@stream, 'Content-Type' => "text/html\ncharset=UTF8")
|
72
72
|
|
73
|
-
@stream.string.split("\r\n").
|
73
|
+
expect(@stream.string.split("\r\n")).to eq([
|
74
74
|
'Content-Type: text/html',
|
75
75
|
'Content-Type: charset=UTF8'
|
76
|
-
]
|
76
|
+
])
|
77
77
|
end
|
78
78
|
|
79
79
|
it "should properly format Time values" do
|
80
80
|
time = Time.parse('2011-01-25 14:15:29 -0800')
|
81
81
|
write_headers(@stream, 'Date' => time)
|
82
82
|
|
83
|
-
@stream.string.split("\r\n").
|
83
|
+
expect(@stream.string.split("\r\n")).to eq([
|
84
84
|
'Date: Tue, 25 Jan 2011 22:15:29 GMT'
|
85
|
-
]
|
85
|
+
])
|
86
86
|
end
|
87
87
|
|
88
88
|
it "should write Array values as multiple headers" do
|
89
89
|
write_headers(@stream, 'Content-Type' => ['text/html', 'charset=UTF8'])
|
90
90
|
|
91
|
-
@stream.string.split("\r\n").
|
91
|
+
expect(@stream.string.split("\r\n")).to eq([
|
92
92
|
'Content-Type: text/html',
|
93
93
|
'Content-Type: charset=UTF8'
|
94
|
-
]
|
94
|
+
])
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
@@ -99,7 +99,7 @@ describe Net::HTTP::Server::Responses do
|
|
99
99
|
it "should write each check of the body" do
|
100
100
|
write_body(@stream,['one', 'two', 'three'])
|
101
101
|
|
102
|
-
@stream.string.
|
102
|
+
expect(@stream.string).to eq('onetwothree')
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
@@ -9,17 +9,17 @@ describe Net::HTTP::Server::Stream do
|
|
9
9
|
|
10
10
|
it "should read data from a socket" do
|
11
11
|
stream = described_class.new(StringIO.new(data))
|
12
|
-
stream.read.
|
12
|
+
expect(stream.read).to eq(data)
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should read an amount of data from a socket, directly into a buffer" do
|
16
16
|
length = 3
|
17
|
-
buffer =
|
17
|
+
buffer = String.new(encoding: Encoding::UTF_8)
|
18
18
|
|
19
19
|
stream = described_class.new(StringIO.new(data))
|
20
20
|
stream.read(length,buffer)
|
21
21
|
|
22
|
-
buffer.
|
22
|
+
expect(buffer).to eq(data[0,length])
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -30,7 +30,7 @@ describe Net::HTTP::Server::Stream do
|
|
30
30
|
stream = described_class.new(StringIO.new())
|
31
31
|
stream.each { |chunk| results << chunk }
|
32
32
|
|
33
|
-
results.
|
33
|
+
expect(results).to be_empty
|
34
34
|
end
|
35
35
|
|
36
36
|
it "should yield each chunk in the stream" do
|
@@ -41,7 +41,7 @@ describe Net::HTTP::Server::Stream do
|
|
41
41
|
stream = described_class.new(StringIO.new(data))
|
42
42
|
stream.each { |chunk| results << chunk }
|
43
43
|
|
44
|
-
results.
|
44
|
+
expect(results).to eq(chunks)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -51,7 +51,7 @@ describe Net::HTTP::Server::Stream do
|
|
51
51
|
data = chunks.join('')
|
52
52
|
|
53
53
|
stream = described_class.new(StringIO.new(data))
|
54
|
-
stream.body.
|
54
|
+
expect(stream.body).to eq(data)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -60,7 +60,7 @@ describe Net::HTTP::Server::Stream do
|
|
60
60
|
data = "foo\n\rbar"
|
61
61
|
|
62
62
|
stream = described_class.new(StringIO.new)
|
63
|
-
stream.write(data).
|
63
|
+
expect(stream.write(data)).to eq(data.length)
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|