webmachine 1.6.0 → 2.0.0.beta
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 +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
|