Skip to content

Commit

Permalink
custom error string for bad requests
Browse files Browse the repository at this point in the history
  • Loading branch information
alor committed Nov 26, 2013
1 parent 2cd7369 commit 5c8a122
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 44 deletions.
2 changes: 1 addition & 1 deletion em-http-server.gemspec
Expand Up @@ -11,7 +11,7 @@ Gem::Specification.new do |gem|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.name = "em-http-server"
gem.require_paths = ["lib"]
gem.version = "0.1.6"
gem.version = "0.1.7"

gem.add_runtime_dependency "eventmachine"
end
24 changes: 17 additions & 7 deletions lib/em-http-server/server.rb
Expand Up @@ -41,28 +41,38 @@ def receive_request(headers, content)
def parse_first_header(line)

# split the line into: METHOD URI PROTOCOL
# eg: GET / HTTP1/1
# eg: GET / HTTP/1.1
parsed = line.split(' ')

# a correct request has three parts
send_error(400, "Bad request") unless parsed.size == 3
return bad_parsing unless parsed.size == 3

@http_request_method, uri, @http_protocol = parsed

# optional query string
@http_request_uri, @http_query_string = uri.split('?')
end

# send back to the client an HTTP error
def send_error(code, desc)
string = "HTTP1/1 #{code} #{desc}\r\n"
def bad_parsing
code = 400
desc = "Bad request"
string = respond_to?(:http_error_string) ? http_error_string(code, desc) : default_error_string(code, desc)
send_error string
raise("#{code} #{desc}")
end

def default_error_string(code, desc)
string = "HTTP/1.1 #{code} #{desc}\r\n"
string << "Connection: close\r\n"
string << "Content-type: text/plain\r\n"
string << "\r\n"
string << "Detected error: HTTP code #{code}"
end

# send back to the client an HTTP error
def send_error(string)
send_data string
close_connection_after_writing
raise("server error #{code}")
end

end
Expand All @@ -72,7 +82,7 @@ def send_error(code, desc)

if __FILE__ == $0

class HTTPHandler < EM::Http::Server
class HTTPHandler < EM::HttpServer::Server

def process_http_request
puts @http_request_method
Expand Down
58 changes: 42 additions & 16 deletions test/test_app.rb
@@ -1,22 +1,13 @@
require 'test/unit'
require 'em-http-server'

begin
once = false
require 'eventmachine'
rescue LoadError => e
raise e if once
once = true
require 'rubygems'
retry
end

require 'eventmachine'


#--------------------------------------

module EventMachine
class HttpServer < EM::Http::Server
class HttpHandler < EM::HttpServer::Server
def process_http_request
send_data generate_response()
close_connection_after_writing
Expand Down Expand Up @@ -47,15 +38,15 @@ class TestApp < Test::Unit::TestCase
def test_simple_get
received_response = nil

EventMachine::HttpServer.class_eval do
EventMachine::HttpHandler.class_eval do
def generate_response
TestResponse_1
end
end


EventMachine.run do
EventMachine.start_server TestHost, TestPort, EventMachine::HttpServer
EventMachine.start_server TestHost, TestPort, EventMachine::HttpHandler
EventMachine.add_timer(1) {raise "timed out"} # make sure the test completes

cb = proc do
Expand All @@ -75,7 +66,7 @@ def generate_response

# This frowsy-looking protocol handler allows the test harness to make some
# its local variables visible, so we can set them here and they can be asserted later.
class MyTestServer < EventMachine::HttpServer
class MyTestServer < EventMachine::HttpHandler

def initialize *args
super
Expand Down Expand Up @@ -251,7 +242,42 @@ def test_invalid
cb = proc do
tcp = TCPSocket.new TestHost, TestPort
data = [
"GET foo HTTP/1.1\r\n",
"GET HTTP/1.1\r\n",
"\r\n"
].join
tcp.write data
received_response = tcp.read
end
eb = proc { EventMachine.stop }
EventMachine.defer cb, eb

EventMachine.add_timer(1) {raise "timed out"} # make sure the test completes
end

assert_equal( "HTTP/1.1 400 Bad request\r\nConnection: close\r\nContent-type: text/plain\r\n\r\nDetected error: HTTP code 400", received_response )
end

def test_invalid_custom
received_response = nil

MyTestServer.class_eval do
def http_error_string(code, desc)
return 'custom'
end
end

EventMachine.run do
EventMachine.start_server(TestHost, TestPort, MyTestServer) do |conn|
conn.instance_eval do
@assertions = proc do
end
end
end

cb = proc do
tcp = TCPSocket.new TestHost, TestPort
data = [
"GET HTTP/1.1\r\n",
"\r\n"
].join
tcp.write data
Expand All @@ -263,7 +289,7 @@ def test_invalid
EventMachine.add_timer(1) {raise "timed out"} # make sure the test completes
end

assert_equal( "HTTP1/1 400 Bad request\r\nConnection: close\r\nContent-type: text/plain\r\n\r\nDetected error: HTTP code 400", received_response )
assert_equal( "custom", received_response )
end


Expand Down
11 changes: 1 addition & 10 deletions test/test_delegated.rb
@@ -1,16 +1,7 @@
require 'test/unit'
require 'em-http-server'

begin
once = false
require 'eventmachine'
rescue LoadError => e
raise e if once
once = true
require 'rubygems'
retry
end

require 'eventmachine'

#--------------------------------------

Expand Down
11 changes: 1 addition & 10 deletions test/test_response.rb
@@ -1,16 +1,7 @@
require 'test/unit'
require 'em-http-server'

begin
once = false
require 'eventmachine'
rescue LoadError => e
raise e if once
once = true
require 'rubygems'
retry
end

require 'eventmachine'

#--------------------------------------

Expand Down

0 comments on commit 5c8a122

Please sign in to comment.