net-http-server 0.1.0
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/.document +3 -0
- data/.gemtest +0 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +8 -0
- data/LICENSE.txt +20 -0
- data/README.md +48 -0
- data/Rakefile +36 -0
- data/gemspec.yml +16 -0
- data/lib/net/http/server.rb +4 -0
- data/lib/net/http/server/daemon.rb +123 -0
- data/lib/net/http/server/parser.rb +151 -0
- data/lib/net/http/server/requests.rb +129 -0
- data/lib/net/http/server/responses.rb +151 -0
- data/lib/net/http/server/server.rb +49 -0
- data/lib/net/http/server/version.rb +10 -0
- data/lib/rack/handler/http.rb +170 -0
- data/net-http-server.gemspec +10 -0
- data/spec/rack/handler/helpers/test_request.rb +69 -0
- data/spec/rack/handler/http_spec.rb +87 -0
- data/spec/rack/handler/images/image.jpg +0 -0
- data/spec/server/daemon_spec.rb +26 -0
- data/spec/server/parser_spec.rb +90 -0
- data/spec/server/requests_spec.rb +110 -0
- data/spec/server/responses_spec.rb +105 -0
- data/spec/server/server_spec.rb +5 -0
- data/spec/spec_helper.rb +2 -0
- metadata +155 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rack/handler/helpers/test_request'
|
3
|
+
|
4
|
+
require 'rack/handler/http'
|
5
|
+
require 'rack/lint'
|
6
|
+
require 'rack/builder'
|
7
|
+
require 'rack/static'
|
8
|
+
|
9
|
+
describe Rack::Handler::HTTP do
|
10
|
+
include TestRequest::Helpers
|
11
|
+
|
12
|
+
let(:host) { '0.0.0.0' }
|
13
|
+
let(:port) { 9204 }
|
14
|
+
|
15
|
+
before(:all) do
|
16
|
+
app = Rack::Builder.app do
|
17
|
+
use Rack::Lint
|
18
|
+
use Rack::Static, :urls => ["/spec/images"]
|
19
|
+
run TestRequest.new
|
20
|
+
end
|
21
|
+
|
22
|
+
@server = Rack::Handler::HTTP.new(app, :Host => host, :Port => port)
|
23
|
+
|
24
|
+
Thread.new { @server.run }
|
25
|
+
Thread.pass until @server.running?
|
26
|
+
end
|
27
|
+
|
28
|
+
after(:all) do
|
29
|
+
@server.stop
|
30
|
+
Thread.pass until @server.stopped?
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should respond to a simple get request" do
|
34
|
+
GET "/"
|
35
|
+
status.should == 200
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should have CGI headers on GET" do
|
39
|
+
GET("/")
|
40
|
+
response["REQUEST_METHOD"].should == "GET"
|
41
|
+
response["SCRIPT_NAME"].should == ''
|
42
|
+
response["PATH_INFO"].should == "/"
|
43
|
+
response["QUERY_STRING"].should == ""
|
44
|
+
response["test.postdata"].should == ""
|
45
|
+
|
46
|
+
GET("/test/foo?quux=1")
|
47
|
+
response["REQUEST_METHOD"].should == "GET"
|
48
|
+
response["SCRIPT_NAME"].should == ''
|
49
|
+
response["REQUEST_URI"].should == "/test/foo"
|
50
|
+
response["PATH_INFO"].should == "/test/foo"
|
51
|
+
response["QUERY_STRING"].should == "quux=1"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should have CGI headers on POST" do
|
55
|
+
POST("/", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
|
56
|
+
status.should == 200
|
57
|
+
response["REQUEST_METHOD"].should == "POST"
|
58
|
+
response["REQUEST_URI"].should == "/"
|
59
|
+
response["QUERY_STRING"].should == ""
|
60
|
+
response["HTTP_X_TEST_HEADER"].should == "42"
|
61
|
+
response["test.postdata"].should == "rack-form-data=23"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should support HTTP auth" do
|
65
|
+
GET("/test", {:user => "ruth", :passwd => "secret"})
|
66
|
+
response["HTTP_AUTHORIZATION"].should == "Basic cnV0aDpzZWNyZXQ="
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should set status" do
|
70
|
+
GET("/test?secret")
|
71
|
+
status.should == 403
|
72
|
+
response["rack.url_scheme"].should == "http"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should not set content-type to '' in requests" do
|
76
|
+
GET("/test", 'Content-Type' => '')
|
77
|
+
response['Content-Type'].should == nil
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should serve images" do
|
81
|
+
file_size = File.size(File.join(File.dirname(__FILE__), 'images', 'image.jpg'))
|
82
|
+
GET("/spec/images/image.jpg")
|
83
|
+
status.should == 200
|
84
|
+
response.content_length.should == file_size
|
85
|
+
response.body.size.should == file_size
|
86
|
+
end
|
87
|
+
end
|
Binary file
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'net/http/server/daemon'
|
3
|
+
|
4
|
+
describe Net::HTTP::Server::Daemon do
|
5
|
+
subject { Net::HTTP::Server::Daemon }
|
6
|
+
|
7
|
+
describe "new" do
|
8
|
+
it "should have a default host" do
|
9
|
+
daemon = subject.new { |request,socket| }
|
10
|
+
|
11
|
+
daemon.host.should_not be_nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have a default port" do
|
15
|
+
daemon = subject.new { |request,socket| }
|
16
|
+
|
17
|
+
daemon.port.should_not be_nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should require a HTTP Request handler" do
|
21
|
+
lambda {
|
22
|
+
subject.new
|
23
|
+
}.should raise_error
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'net/http/server/parser'
|
3
|
+
|
4
|
+
describe Net::HTTP::Server::Parser do
|
5
|
+
it "should not parse garbage" do
|
6
|
+
garbage = (1..255).map { |b| b.chr }.join * 100
|
7
|
+
|
8
|
+
lambda {
|
9
|
+
subject.parse(garbage)
|
10
|
+
}.should raise_error(Parslet::ParseFailed)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "request line" do
|
14
|
+
it "should parse non-standard request methods" do
|
15
|
+
request = subject.parse("FOO / HTTP/1.1\r\n\r\n")
|
16
|
+
|
17
|
+
request[:method].should == 'FOO'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should allow '*' as the path" do
|
21
|
+
request = subject.parse("OPTIONS * HTTP/1.1\r\n\r\n")
|
22
|
+
|
23
|
+
request[:uri].should == '*'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should not confuse the '/*' path with '*'" do
|
27
|
+
request = subject.parse("OPTIONS /* HTTP/1.1\r\n\r\n")
|
28
|
+
|
29
|
+
request[:uri][:path].should == '*'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should parse absolute paths" do
|
33
|
+
request = subject.parse("GET /absolute/path HTTP/1.1\r\n\r\n")
|
34
|
+
|
35
|
+
request[:uri][:path].should == 'absolute/path'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should parse the params in the path" do
|
39
|
+
request = subject.parse("GET /path;q=1;p=2 HTTP/1.1\r\n\r\n")
|
40
|
+
|
41
|
+
request[:uri][:path].should == 'path'
|
42
|
+
request[:uri][:params].should == 'q=1;p=2'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should parse the query-string in the path" do
|
46
|
+
request = subject.parse("GET /path?q=1&p=2 HTTP/1.1\r\n\r\n")
|
47
|
+
|
48
|
+
request[:uri][:path].should == 'path'
|
49
|
+
request[:uri][:query].should == 'q=1&p=2'
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should parse absolute URIs paths" do
|
53
|
+
request = subject.parse("GET http://www.example.com:8080/path HTTP/1.1\r\n\r\n")
|
54
|
+
|
55
|
+
request[:uri][:scheme].should == 'http'
|
56
|
+
request[:uri][:host].should == 'www.example.com'
|
57
|
+
request[:uri][:port].should == '8080'
|
58
|
+
request[:uri][:path].should == 'path'
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should parse non-http URIs" do
|
62
|
+
request = subject.parse("GET xmpp://alice:secret@example.com/path HTTP/1.1\r\n\r\n")
|
63
|
+
|
64
|
+
request[:uri][:scheme].should == 'xmpp'
|
65
|
+
request[:uri][:user_info].should == 'alice:secret'
|
66
|
+
request[:uri][:host].should == 'example.com'
|
67
|
+
request[:uri][:path].should == 'path'
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should parse the HTTP version" do
|
71
|
+
request = subject.parse("GET /path HTTP/1.1\r\n\r\n")
|
72
|
+
|
73
|
+
request[:version].should == '1.1'
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should allow future HTTP versions" do
|
77
|
+
request = subject.parse("GET /path HTTP/2.0\r\n\r\n")
|
78
|
+
|
79
|
+
request[:version].should == '2.0'
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should parse simple GET requests" do
|
83
|
+
request = subject.parse("GET / HTTP/1.1\r\n\r\n")
|
84
|
+
|
85
|
+
request[:method].should == 'GET'
|
86
|
+
request[:uri][:path].should be_nil
|
87
|
+
request[:version].should == '1.1'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'net/http/server/requests'
|
3
|
+
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
describe Net::HTTP::Server::Requests do
|
7
|
+
include Net::HTTP::Server::Requests
|
8
|
+
|
9
|
+
describe "read_request" do
|
10
|
+
it "should ignore requests that do not contain an HTTP version" do
|
11
|
+
stream = StringIO.new("GET /\r\n")
|
12
|
+
|
13
|
+
read_request(stream).should be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should ignore requests with malformed headers" do
|
17
|
+
stream = StringIO.new("GET / HTTP/1.1\r\nFoo: Bar\r\nBAZ\r\n\r\n")
|
18
|
+
|
19
|
+
read_request(stream).should be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should read requests with an HTTP Version and Headers" do
|
23
|
+
request = "GET / HTTP/1.1\r\nFoo: Bar\r\n\r\n"
|
24
|
+
stream = StringIO.new(request)
|
25
|
+
|
26
|
+
read_request(stream).should == request
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not read the body of the request" do
|
30
|
+
request = "GET / HTTP/1.1\r\nFoo: Bar\r\n\r\n"
|
31
|
+
body = "<html>\r\n\t<body>hello</body>\r\n</html>\r\n"
|
32
|
+
stream = StringIO.new(request + body)
|
33
|
+
|
34
|
+
read_request(stream)
|
35
|
+
|
36
|
+
stream.read.should == body
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "normalize_uri" do
|
41
|
+
it "should infer the :port, if :scheme is also set" do
|
42
|
+
request = {:uri => {:scheme => 'https'}}
|
43
|
+
normalize_uri(request)
|
44
|
+
|
45
|
+
request[:uri][:port].should == 443
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should convert :port to an Integer" do
|
49
|
+
request = {:uri => {:scheme => 'http', :port => '80'}}
|
50
|
+
normalize_uri(request)
|
51
|
+
|
52
|
+
request[:uri][:port].should == 80
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should default :path to '/'" do
|
56
|
+
request = {:uri => {:path => nil}}
|
57
|
+
normalize_uri(request)
|
58
|
+
|
59
|
+
request[:uri][:path].should == '/'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should ensure that the path begins with a '/'" do
|
63
|
+
request = {:uri => {:path => 'foo'}}
|
64
|
+
normalize_uri(request)
|
65
|
+
|
66
|
+
request[:uri][:path].should == '/foo'
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should replace a '*' URI with an empty Hash" do
|
70
|
+
request = {:uri => '*'}
|
71
|
+
normalize_uri(request)
|
72
|
+
|
73
|
+
request[:uri].should == {}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "normalize_headers" do
|
78
|
+
it "should convert empty headers to an empty Hash" do
|
79
|
+
request = {:headers => []}
|
80
|
+
normalize_headers(request)
|
81
|
+
|
82
|
+
request[:headers].should == {}
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should convert header names and values into a Hash" do
|
86
|
+
request = {:headers => [
|
87
|
+
{:name => 'Content-Type', :value => 'text/html'},
|
88
|
+
{:name => 'Content-Length', :value => '5'}
|
89
|
+
]}
|
90
|
+
normalize_headers(request)
|
91
|
+
|
92
|
+
request[:headers].should == {
|
93
|
+
'Content-Type' => 'text/html',
|
94
|
+
'Content-Length' => '5'
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should group duplicate header names into the same Hash key" do
|
99
|
+
request = {:headers => [
|
100
|
+
{:name => 'Content-Type', :value => 'text/html'},
|
101
|
+
{:name => 'Content-Type', :value => 'UTF8'},
|
102
|
+
]}
|
103
|
+
normalize_headers(request)
|
104
|
+
|
105
|
+
request[:headers].should == {
|
106
|
+
'Content-Type' => ['text/html', 'UTF8']
|
107
|
+
}
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'net/http/server/responses'
|
3
|
+
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
describe Net::HTTP::Server::Responses do
|
7
|
+
include Net::HTTP::Server::Responses
|
8
|
+
|
9
|
+
before(:each) { @stream = StringIO.new }
|
10
|
+
|
11
|
+
describe "write_status" do
|
12
|
+
let(:status) { 200 }
|
13
|
+
let(:reason) { Net::HTTP::Server::Responses::HTTP_STATUSES[status] }
|
14
|
+
|
15
|
+
before(:each) { write_status(@stream,status) }
|
16
|
+
|
17
|
+
it "should write the HTTP Version" do
|
18
|
+
parts = @stream.string.split(' ')
|
19
|
+
|
20
|
+
parts[0].should =~ /HTTP\/1.1/
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should write the Status Code" do
|
24
|
+
parts = @stream.string.split(' ')
|
25
|
+
|
26
|
+
parts[1].should == status.to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should write the Reason String" do
|
30
|
+
parts = @stream.string.split(' ')
|
31
|
+
|
32
|
+
parts[2].should == reason
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should end the line with a '\\r\\n'" do
|
36
|
+
@stream.string[-2..-1].should == "\r\n"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "write_headers" do
|
41
|
+
it "should separate header names and values with a ': '" do
|
42
|
+
write_headers(@stream, 'Foo' => 'Bar')
|
43
|
+
|
44
|
+
@stream.string.should include(': ')
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should terminate each header with a '\\r\\n'" do
|
48
|
+
write_headers(@stream, 'Foo' => 'Bar', 'Baz' => 'Qix')
|
49
|
+
|
50
|
+
@stream.string.split("\r\n").should =~ [
|
51
|
+
'Foo: Bar',
|
52
|
+
'Baz: Qix'
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should end the headers with a '\\r\\n'" do
|
57
|
+
write_headers(@stream, {})
|
58
|
+
|
59
|
+
@stream.string.should == "\r\n"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should write String headers" do
|
63
|
+
write_headers(@stream, 'Content-Type' => 'text/html')
|
64
|
+
|
65
|
+
@stream.string.split("\r\n").should == [
|
66
|
+
'Content-Type: text/html'
|
67
|
+
]
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should write multiple headers for multi-line String values" do
|
71
|
+
write_headers(@stream, 'Content-Type' => "text/html\ncharset=UTF8")
|
72
|
+
|
73
|
+
@stream.string.split("\r\n").should == [
|
74
|
+
'Content-Type: text/html',
|
75
|
+
'Content-Type: charset=UTF8'
|
76
|
+
]
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should properly format Time values" do
|
80
|
+
time = Time.parse('2011-01-25 14:15:29 -0800')
|
81
|
+
write_headers(@stream, 'Date' => time)
|
82
|
+
|
83
|
+
@stream.string.split("\r\n").should == [
|
84
|
+
'Date: Tue, 25 Jan 2011 22:15:29 GMT'
|
85
|
+
]
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should write Array values as multiple headers" do
|
89
|
+
write_headers(@stream, 'Content-Type' => ['text/html', 'charset=UTF8'])
|
90
|
+
|
91
|
+
@stream.string.split("\r\n").should == [
|
92
|
+
'Content-Type: text/html',
|
93
|
+
'Content-Type: charset=UTF8'
|
94
|
+
]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "write_body" do
|
99
|
+
it "should write each check of the body" do
|
100
|
+
write_body(@stream,['one', 'two', 'three'])
|
101
|
+
|
102
|
+
@stream.string.should == 'onetwothree'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: net-http-server
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Postmodern
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-01-26 00:00:00 -08:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: parslet
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 0
|
31
|
+
version: "1.0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: ore-tasks
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ~>
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
segments:
|
43
|
+
- 0
|
44
|
+
- 3
|
45
|
+
- 0
|
46
|
+
version: 0.3.0
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rspec
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
segments:
|
58
|
+
- 2
|
59
|
+
- 4
|
60
|
+
- 0
|
61
|
+
version: 2.4.0
|
62
|
+
type: :development
|
63
|
+
version_requirements: *id003
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: yard
|
66
|
+
prerelease: false
|
67
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ~>
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
- 6
|
75
|
+
- 0
|
76
|
+
version: 0.6.0
|
77
|
+
type: :development
|
78
|
+
version_requirements: *id004
|
79
|
+
description: A Rack compatible pure Ruby HTTP Server.
|
80
|
+
email: postmodern.mod3@gmail.com
|
81
|
+
executables: []
|
82
|
+
|
83
|
+
extensions: []
|
84
|
+
|
85
|
+
extra_rdoc_files:
|
86
|
+
- README.md
|
87
|
+
- ChangeLog.md
|
88
|
+
- LICENSE.txt
|
89
|
+
files:
|
90
|
+
- .document
|
91
|
+
- .gemtest
|
92
|
+
- .rspec
|
93
|
+
- .yardopts
|
94
|
+
- ChangeLog.md
|
95
|
+
- LICENSE.txt
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- gemspec.yml
|
99
|
+
- lib/net/http/server.rb
|
100
|
+
- lib/net/http/server/daemon.rb
|
101
|
+
- lib/net/http/server/parser.rb
|
102
|
+
- lib/net/http/server/requests.rb
|
103
|
+
- lib/net/http/server/responses.rb
|
104
|
+
- lib/net/http/server/server.rb
|
105
|
+
- lib/net/http/server/version.rb
|
106
|
+
- lib/rack/handler/http.rb
|
107
|
+
- net-http-server.gemspec
|
108
|
+
- spec/rack/handler/helpers/test_request.rb
|
109
|
+
- spec/rack/handler/http_spec.rb
|
110
|
+
- spec/rack/handler/images/image.jpg
|
111
|
+
- spec/server/daemon_spec.rb
|
112
|
+
- spec/server/parser_spec.rb
|
113
|
+
- spec/server/requests_spec.rb
|
114
|
+
- spec/server/responses_spec.rb
|
115
|
+
- spec/server/server_spec.rb
|
116
|
+
- spec/spec_helper.rb
|
117
|
+
has_rdoc: yard
|
118
|
+
homepage: http://github.com/postmodern/net-http-server
|
119
|
+
licenses:
|
120
|
+
- MIT
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options: []
|
123
|
+
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
segments:
|
132
|
+
- 0
|
133
|
+
version: "0"
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
none: false
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
segments:
|
140
|
+
- 0
|
141
|
+
version: "0"
|
142
|
+
requirements: []
|
143
|
+
|
144
|
+
rubyforge_project: net-http-server
|
145
|
+
rubygems_version: 1.3.7
|
146
|
+
signing_key:
|
147
|
+
specification_version: 3
|
148
|
+
summary: A pure Ruby HTTP Server
|
149
|
+
test_files:
|
150
|
+
- spec/server/daemon_spec.rb
|
151
|
+
- spec/server/requests_spec.rb
|
152
|
+
- spec/server/parser_spec.rb
|
153
|
+
- spec/server/responses_spec.rb
|
154
|
+
- spec/server/server_spec.rb
|
155
|
+
- spec/rack/handler/http_spec.rb
|