Created
June 26, 2010 22:01
-
-
Save jballanc/454372 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/ext/CTParser/CTParser.m b/ext/CTParser/CTParser.m | |
index ae31c1d..af217eb 100644 | |
--- a/ext/CTParser/CTParser.m | |
+++ b/ext/CTParser/CTParser.m | |
@@ -124,13 +124,9 @@ header_done(void *env, const char *at, size_t length) | |
} | |
// If we've been given any part of the body, put it here | |
- NSMutableData *body = [environment objectForKey:@"rack.input"]; | |
- if (body != nil) { | |
- [body appendData:[NSData dataWithBytes:at length:length]]; | |
- } | |
- else { | |
- NSLog(@"Hmm...you seem to have body data but no where to put it. That's probably an error."); | |
- } | |
+ NSMutableData *body = [[NSMutableData alloc] init]; | |
+ [body appendData:[NSData dataWithBytes:at length:length]]; | |
+ [environment setObject:body forKey:@"rack.input"]; | |
} | |
@implementation CTParser | |
diff --git a/lib/control_tower/rack_socket.rb b/lib/control_tower/rack_socket.rb | |
index 58c4810..aec7887 100644 | |
--- a/lib/control_tower/rack_socket.rb | |
+++ b/lib/control_tower/rack_socket.rb | |
@@ -10,7 +10,7 @@ module ControlTower | |
VERSION = [1,0].freeze | |
def initialize(host, port, server, concurrent) | |
- @server = server | |
+ @app = server.app | |
@socket = TCPServer.new(host, port) | |
@status = :closed # Start closed and give the server time to start | |
@@ -19,6 +19,7 @@ module ControlTower | |
@request_queue = Dispatch::Queue.concurrent | |
puts "Caution! Wake turbulance from heavy aircraft landing on parallel runway.\n(Parallel Request Action ENABLED!)" | |
else | |
+ @multithread = false | |
@request_queue = Dispatch::Queue.new('com.apple.ControlTower.rack_socket_queue') | |
end | |
@request_group = Dispatch::Group.new | |
@@ -30,15 +31,53 @@ module ControlTower | |
connection = @socket.accept | |
@request_queue.async(@request_group) do | |
- env = prepare_environment | |
+ env = { 'rack.errors' => $stderr, | |
+ 'rack.multiprocess' => false, | |
+ 'rack.multithread' => @multithread, | |
+ 'rack.run_once' => false, | |
+ 'rack.version' => VERSION } | |
begin | |
request_data = parse!(connection, env) | |
if request_data | |
request_data['REMOTE_ADDR'] = connection.addr[3] | |
- response_data = @server.handle_request(request_data) | |
- response_data.each do |chunk| | |
- connection.write chunk | |
+ status, headers, body = @app.call(request_data) | |
+ | |
+ # Unless somebody's already set it for us (or we don't need it), set the Content-Length | |
+ unless (status == -1 || | |
+ (status >= 100 and status <= 199) || | |
+ status == 204 || | |
+ status == 304 || | |
+ headers.has_key?('Content-Length')) | |
+ headers['Content-Length'] = if body.respond_to?(:each) | |
+ size = 0 | |
+ body.each { |x| size += x.bytesize } | |
+ size | |
+ else | |
+ body.bytesize | |
+ end | |
+ end | |
+ | |
+ # TODO -- We don't handle keep-alive connections yet | |
+ headers['Connection'] = 'close' | |
+ | |
+ resp = "HTTP/1.1 #{status}\r\n" | |
+ headers.each do |header, value| | |
+ resp << "#{header}: #{value}\r\n" | |
+ end | |
+ resp << "\r\n" | |
+ | |
+ # Start writing the response | |
+ connection.write resp | |
+ | |
+ # Finish writing out the body | |
+ if body.respond_to?(:each) | |
+ body.each do |chunk| | |
+ connection.write chunk | |
+ end | |
+ else | |
+ connection.write body | |
end | |
+ | |
else | |
$stderr.puts "Error: No request data received!" | |
end | |
@@ -72,15 +111,6 @@ module ControlTower | |
private | |
- def prepare_environment | |
- { 'rack.errors' => $stderr, | |
- 'rack.input' => NSMutableData.new, | |
- 'rack.multiprocess' => false, | |
- 'rack.multithread' => @multithread, | |
- 'rack.run_once' => false, | |
- 'rack.version' => VERSION } | |
- end | |
- | |
def parse!(connection, env) | |
parser = Thread.current[:http_parser] ||= ::CTParser.new | |
parser.reset | |
diff --git a/lib/control_tower/server.rb b/lib/control_tower/server.rb | |
index c47cd25..4636677 100644 | |
--- a/lib/control_tower/server.rb | |
+++ b/lib/control_tower/server.rb | |
@@ -3,6 +3,8 @@ | |
module ControlTower | |
class Server | |
+ attr_reader :app | |
+ | |
def initialize(app, options) | |
@app = app | |
parse_options(options) | |
@@ -19,10 +21,6 @@ module ControlTower | |
@socket.open | |
end | |
- def handle_request(env) | |
- wrap_output(*@app.call(env)) | |
- end | |
- | |
private | |
def parse_options(opt) | |
@@ -30,42 +28,5 @@ module ControlTower | |
@host = opt[:host] || `hostname`.chomp | |
@concurrent = opt[:concurrent] | |
end | |
- | |
- def wrap_output(status, headers, body) | |
- # Unless somebody's already set it for us (or we don't need it), set the Content-Length | |
- unless (status == -1 || | |
- (status >= 100 and status <= 199) || | |
- status == 204 || | |
- status == 304 || | |
- headers.has_key?("Content-Length")) | |
- headers["Content-Length"] = if body.respond_to?(:each) | |
- size = 0 | |
- body.each { |x| size += x.bytesize } | |
- size | |
- else | |
- body.bytesize | |
- end | |
- end | |
- | |
- # TODO -- We don't handle keep-alive connections yet | |
- headers["Connection"] = 'close' | |
- | |
- resp = "HTTP/1.1 #{status}\r\n" | |
- headers.each do |header, value| | |
- resp << "#{header}: #{value}\r\n" | |
- end | |
- resp << "\r\n" | |
- | |
- # Assemble our response... | |
- chunks = [resp] | |
- if body.respond_to?(:each) | |
- body.each do |chunk| | |
- chunks << chunk | |
- end | |
- else | |
- chunks << body | |
- end | |
- chunks | |
- end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment