webmachine 1.6.0 → 2.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +2 -5
- data/documentation/adapters.md +2 -11
- data/examples/debugger.rb +5 -3
- data/examples/logging.rb +2 -2
- data/examples/webrick.rb +2 -2
- data/lib/webmachine/adapter.rb +0 -3
- data/lib/webmachine/adapters/lazy_request_body.rb +1 -1
- data/lib/webmachine/adapters/rack.rb +38 -34
- data/lib/webmachine/adapters/rack_mapped.rb +1 -2
- data/lib/webmachine/adapters/webrick.rb +11 -12
- data/lib/webmachine/adapters.rb +0 -2
- data/lib/webmachine/application.rb +2 -2
- data/lib/webmachine/chunked_body.rb +1 -1
- data/lib/webmachine/configuration.rb +1 -1
- data/lib/webmachine/constants.rb +12 -12
- data/lib/webmachine/cookie.rb +20 -18
- data/lib/webmachine/decision/conneg.rb +24 -24
- data/lib/webmachine/decision/falsey.rb +0 -1
- data/lib/webmachine/decision/flow.rb +19 -20
- data/lib/webmachine/decision/fsm.rb +4 -4
- data/lib/webmachine/decision/helpers.rb +21 -21
- data/lib/webmachine/dispatcher/route.rb +28 -28
- data/lib/webmachine/dispatcher.rb +3 -2
- data/lib/webmachine/errors.rb +7 -8
- data/lib/webmachine/etags.rb +2 -1
- data/lib/webmachine/header_negotiation.rb +5 -6
- data/lib/webmachine/headers.rb +5 -5
- data/lib/webmachine/media_type.rb +5 -5
- data/lib/webmachine/quoted_string.rb +3 -3
- data/lib/webmachine/request.rb +7 -10
- data/lib/webmachine/rescueable_exception.rb +3 -3
- data/lib/webmachine/resource/authentication.rb +3 -4
- data/lib/webmachine/resource/callbacks.rb +3 -3
- data/lib/webmachine/resource/encodings.rb +3 -9
- data/lib/webmachine/resource.rb +1 -1
- data/lib/webmachine/response.rb +7 -9
- data/lib/webmachine/spec/adapter_lint.rb +67 -69
- data/lib/webmachine/spec/test_resource.rb +22 -22
- data/lib/webmachine/streaming/encoder.rb +3 -2
- data/lib/webmachine/streaming/io_encoder.rb +4 -3
- data/lib/webmachine/trace/fsm.rb +25 -18
- data/lib/webmachine/trace/resource_proxy.rb +10 -9
- data/lib/webmachine/trace/static/http-headers-status-v3.png +0 -0
- data/lib/webmachine/trace/trace_resource.rb +22 -24
- data/lib/webmachine/trace.rb +7 -6
- data/lib/webmachine/translation.rb +3 -3
- data/lib/webmachine/version.rb +1 -1
- metadata +52 -86
- data/.gitignore +0 -31
- data/Gemfile +0 -46
- data/Guardfile +0 -11
- data/RELEASING.md +0 -21
- data/Rakefile +0 -44
- data/lib/webmachine/adapters/httpkit.rb +0 -74
- data/lib/webmachine/adapters/reel.rb +0 -113
- data/memory_test.rb +0 -37
- data/spec/spec_helper.rb +0 -56
- data/spec/webmachine/adapter_spec.rb +0 -39
- data/spec/webmachine/adapters/httpkit_spec.rb +0 -10
- data/spec/webmachine/adapters/rack_mapped_spec.rb +0 -71
- data/spec/webmachine/adapters/rack_spec.rb +0 -62
- data/spec/webmachine/adapters/reel_spec.rb +0 -76
- data/spec/webmachine/adapters/webrick_spec.rb +0 -12
- data/spec/webmachine/application_spec.rb +0 -74
- data/spec/webmachine/chunked_body_spec.rb +0 -30
- data/spec/webmachine/configuration_spec.rb +0 -27
- data/spec/webmachine/cookie_spec.rb +0 -99
- data/spec/webmachine/decision/conneg_spec.rb +0 -166
- data/spec/webmachine/decision/falsey_spec.rb +0 -8
- data/spec/webmachine/decision/flow_spec.rb +0 -1148
- data/spec/webmachine/decision/fsm_spec.rb +0 -163
- data/spec/webmachine/decision/helpers_spec.rb +0 -216
- data/spec/webmachine/dispatcher/rfc3986_percent_decode_spec.rb +0 -22
- data/spec/webmachine/dispatcher/route_spec.rb +0 -248
- data/spec/webmachine/dispatcher_spec.rb +0 -104
- data/spec/webmachine/errors_spec.rb +0 -13
- data/spec/webmachine/etags_spec.rb +0 -75
- data/spec/webmachine/events_spec.rb +0 -58
- data/spec/webmachine/headers_spec.rb +0 -99
- data/spec/webmachine/media_type_spec.rb +0 -85
- data/spec/webmachine/request_spec.rb +0 -273
- data/spec/webmachine/rescueable_exception_spec.rb +0 -15
- data/spec/webmachine/resource/authentication_spec.rb +0 -68
- data/spec/webmachine/response_spec.rb +0 -51
- data/spec/webmachine/trace/fsm_spec.rb +0 -37
- data/spec/webmachine/trace/resource_proxy_spec.rb +0 -34
- data/spec/webmachine/trace/trace_store_spec.rb +0 -29
- data/spec/webmachine/trace_spec.rb +0 -17
- data/webmachine.gemspec +0 -25
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'webmachine/adapter'
|
2
|
-
require 'webmachine/constants'
|
3
|
-
require 'webmachine/version'
|
4
|
-
require 'httpkit'
|
5
|
-
require 'webmachine/version'
|
6
|
-
require 'webmachine/response'
|
7
|
-
require 'webmachine/request'
|
8
|
-
require 'webmachine/headers'
|
9
|
-
|
10
|
-
module Webmachine
|
11
|
-
module Adapters
|
12
|
-
class HTTPkit < Adapter
|
13
|
-
VERSION_STRING = "#{Webmachine::SERVER_STRING} HTTPkit/#{::HTTPkit::VERSION}".freeze
|
14
|
-
|
15
|
-
def options
|
16
|
-
@options ||= {
|
17
|
-
:address => application.configuration.ip,
|
18
|
-
:port => application.configuration.port,
|
19
|
-
:handlers => [
|
20
|
-
::HTTPkit::Server::TimeoutsHandler.new,
|
21
|
-
::HTTPkit::Server::KeepAliveHandler.new,
|
22
|
-
self
|
23
|
-
]
|
24
|
-
}
|
25
|
-
end
|
26
|
-
|
27
|
-
def run
|
28
|
-
::HTTPkit.start do
|
29
|
-
::HTTPkit::Server.start(options)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# Called by HTTPkit::Server for every request
|
34
|
-
def serve(request, served)
|
35
|
-
response = Webmachine::Response.new
|
36
|
-
application.dispatcher.dispatch(convert_request(request), response)
|
37
|
-
|
38
|
-
served.fulfill(convert_response(response))
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
# Converts HTTPkit::Request to Webmachine::Request
|
44
|
-
def convert_request(request)
|
45
|
-
Webmachine::Request.new(
|
46
|
-
request.http_method.to_s.upcase,
|
47
|
-
request.uri,
|
48
|
-
Webmachine::Headers[request.headers.dup],
|
49
|
-
request.body)
|
50
|
-
end
|
51
|
-
|
52
|
-
# Converts Webmachine::Response to HTTPkit::Response
|
53
|
-
def convert_response(response)
|
54
|
-
response.headers[SERVER] = VERSION_STRING
|
55
|
-
|
56
|
-
|
57
|
-
::HTTPkit::Response.new(
|
58
|
-
response.code.to_i,
|
59
|
-
response.headers,
|
60
|
-
convert_body(response.body))
|
61
|
-
end
|
62
|
-
|
63
|
-
# HTTPkit::Body accepts strings and enumerables, i.e. Webmachine's
|
64
|
-
# Callable, Enumerable, IO, and Fiber encoders are supported.
|
65
|
-
def convert_body(body)
|
66
|
-
if body.respond_to?(:call)
|
67
|
-
[body.call]
|
68
|
-
else
|
69
|
-
body || ''
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,113 +0,0 @@
|
|
1
|
-
require 'webmachine/adapter'
|
2
|
-
require 'webmachine/constants'
|
3
|
-
require 'set'
|
4
|
-
require 'celluloid/current'
|
5
|
-
require 'reel'
|
6
|
-
require 'webmachine/headers'
|
7
|
-
require 'webmachine/request'
|
8
|
-
require 'webmachine/response'
|
9
|
-
|
10
|
-
module Webmachine
|
11
|
-
module Adapters
|
12
|
-
class Reel < Adapter
|
13
|
-
# Used to override default Reel server options (useful in testing)
|
14
|
-
DEFAULT_OPTIONS = {}
|
15
|
-
|
16
|
-
def run
|
17
|
-
@options = DEFAULT_OPTIONS.merge({
|
18
|
-
:port => application.configuration.port,
|
19
|
-
:host => application.configuration.ip
|
20
|
-
}).merge(application.configuration.adapter_options)
|
21
|
-
|
22
|
-
if extra_verbs = application.configuration.adapter_options[:extra_verbs]
|
23
|
-
@extra_verbs = Set.new(extra_verbs.map(&:to_s).map(&:upcase))
|
24
|
-
else
|
25
|
-
@extra_verbs = Set.new
|
26
|
-
end
|
27
|
-
|
28
|
-
if @options[:ssl]
|
29
|
-
unless @options[:ssl][:cert] && @options[:ssl][:key]
|
30
|
-
raise ArgumentError, 'Certificate or Private key missing for HTTPS Server'
|
31
|
-
end
|
32
|
-
@server = ::Reel::Server::HTTPS.supervise(@options[:host], @options[:port], @options[:ssl], &method(:process))
|
33
|
-
else
|
34
|
-
@server = ::Reel::Server::HTTP.supervise(@options[:host], @options[:port], &method(:process))
|
35
|
-
end
|
36
|
-
|
37
|
-
Celluloid::Actor.join(@server)
|
38
|
-
end
|
39
|
-
|
40
|
-
def process(connection)
|
41
|
-
connection.each_request do |request|
|
42
|
-
# Users of the adapter can configure a custom WebSocket handler
|
43
|
-
if request.websocket?
|
44
|
-
if handler = @options[:websocket_handler]
|
45
|
-
handler.call(request.websocket)
|
46
|
-
else
|
47
|
-
# Pretend we don't know anything about the WebSocket protocol
|
48
|
-
# FIXME: This isn't strictly what RFC 6455 would have us do
|
49
|
-
request.respond :bad_request, "WebSockets not supported"
|
50
|
-
end
|
51
|
-
|
52
|
-
next
|
53
|
-
end
|
54
|
-
|
55
|
-
# Optional support for e.g. WebDAV verbs not included in Webmachine's
|
56
|
-
# state machine. Do the "Railsy" thing and handle them like POSTs
|
57
|
-
# with a magical parameter
|
58
|
-
if @extra_verbs.include?(request.method)
|
59
|
-
method = POST_METHOD
|
60
|
-
param = "_method=#{request.method}"
|
61
|
-
uri = request_uri(request.url, request.headers, param)
|
62
|
-
else
|
63
|
-
method = request.method
|
64
|
-
uri = request_uri(request.url, request.headers)
|
65
|
-
end
|
66
|
-
|
67
|
-
wm_headers = Webmachine::Headers[request.headers.dup]
|
68
|
-
wm_request = Webmachine::Request.new(method, uri, wm_headers, request.body)
|
69
|
-
|
70
|
-
wm_response = Webmachine::Response.new
|
71
|
-
application.dispatcher.dispatch(wm_request, wm_response)
|
72
|
-
|
73
|
-
fixup_headers(wm_response)
|
74
|
-
fixup_callable_encoder(wm_response)
|
75
|
-
|
76
|
-
request.respond ::Reel::Response.new(wm_response.code,
|
77
|
-
wm_response.headers,
|
78
|
-
wm_response.body)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def request_uri(path, headers, extra_query_params = nil)
|
83
|
-
path_parts = path.split('?')
|
84
|
-
uri_hash = {path: path_parts.first}
|
85
|
-
uri_hash[:query] = path_parts.last if path_parts.length == 2
|
86
|
-
|
87
|
-
if extra_query_params
|
88
|
-
if uri_hash[:query]
|
89
|
-
uri_hash[:query] << "&#{extra_query_params}"
|
90
|
-
else
|
91
|
-
uri_hash[:query] = extra_query_params
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
URI::HTTP.build(uri_hash)
|
96
|
-
end
|
97
|
-
|
98
|
-
def fixup_headers(response)
|
99
|
-
response.headers.each do |key, value|
|
100
|
-
if value.is_a?(Array)
|
101
|
-
response.headers[key] = value.join(", ")
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def fixup_callable_encoder(response)
|
107
|
-
if response.body.is_a?(Streaming::CallableEncoder)
|
108
|
-
response.body = [response.body.call]
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
data/memory_test.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
$:.push File.expand_path("../lib", __FILE__)
|
2
|
-
require 'webmachine'
|
3
|
-
|
4
|
-
class Constantized < Webmachine::Resource
|
5
|
-
HELLO_WORLD = "Hello World".freeze
|
6
|
-
ALLOWED_METHODS = ['GET'.freeze].freeze
|
7
|
-
CONTENT_TYPES_PROVIDED = [['text/html'.freeze, :to_html].freeze].freeze
|
8
|
-
|
9
|
-
def allowed_methods
|
10
|
-
ALLOWED_METHODS
|
11
|
-
end
|
12
|
-
|
13
|
-
def content_types_provided
|
14
|
-
CONTENT_TYPES_PROVIDED
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_html
|
18
|
-
HELLO_WORLD
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
Webmachine.application.routes do
|
23
|
-
add ['constantized'], Constantized
|
24
|
-
end
|
25
|
-
|
26
|
-
require 'webmachine/test'
|
27
|
-
session = Webmachine::Test::Session.new(Webmachine.application)
|
28
|
-
CONSTANTIZED = '/constantized'.freeze
|
29
|
-
require 'memory_profiler'
|
30
|
-
report = MemoryProfiler.report do
|
31
|
-
100.times do
|
32
|
-
session.get(CONSTANTIZED)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
report.pretty_print
|
37
|
-
|
data/spec/spec_helper.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
require "bundler/setup"
|
2
|
-
Bundler.require :default, :test, :webservers
|
3
|
-
require 'logger'
|
4
|
-
|
5
|
-
class NullLogger < Logger
|
6
|
-
def add(severity, message=nil, progname=nil, &block)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
RSpec.configure do |config|
|
11
|
-
config.mock_with :rspec
|
12
|
-
config.filter_run :focus => true
|
13
|
-
config.run_all_when_everything_filtered = true
|
14
|
-
config.formatter = :documentation if ENV['CI']
|
15
|
-
if defined?(::Java)
|
16
|
-
config.seed = Time.now.utc
|
17
|
-
else
|
18
|
-
config.order = :random
|
19
|
-
end
|
20
|
-
|
21
|
-
config.before :each do
|
22
|
-
Webmachine::RescuableException.remove(RSpec::Mocks::MockExpectationError)
|
23
|
-
end
|
24
|
-
|
25
|
-
config.after :each do
|
26
|
-
Webmachine::RescuableException.default!
|
27
|
-
end
|
28
|
-
|
29
|
-
config.before(:suite) do
|
30
|
-
options = {
|
31
|
-
:Logger => NullLogger.new(STDERR),
|
32
|
-
:AccessLog => []
|
33
|
-
}
|
34
|
-
Webmachine::Adapters::WEBrick::DEFAULT_OPTIONS.merge! options
|
35
|
-
Webmachine::Adapters::Rack::DEFAULT_OPTIONS.merge! options if defined?(Webmachine::Adapters::Rack)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# For use in specs that need a fully initialized resource
|
40
|
-
shared_context "default resource" do
|
41
|
-
let(:method) { 'GET' }
|
42
|
-
let(:uri) { URI.parse("http://localhost/") }
|
43
|
-
let(:headers) { Webmachine::Headers.new }
|
44
|
-
let(:body) { "" }
|
45
|
-
let(:request) { Webmachine::Request.new(method, uri, headers, body) }
|
46
|
-
let(:response) { Webmachine::Response.new }
|
47
|
-
|
48
|
-
let(:resource_class) do
|
49
|
-
Class.new(Webmachine::Resource) do
|
50
|
-
def to_html
|
51
|
-
"<html><body>Hello, world!</body></html>"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
let(:resource) { resource_class.new(request, response) }
|
56
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Webmachine::Adapter do
|
4
|
-
let(:application) { Webmachine::Application.new }
|
5
|
-
let(:adapter) do
|
6
|
-
server = TCPServer.new('0.0.0.0', 0)
|
7
|
-
application.configuration.port = server.addr[1]
|
8
|
-
server.close
|
9
|
-
|
10
|
-
described_class.new(application)
|
11
|
-
end
|
12
|
-
|
13
|
-
describe "#initialize" do
|
14
|
-
it "stores the provided application" do
|
15
|
-
expect(adapter.application).to eq(application)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe ".run" do
|
20
|
-
it "creates a new adapter and runs it" do
|
21
|
-
adapter = double(described_class)
|
22
|
-
|
23
|
-
expect(described_class).to receive(:new).
|
24
|
-
with(application).
|
25
|
-
and_return(adapter)
|
26
|
-
|
27
|
-
expect(adapter).to receive(:run)
|
28
|
-
|
29
|
-
described_class.run(application)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe "#run" do
|
34
|
-
it "raises a NotImplementedError" do
|
35
|
-
expect { adapter.run }.to raise_exception(NotImplementedError)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
require 'webmachine/adapter'
|
2
|
-
require 'webmachine/adapters/rack_mapped'
|
3
|
-
require 'spec_helper'
|
4
|
-
require 'webmachine/spec/adapter_lint'
|
5
|
-
require 'rack/test'
|
6
|
-
|
7
|
-
describe Webmachine::Adapters::RackMapped do
|
8
|
-
it_should_behave_like :adapter_lint do
|
9
|
-
it "should set Server header" do
|
10
|
-
response = client.request(Net::HTTP::Get.new("/test"))
|
11
|
-
expect(response["Server"]).to match(/Webmachine/)
|
12
|
-
expect(response["Server"]).to match(/Rack/)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe Webmachine::Adapters::RackMapped do
|
18
|
-
class CreateResource < Webmachine::Resource
|
19
|
-
def allowed_methods
|
20
|
-
["POST"]
|
21
|
-
end
|
22
|
-
|
23
|
-
def content_types_accepted
|
24
|
-
[["application/json", :from_json]]
|
25
|
-
end
|
26
|
-
|
27
|
-
def content_types_provided
|
28
|
-
[["application/json", :to_json]]
|
29
|
-
end
|
30
|
-
|
31
|
-
def post_is_create?
|
32
|
-
true
|
33
|
-
end
|
34
|
-
|
35
|
-
def create_path
|
36
|
-
"created_path_here/123"
|
37
|
-
end
|
38
|
-
|
39
|
-
def from_json
|
40
|
-
response.body = %{ {"foo": "bar"} }
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
let(:app) do
|
45
|
-
Rack::Builder.new do
|
46
|
-
map '/some/route' do
|
47
|
-
run(Webmachine::Application.new do |app|
|
48
|
-
app.add_route(["test"], Test::Resource)
|
49
|
-
app.add_route(["create_test"], CreateResource)
|
50
|
-
app.configure do | config |
|
51
|
-
config.adapter = :RackMapped
|
52
|
-
end
|
53
|
-
end.adapter)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
context "using Rack::Test" do
|
59
|
-
include Rack::Test::Methods
|
60
|
-
|
61
|
-
it "provides the full request URI" do
|
62
|
-
rack_response = get "some/route/test", nil, {"HTTP_ACCEPT" => "test/response.request_uri"}
|
63
|
-
expect(rack_response.body).to eq "http://example.org/some/route/test"
|
64
|
-
end
|
65
|
-
|
66
|
-
it "provides LOCATION header using custom base_uri when creating from POST request" do
|
67
|
-
rack_response = post "/some/route/create_test", %{{"foo": "bar"}}, {"HTTP_ACCEPT" => "application/json", "CONTENT_TYPE" => "application/json"}
|
68
|
-
expect(rack_response.headers["Location"]).to eq("http://example.org/some/route/created_path_here/123")
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
require 'webmachine/adapter'
|
2
|
-
require 'webmachine/adapters/rack'
|
3
|
-
require 'spec_helper'
|
4
|
-
require 'webmachine/spec/adapter_lint'
|
5
|
-
require 'rack/test'
|
6
|
-
|
7
|
-
describe Webmachine::Adapters::Rack do
|
8
|
-
it_should_behave_like :adapter_lint do
|
9
|
-
it "should set Server header" do
|
10
|
-
response = client.request(Net::HTTP::Get.new("/test"))
|
11
|
-
expect(response["Server"]).to match(/Webmachine/)
|
12
|
-
expect(response["Server"]).to match(/Rack/)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe Webmachine::Adapters::Rack::RackResponse do
|
18
|
-
context "on Rack < 1.5 release" do
|
19
|
-
before { allow(Rack).to receive_messages(:release => "1.4") }
|
20
|
-
|
21
|
-
it "should add Content-Type header on not acceptable response" do
|
22
|
-
rack_response = described_class.new(double(:body), 406, {})
|
23
|
-
rack_status, rack_headers, rack_body = rack_response.finish
|
24
|
-
expect(rack_headers).to have_key("Content-Type")
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context "on Rack >= 1.5 release" do
|
29
|
-
before { allow(Rack).to receive_messages(:release => "1.5") }
|
30
|
-
|
31
|
-
it "should not add Content-Type header on not acceptable response" do
|
32
|
-
rack_response = described_class.new(double(:body), 406, {})
|
33
|
-
rack_status, rack_headers, rack_body = rack_response.finish
|
34
|
-
expect(rack_headers).not_to have_key("Content-Type")
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe Webmachine::Adapters::Rack do
|
40
|
-
let(:app) do
|
41
|
-
Webmachine::Application.new do |app|
|
42
|
-
app.add_route(["test"], Test::Resource)
|
43
|
-
app.configure do | config |
|
44
|
-
config.adapter = :Rack
|
45
|
-
end
|
46
|
-
end.adapter
|
47
|
-
end
|
48
|
-
|
49
|
-
context "using Rack::Test" do
|
50
|
-
include Rack::Test::Methods
|
51
|
-
|
52
|
-
it "provides the full request URI" do
|
53
|
-
rack_response = get "test", nil, {"HTTP_ACCEPT" => "test/response.request_uri"}
|
54
|
-
expect(rack_response.body).to eq "http://example.org/test"
|
55
|
-
end
|
56
|
-
|
57
|
-
it "provides the rack env on the request" do
|
58
|
-
rack_response = get "test", nil, {"HTTP_ACCEPT" => "test/response.rack_env"}
|
59
|
-
expect(JSON.parse(rack_response.body).keys).to include "rack.input"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'webmachine/spec/adapter_lint'
|
3
|
-
describe Webmachine::Adapters::Reel do
|
4
|
-
context 'lint' do
|
5
|
-
it_should_behave_like :adapter_lint
|
6
|
-
end
|
7
|
-
|
8
|
-
context 'websockets' do
|
9
|
-
let(:application) { Webmachine::Application.new }
|
10
|
-
let(:adapter) do
|
11
|
-
server = TCPServer.new('0.0.0.0', 0)
|
12
|
-
application.configuration.port = server.addr[1]
|
13
|
-
server.close
|
14
|
-
described_class.new(application)
|
15
|
-
end
|
16
|
-
|
17
|
-
let(:example_host) { "www.example.com" }
|
18
|
-
let(:example_path) { "/example"}
|
19
|
-
let(:example_url) { "ws://#{example_host}#{example_path}" }
|
20
|
-
let :handshake_headers do
|
21
|
-
{
|
22
|
-
"Host" => example_host,
|
23
|
-
"Upgrade" => "websocket",
|
24
|
-
"Connection" => "Upgrade",
|
25
|
-
"Sec-WebSocket-Key" => "dGhlIHNhbXBsZSBub25jZQ==",
|
26
|
-
"Origin" => "http://example.com",
|
27
|
-
"Sec-WebSocket-Protocol" => "chat, superchat",
|
28
|
-
"Sec-WebSocket-Version" => "13"
|
29
|
-
}
|
30
|
-
end
|
31
|
-
let(:client_message) { "Hi server!" }
|
32
|
-
let(:server_message) { "Hi client!" }
|
33
|
-
|
34
|
-
it 'supports websockets' do
|
35
|
-
application.configuration.adapter_options[:websocket_handler] = proc do |socket|
|
36
|
-
expect(socket.read).to eq client_message
|
37
|
-
socket << server_message
|
38
|
-
end
|
39
|
-
|
40
|
-
reel_server(adapter) do |client|
|
41
|
-
client << WebSocket::ClientHandshake.new(:get, example_url, handshake_headers).to_data
|
42
|
-
|
43
|
-
# Discard handshake response
|
44
|
-
# FIXME: hax
|
45
|
-
client.readpartial(4096)
|
46
|
-
|
47
|
-
client << WebSocket::Message.new(client_message).to_data
|
48
|
-
parser = WebSocket::Parser.new
|
49
|
-
parser.append client.readpartial(4096) until message = parser.next_message
|
50
|
-
|
51
|
-
expect(message).to eq server_message
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def reel_server(adptr = adapter)
|
57
|
-
thread = Thread.new { adptr.run }
|
58
|
-
begin
|
59
|
-
Timeout.timeout(5) do
|
60
|
-
begin
|
61
|
-
sock = TCPSocket.new(adptr.application.configuration.ip, adptr.application.configuration.port)
|
62
|
-
begin
|
63
|
-
yield(sock)
|
64
|
-
ensure
|
65
|
-
sock.close
|
66
|
-
end
|
67
|
-
rescue Errno::ECONNREFUSED
|
68
|
-
Thread.pass
|
69
|
-
retry
|
70
|
-
end
|
71
|
-
end
|
72
|
-
ensure
|
73
|
-
thread.kill if thread
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "webmachine/spec/adapter_lint"
|
3
|
-
|
4
|
-
describe Webmachine::Adapters::WEBrick do
|
5
|
-
it_should_behave_like :adapter_lint do
|
6
|
-
it "should set Server header" do
|
7
|
-
response = client.request(Net::HTTP::Get.new("/test"))
|
8
|
-
expect(response["Server"]).to match(/Webmachine/)
|
9
|
-
expect(response["Server"]).to match(/WEBrick/)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Webmachine::Application do
|
4
|
-
let(:application) { described_class.new }
|
5
|
-
let(:test_resource) { Class.new(Webmachine::Resource) }
|
6
|
-
|
7
|
-
it "accepts a Configuration when initialized" do
|
8
|
-
config = Webmachine::Configuration.new('1.1.1.1', 9999, :Reel, {})
|
9
|
-
expect(described_class.new(config).configuration).to be(config)
|
10
|
-
end
|
11
|
-
|
12
|
-
it "is yielded into a block provided during initialization" do
|
13
|
-
yielded_app = nil
|
14
|
-
returned_app = described_class.new do |app|
|
15
|
-
expect(app).to be_kind_of(Webmachine::Application)
|
16
|
-
yielded_app = app
|
17
|
-
end
|
18
|
-
expect(returned_app).to be(yielded_app)
|
19
|
-
end
|
20
|
-
|
21
|
-
it "is initialized with the default Configration if none is given" do
|
22
|
-
expect(application.configuration).to eq(Webmachine::Configuration.default)
|
23
|
-
end
|
24
|
-
|
25
|
-
it "returns the receiver from the configure call so you can chain it" do
|
26
|
-
expect(application.configure { |c| }).to equal(application)
|
27
|
-
end
|
28
|
-
|
29
|
-
it "is configurable" do
|
30
|
-
application.configure do |config|
|
31
|
-
expect(config).to be_kind_of(Webmachine::Configuration)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
it "is initialized with an empty Dispatcher" do
|
36
|
-
expect(application.dispatcher.routes).to be_empty
|
37
|
-
end
|
38
|
-
|
39
|
-
it "can have routes added" do
|
40
|
-
route = nil
|
41
|
-
resource = test_resource # overcome instance_eval :/
|
42
|
-
|
43
|
-
expect(application.routes).to be_empty
|
44
|
-
|
45
|
-
application.routes do
|
46
|
-
route = add [:*], resource
|
47
|
-
end
|
48
|
-
|
49
|
-
expect(route).to be_kind_of(Webmachine::Dispatcher::Route)
|
50
|
-
expect(application.routes).to eq([route])
|
51
|
-
end
|
52
|
-
|
53
|
-
describe "#adapter" do
|
54
|
-
let(:adapter_class) { application.adapter_class }
|
55
|
-
|
56
|
-
it "returns an instance of it's adapter class" do
|
57
|
-
expect(application.adapter).to be_an_instance_of(adapter_class)
|
58
|
-
end
|
59
|
-
|
60
|
-
it "is memoized" do
|
61
|
-
expect(application.adapter).to eql application.adapter
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
it "can be run" do
|
66
|
-
expect(application.adapter).to receive(:run)
|
67
|
-
application.run
|
68
|
-
end
|
69
|
-
|
70
|
-
it "can be queried about its configured adapter" do
|
71
|
-
expected = Webmachine::Adapters.const_get(application.configuration.adapter)
|
72
|
-
expect(application.adapter_class).to equal(expected)
|
73
|
-
end
|
74
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'webmachine/chunked_body'
|
3
|
-
|
4
|
-
describe Webmachine::ChunkedBody do
|
5
|
-
it "builds a proper body" do
|
6
|
-
body = ''
|
7
|
-
Webmachine::ChunkedBody.new(['foo', 'bar', '', 'j', 'webmachine']).each do |chunk|
|
8
|
-
body << chunk
|
9
|
-
end
|
10
|
-
expect(body).to eq("3\r\nfoo\r\n3\r\nbar\r\n1\r\nj\r\na\r\nwebmachine\r\n0\r\n\r\n")
|
11
|
-
end
|
12
|
-
|
13
|
-
context "with an empty body" do
|
14
|
-
it "builds a proper body" do
|
15
|
-
body = ''
|
16
|
-
Webmachine::ChunkedBody.new([]).each do |chunk|
|
17
|
-
body << chunk
|
18
|
-
end
|
19
|
-
expect(body).to eq("0\r\n\r\n")
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "#each" do
|
24
|
-
context "without a block given" do
|
25
|
-
it "returns an Enumerator" do
|
26
|
-
expect(Webmachine::ChunkedBody.new([]).each).to respond_to(:next)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Webmachine::Configuration do
|
4
|
-
before { Webmachine.configuration = nil }
|
5
|
-
|
6
|
-
%w{ip port adapter adapter_options}.each do |field|
|
7
|
-
it { is_expected.to respond_to(field) }
|
8
|
-
it { is_expected.to respond_to("#{field}=") }
|
9
|
-
end
|
10
|
-
|
11
|
-
it "should yield configuration to the block" do
|
12
|
-
Webmachine.configure do |config|
|
13
|
-
expect(config).to be_kind_of(described_class)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should set the global configuration from the yielded instance" do
|
18
|
-
Webmachine.configure do |config|
|
19
|
-
@config = config
|
20
|
-
end
|
21
|
-
expect(@config).to eq Webmachine.configuration
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should return the module from the configure call so you can chain it" do
|
25
|
-
expect(Webmachine.configure {|c|}).to eq Webmachine
|
26
|
-
end
|
27
|
-
end
|