Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implement Hatetepe adapter

  • Loading branch information...
commit 31a27e92a131b4afd855d2bdbf737bdffc4f4598 1 parent c89fe90
@lgierth lgierth authored
View
3  lib/webmachine/adapters.rb
@@ -4,6 +4,7 @@ module Webmachine
# Contains classes and modules that connect Webmachine to Ruby
# application servers.
module Adapters
- autoload :Mongrel, 'webmachine/adapters/mongrel'
+ autoload :Mongrel, 'webmachine/adapters/mongrel'
+ autoload :Hatetepe, 'webmachine/adapters/hatetepe'
end
end
View
85 lib/webmachine/adapters/hatetepe.rb
@@ -0,0 +1,85 @@
+require 'hatetepe/server'
+require 'webmachine/version'
+require 'webmachine/headers'
+require 'webmachine/request'
+require 'webmachine/response'
+require 'webmachine/dispatcher'
+require 'webmachine/chunked_body'
+
+module Webmachine
+ module Adapters
+ class Hatetepe < Adapter
+ def options
+ {
+ :host => configuration.ip,
+ :port => configuration.port,
+ :app => [
+ ::Hatetepe::Server::Pipeline,
+ ::Hatetepe::Server::KeepAlive,
+ method(:call)
+ ]
+ }
+ end
+
+ def run
+ EM.synchrony do
+ ::Hatetepe::Server.start(options)
+ trap("INT") { EM.stop }
+ end
+ end
+
+ def call(request, &respond)
+ response = Webmachine::Response.new
+ dispatcher.dispatch(convert_request(request), response)
+
+ respond.call(convert_response(response))
+ end
+
+ def convert_request(request)
+ args = [
+ request.verb,
+ URI.parse(request.uri),
+ Webmachine::Headers[request.headers.map {|k, v| [k.downcase, v] }],
+ Body.new(request.body)
+ ]
+ Webmachine::Request.new(*args)
+ end
+
+ def convert_response(response)
+ response.headers["Server"] = [
+ Webmachine::SERVER_STRING,
+ "hatetepe/#{::Hatetepe::VERSION}"
+ ].join(" ")
+
+ args = [
+ response.code.to_i,
+ response.headers,
+ convert_body(response.body)
+ ]
+ ::Hatetepe::Response.new(*args)
+ end
+
+ def convert_body(body)
+ if body.respond_to?(:call)
+ [ body.call ]
+ elsif body.respond_to?(:to_s)
+ [ body.to_s ]
+ else
+ body
+ end
+ end
+
+ class Body < Struct.new(:body)
+ def each(&block)
+ body.rewind
+ body.each(&block)
+ end
+
+ def to_s
+ body.rewind
+ body.read.to_s
+ end
+ end
+ end
+ end
+end
View
60 spec/webmachine/adapters/hatetepe_spec.rb
@@ -0,0 +1,60 @@
+require "spec_helper"
+
+describe Webmachine::Adapters::Hatetepe do
+ let(:configuration) { Webmachine::Configuration.default }
+ let(:dispatcher) { Webmachine::Dispatcher.new }
+ let(:adapter) { described_class.new(configuration, dispatcher) }
+
+ it "inherits from Webmachine::Adapter" do
+ adapter.should be_a(Webmachine::Adapter)
+ end
+
+ describe "#run" do
+ it "starts a server" do
+ Hatetepe::Server.should_receive(:start).with(adapter.options) { EM.stop }
+ adapter.run
+ end
+ end
+
+ describe "#call" do
+ let :request do
+ Hatetepe::Request.new(:get, "/", {}, StringIO.new("hello, world!"))
+ end
+
+ it "builds a string-like and enumerable request body" do
+ dispatcher.should_receive(:dispatch) do |req, res|
+ req.body.to_s.should eq("hello, world!")
+ enum_to_s(req.body).should eq("hello, world!")
+ end
+ adapter.call(request) {}
+ end
+
+ shared_examples "enumerable response body" do
+ before do
+ dispatcher.stub(:dispatch) {|_, response| response.body = body }
+ end
+
+ it "builds an enumerable response body" do
+ adapter.call(request) do |response|
+ enum_to_s(response.body).should eq("bye, world!")
+ end
+ end
+ end
+
+ describe "with normal response" do
+ let(:body) { "bye, world!" }
+
+ it_behaves_like "enumerable response body"
+ end
+
+ describe "with streaming response" do
+ let(:body) { proc { "bye, world!" } }
+
+ it_behaves_like "enumerable response body"
+ end
+ end
+
+ def enum_to_s(enum)
+ Enumerator.new(enum).to_a.join
+ end
+end
View
1  webmachine.gemspec
@@ -20,6 +20,7 @@ Gem::Specification.new do |gem|
gem.add_development_dependency(%q<yard>, ["~> 0.7.3"])
gem.add_development_dependency(%q<rake>)
gem.add_development_dependency(%q<mongrel>, ['~>1.2.beta'])
+ gem.add_development_dependency(%q<hatetepe>, ['~> 0.5'])
gem.add_development_dependency(%q<rack>)
gem.add_development_dependency(%q<rack-test>)
Please sign in to comment.
Something went wrong with that request. Please try again.