eventmachine_httpserver 0.0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +69 -62
- data/{COPYING → docs/COPYING} +0 -0
- data/{README → docs/README} +0 -0
- data/{RELEASE_NOTES → docs/RELEASE_NOTES} +0 -0
- data/eventmachine_httpserver.gemspec +33 -0
- data/eventmachine_httpserver.gemspec.tmpl +23 -0
- data/ext/extconf.rb +7 -2
- data/ext/http.cpp +2 -4
- data/ext/http.h +0 -2
- data/ext/rubyhttp.cpp +5 -2
- data/lib/evma_httpserver.rb +0 -2
- data/lib/evma_httpserver/response.rb +37 -4
- data/test/test_app.rb +239 -0
- data/test/{response.rb → test_delegated.rb} +43 -39
- data/test/test_response.rb +178 -0
- metadata +53 -47
- data/ext/ptch +0 -148
- data/test/app.rb +0 -235
data/Rakefile
CHANGED
@@ -1,85 +1,92 @@
|
|
1
1
|
# $Id: Rakefile 3546 2006-12-31 21:01:27Z francis $
|
2
|
-
# Rakefile for the Bayshore configurable LDAP server.
|
3
|
-
#
|
4
|
-
|
5
2
|
|
6
3
|
require 'rake/gempackagetask'
|
7
4
|
require 'rake/clean'
|
5
|
+
require 'rake/testtask'
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
require 'archive/tar/minitar'
|
14
|
-
require 'zlib'
|
15
|
-
$can_minitar = true
|
16
|
-
rescue LoadError
|
7
|
+
Rake::TestTask.new do |t|
|
8
|
+
t.libs += %w(ext)
|
9
|
+
t.test_files = FileList['test/test_*.rb']
|
10
|
+
t.verbose = true
|
17
11
|
end
|
18
12
|
|
19
|
-
|
20
|
-
|
21
|
-
$tardist = "#$distdir.tar.gz"
|
22
|
-
$name = "eventmachine_httpserver"
|
23
|
-
|
13
|
+
namespace :build do
|
14
|
+
sources = FileList['ext/*.{cpp,c,h}']
|
24
15
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
Rake::GemPackageTask.new(spec) do |g|
|
30
|
-
if $can_minitar
|
31
|
-
g.need_tar = true
|
32
|
-
g.need_zip = true
|
16
|
+
file 'ext/Makefile' => 'ext/extconf.rb' do
|
17
|
+
Dir.chdir 'ext' do
|
18
|
+
ruby 'extconf.rb'
|
19
|
+
end
|
33
20
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
21
|
+
CLEAN.include('ext/Makefile')
|
22
|
+
CLEAN.include('ext/*.log')
|
23
|
+
|
24
|
+
libfile = "ext/eventmachine_httpserver.#{Config::CONFIG['DLEXT']}"
|
25
|
+
file libfile => ['ext/Makefile', *sources] do
|
26
|
+
Dir.chdir 'ext' do
|
27
|
+
make = case RUBY_PLATFORM
|
28
|
+
when /mswin32/
|
29
|
+
'nmake'
|
30
|
+
else
|
31
|
+
# typical gcc stack, might need a case for gmake on some
|
32
|
+
'make'
|
33
|
+
end
|
34
|
+
sh make
|
35
|
+
end
|
46
36
|
end
|
47
|
-
|
37
|
+
CLEAN.include(libfile)
|
38
|
+
|
39
|
+
task :makefile => 'ext/Makefile'
|
40
|
+
|
41
|
+
task :extension => libfile
|
48
42
|
end
|
49
43
|
|
44
|
+
desc "Build the extension inside the ext dir"
|
45
|
+
task :build => :"build:extension"
|
46
|
+
|
47
|
+
desc "Build as necessary, then run tests"
|
48
|
+
task :test => :build
|
49
|
+
|
50
|
+
namespace :gem do
|
51
|
+
# TODO : use rake-compiler (github.com/luislavena/rake-compiler) for this!
|
52
|
+
# specbinary = eval(File.read("eventmachine_httpserver-binary.gemspec"))
|
53
|
+
# specbinary.version = $version
|
54
|
+
# desc "Build a binary RubyGem for EventMachine HTTP Server"
|
55
|
+
# task :gembinary => ["pkg/eventmachine_httpserver-binary-#{$version}.gem"]
|
56
|
+
# Rake::GemPackageTask.new(specbinary)
|
57
|
+
|
58
|
+
def gemspec
|
59
|
+
# The template executes some ruby code to make a manifest, so we just eval
|
60
|
+
# it. Later you could fill it with an ERB processor or whatever. It must
|
61
|
+
# return a valid gemspec object.
|
62
|
+
@gemspec ||= eval(File.read("eventmachine_httpserver.gemspec.tmpl"))
|
63
|
+
end
|
50
64
|
|
65
|
+
def version
|
66
|
+
gemspec.version
|
67
|
+
end
|
51
68
|
|
52
|
-
|
53
|
-
|
54
|
-
require 'test/unit/ui/console/testrunner'
|
55
|
-
|
56
|
-
runner = Test::Unit::UI::Console::TestRunner
|
57
|
-
|
58
|
-
$LOAD_PATH.unshift('test')
|
59
|
-
$stderr.puts "Checking for test cases:" if test.verbose
|
60
|
-
filename_array.each do |testcase|
|
61
|
-
$stderr.puts "\t#{testcase}" if test.verbose
|
62
|
-
load testcase
|
69
|
+
file "eventmachine_httpserver.gemspec" => 'eventmachine_httpserver.gemspec.tmpl' do |t|
|
70
|
+
open(t.name, 'w') { |f| f.write gemspec.to_ruby }
|
63
71
|
end
|
64
72
|
|
65
|
-
|
73
|
+
desc "Generate the gemspec from template"
|
74
|
+
task :spec => "eventmachine_httpserver.gemspec"
|
66
75
|
|
67
|
-
|
68
|
-
|
76
|
+
file "eventmachine_httpserver-#{version}.gem" => :"gem:spec" do
|
77
|
+
sh "gem build eventmachine_httpserver.gemspec"
|
69
78
|
end
|
70
79
|
|
71
|
-
|
72
|
-
|
80
|
+
desc "Build the RubyGem for EventMachine HTTP Server"
|
81
|
+
task :build => "eventmachine_httpserver-#{version}.gem"
|
73
82
|
|
74
|
-
desc "
|
75
|
-
task :
|
76
|
-
|
77
|
-
end
|
83
|
+
desc "run gem install on the built gem"
|
84
|
+
task :install => :build do
|
85
|
+
sh 'gem inst eventmachine_httpserver*.gem'
|
86
|
+
end
|
78
87
|
|
79
|
-
|
80
|
-
|
81
|
-
run_test_package t, Dir['test/app.rb']
|
88
|
+
CLOBBER.include("eventmachine_httpserver.gemspec")
|
89
|
+
CLEAN.include("eventmachine_httpserver-#{version}.gem")
|
82
90
|
end
|
83
91
|
|
84
|
-
task :default =>
|
85
|
-
|
92
|
+
task :default => :test
|
data/{COPYING → docs/COPYING}
RENAMED
File without changes
|
data/{README → docs/README}
RENAMED
File without changes
|
File without changes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{eventmachine_httpserver}
|
5
|
+
s.version = "0.1.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Francis Cianfrocca"]
|
9
|
+
s.cert_chain = nil
|
10
|
+
s.date = %q{2007-03-16}
|
11
|
+
s.description = %q{}
|
12
|
+
s.email = %q{garbagecat10@gmail.com}
|
13
|
+
s.extensions = ["ext/extconf.rb"]
|
14
|
+
s.extra_rdoc_files = ["docs/COPYING", "docs/README", "docs/RELEASE_NOTES"]
|
15
|
+
s.files = ["Rakefile", "docs/COPYING", "docs/README", "docs/RELEASE_NOTES", "eventmachine_httpserver.gemspec", "eventmachine_httpserver.gemspec.tmpl", "ext/extconf.rb", "ext/http.cpp", "ext/http.h", "ext/rubyhttp.cpp", "lib/evma_httpserver.rb", "lib/evma_httpserver/response.rb", "test/test_app.rb", "test/test_delegated.rb", "test/test_response.rb"]
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.homepage = %q{http://rubyeventmachine.com}
|
18
|
+
s.rdoc_options = ["--title", "EventMachine_HttpServer", "--main", "docs/README", "--line-numbers"]
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.required_ruby_version = Gem::Requirement.new("> 0.0.0")
|
21
|
+
s.rubygems_version = %q{1.3.1}
|
22
|
+
s.summary = %q{EventMachine HTTP Server}
|
23
|
+
|
24
|
+
if s.respond_to? :specification_version then
|
25
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
26
|
+
s.specification_version = 1
|
27
|
+
|
28
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
29
|
+
else
|
30
|
+
end
|
31
|
+
else
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = %q{eventmachine_httpserver}
|
3
|
+
s.version = "0.1.1"
|
4
|
+
|
5
|
+
s.specification_version = 1 if s.respond_to? :specification_version=
|
6
|
+
|
7
|
+
s.required_rubygems_version = nil if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Francis Cianfrocca"]
|
9
|
+
s.cert_chain = nil
|
10
|
+
s.date = %q{2007-03-16}
|
11
|
+
s.description = %q{}
|
12
|
+
s.email = %q{garbagecat10@gmail.com}
|
13
|
+
s.extensions = ["ext/extconf.rb"]
|
14
|
+
s.extra_rdoc_files = `git ls-files docs`.split
|
15
|
+
s.files = `git ls-files | grep -v .gitignore`.split
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.homepage = %q{http://rubyeventmachine.com}
|
18
|
+
s.rdoc_options = ["--title", "EventMachine_HttpServer", "--main", "docs/README", "--line-numbers"]
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.required_ruby_version = Gem::Requirement.new("> 0.0.0")
|
21
|
+
s.rubygems_version = %q{1.3.1}
|
22
|
+
s.summary = %q{EventMachine HTTP Server}
|
23
|
+
end
|
data/ext/extconf.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# $Id: extconf.rb 3896 2007-03-06 20:21:01Z francis $
|
2
|
-
#
|
3
1
|
#----------------------------------------------------------------------------
|
4
2
|
#
|
5
3
|
# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
|
@@ -116,6 +114,13 @@ else
|
|
116
114
|
end
|
117
115
|
# on Unix we need a g++ link, not gcc.
|
118
116
|
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
117
|
+
|
118
|
+
# Modify the mkmf constant LINK_SO so the generated shared object is stripped.
|
119
|
+
# You might think modifying CONFIG['LINK_SO'] would be a better way to do this,
|
120
|
+
# but it doesn't work because mkmf doesn't look at CONFIG['LINK_SO'] again after
|
121
|
+
# it initializes.
|
122
|
+
# linkso = Object.send :remove_const, "LINK_SO"
|
123
|
+
# LINK_SO = linkso + "; strip $@"
|
119
124
|
end
|
120
125
|
|
121
126
|
if $CPPFLAGS
|
data/ext/http.cpp
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: http.cpp 3967 2007-03-16 11:53:55Z francis $
|
4
|
-
|
5
3
|
File: http.cpp
|
6
4
|
Date: 21Apr06
|
7
5
|
|
@@ -27,6 +25,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
27
25
|
|
28
26
|
#include <iostream>
|
29
27
|
#include <string>
|
28
|
+
#include <cstdlib>
|
29
|
+
#include <cstring>
|
30
30
|
#include <sstream>
|
31
31
|
#include <stdexcept>
|
32
32
|
#include <stdio.h>
|
@@ -564,5 +564,3 @@ void HttpConnection_t::_SendError (int code)
|
|
564
564
|
|
565
565
|
SendData (ss.str().c_str(), ss.str().length());
|
566
566
|
}
|
567
|
-
|
568
|
-
|
data/ext/http.h
CHANGED
data/ext/rubyhttp.cpp
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: rubyhttp.cpp 3966 2007-03-16 11:52:05Z francis $
|
4
|
-
|
5
3
|
File: libmain.cpp
|
6
4
|
Date: 06Apr06
|
7
5
|
|
@@ -87,6 +85,10 @@ void RubyHttpConnection_t::CloseConnection (bool after_writing)
|
|
87
85
|
}
|
88
86
|
|
89
87
|
|
88
|
+
/*************************************
|
89
|
+
RubyHttpConnection_t::ReceivePostData
|
90
|
+
*************************************/
|
91
|
+
|
90
92
|
void RubyHttpConnection_t::ReceivePostData (const char *data, int len)
|
91
93
|
{
|
92
94
|
VALUE data_val = Qnil;
|
@@ -205,6 +207,7 @@ t_receive_post_data
|
|
205
207
|
static VALUE t_receive_post_data (VALUE self, VALUE data)
|
206
208
|
{
|
207
209
|
/** This is a NOOP. It should be overridden. **/
|
210
|
+
return Qnil;
|
208
211
|
}
|
209
212
|
|
210
213
|
/********
|
data/lib/evma_httpserver.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# $Id: response.rb 3897 2007-03-06 20:21:08Z francis $
|
2
|
-
#
|
3
1
|
# EventMachine HTTP Server
|
4
2
|
# HTTP Response-support class
|
5
3
|
#
|
@@ -34,6 +32,22 @@
|
|
34
32
|
|
35
33
|
module EventMachine
|
36
34
|
|
35
|
+
# This class provides a wide variety of features for generating and
|
36
|
+
# dispatching HTTP responses. It allows you to conveniently generate
|
37
|
+
# headers and content (including chunks and multiparts), and dispatch
|
38
|
+
# responses (including deferred or partially-complete responses).
|
39
|
+
#
|
40
|
+
# Although HttpResponse is coded as a class, it's not complete as it
|
41
|
+
# stands. It assumes that it has certain of the behaviors of
|
42
|
+
# EventMachine::Connection. You must add these behaviors, either by
|
43
|
+
# subclassing HttpResponse, or using the alternate version of this
|
44
|
+
# class, DelegatedHttpResponse. See the test cases for current information
|
45
|
+
# on which behaviors you have to add.
|
46
|
+
#
|
47
|
+
# TODO, someday it would be nice to provide a version of this functionality
|
48
|
+
# that is coded as a Module, so it can simply be mixed into an instance of
|
49
|
+
# EventMachine::Connection.
|
50
|
+
#
|
37
51
|
class HttpResponse
|
38
52
|
attr_accessor :status, :content, :headers, :chunks, :multiparts
|
39
53
|
|
@@ -108,7 +122,7 @@ module EventMachine
|
|
108
122
|
def generate_header_lines in_hash
|
109
123
|
out_ary = []
|
110
124
|
in_hash.keys.sort.each {|k|
|
111
|
-
v =
|
125
|
+
v = in_hash[k]
|
112
126
|
if v.is_a?(Array)
|
113
127
|
v.each {|v1| out_ary << "#{k}: #{v1}\r\n" }
|
114
128
|
else
|
@@ -257,7 +271,7 @@ module EventMachine
|
|
257
271
|
end
|
258
272
|
end
|
259
273
|
|
260
|
-
#
|
274
|
+
# TODO, this is going to be way too slow. Cache up the uuidgens.
|
261
275
|
#
|
262
276
|
def self.concoct_multipart_boundary
|
263
277
|
@multipart_index ||= 0
|
@@ -278,3 +292,22 @@ module EventMachine
|
|
278
292
|
end
|
279
293
|
end
|
280
294
|
|
295
|
+
#----------------------------------------------------------------------------
|
296
|
+
|
297
|
+
require 'forwardable'
|
298
|
+
|
299
|
+
module EventMachine
|
300
|
+
class DelegatedHttpResponse < HttpResponse
|
301
|
+
extend Forwardable
|
302
|
+
def_delegators :@delegate,
|
303
|
+
:send_data,
|
304
|
+
:close_connection,
|
305
|
+
:close_connection_after_writing
|
306
|
+
|
307
|
+
def initialize dele
|
308
|
+
super()
|
309
|
+
@delegate = dele
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
data/test/test_app.rb
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'evma_httpserver'
|
3
|
+
|
4
|
+
begin
|
5
|
+
once = false
|
6
|
+
require 'eventmachine'
|
7
|
+
rescue LoadError => e
|
8
|
+
raise e if once
|
9
|
+
once = true
|
10
|
+
require 'rubygems'
|
11
|
+
retry
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
#--------------------------------------
|
17
|
+
|
18
|
+
module EventMachine
|
19
|
+
module HttpServer
|
20
|
+
def process_http_request
|
21
|
+
send_data generate_response()
|
22
|
+
close_connection_after_writing
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
#--------------------------------------
|
28
|
+
|
29
|
+
require 'socket'
|
30
|
+
|
31
|
+
class TestApp < Test::Unit::TestCase
|
32
|
+
|
33
|
+
TestHost = "127.0.0.1"
|
34
|
+
TestPort = 8911
|
35
|
+
|
36
|
+
TestResponse_1 = <<EORESP
|
37
|
+
HTTP/1.0 200 ...
|
38
|
+
Content-length: 4
|
39
|
+
Content-type: text/plain
|
40
|
+
Connection: close
|
41
|
+
|
42
|
+
1234
|
43
|
+
EORESP
|
44
|
+
|
45
|
+
Thread.abort_on_exception = true
|
46
|
+
|
47
|
+
def test_simple_get
|
48
|
+
received_response = nil
|
49
|
+
|
50
|
+
EventMachine::HttpServer.module_eval do
|
51
|
+
def generate_response
|
52
|
+
TestResponse_1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
EventMachine.run do
|
58
|
+
EventMachine.start_server TestHost, TestPort, EventMachine::HttpServer
|
59
|
+
EventMachine.add_timer(1) {raise "timed out"} # make sure the test completes
|
60
|
+
|
61
|
+
cb = proc do
|
62
|
+
tcp = TCPSocket.new TestHost, TestPort
|
63
|
+
tcp.write "GET / HTTP/1.0\r\n\r\n"
|
64
|
+
received_response = tcp.read
|
65
|
+
end
|
66
|
+
eb = proc { EventMachine.stop }
|
67
|
+
EventMachine.defer cb, eb
|
68
|
+
end
|
69
|
+
|
70
|
+
assert_equal( TestResponse_1, received_response )
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
# This frowsy-looking protocol handler allows the test harness to make some
|
77
|
+
# its local variables visible, so we can set them here and they can be asserted later.
|
78
|
+
class MyTestServer < EventMachine::Connection
|
79
|
+
include EventMachine::HttpServer
|
80
|
+
def initialize *args
|
81
|
+
super
|
82
|
+
end
|
83
|
+
def generate_response
|
84
|
+
@assertions.call
|
85
|
+
TestResponse_1
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
def test_parameters
|
92
|
+
path_info = "/test.html"
|
93
|
+
query_string = "a=b&c=d"
|
94
|
+
cookie = "eat_me=I'm a cookie"
|
95
|
+
etag = "12345"
|
96
|
+
|
97
|
+
# collect all the stuff we want to assert outside the actual test,
|
98
|
+
# to ensure it gets asserted even if the test catches some exception.
|
99
|
+
received_response = nil
|
100
|
+
request_parms = {}
|
101
|
+
|
102
|
+
|
103
|
+
EventMachine.run do
|
104
|
+
EventMachine.start_server(TestHost, TestPort, MyTestServer) do |conn|
|
105
|
+
# In each accepted connection, set up a procedure that will copy
|
106
|
+
# the request parameters into a local variable visible here, so
|
107
|
+
# we can assert the values later.
|
108
|
+
conn.instance_eval do
|
109
|
+
@assertions = proc {
|
110
|
+
parms = %w( PATH_INFO QUERY_STRING HTTP_COOKIE IF_NONE_MATCH
|
111
|
+
CONTENT_TYPE REQUEST_METHOD REQUEST_URI )
|
112
|
+
parms.each {|parm|
|
113
|
+
# request_parms is bound to a local variable visible in this context.
|
114
|
+
request_parms[parm] = ENV[parm]
|
115
|
+
}
|
116
|
+
}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
EventMachine.add_timer(1) {raise "timed out"} # make sure the test completes
|
120
|
+
|
121
|
+
cb = proc do
|
122
|
+
tcp = TCPSocket.new TestHost, TestPort
|
123
|
+
data = [
|
124
|
+
"GET #{path_info}?#{query_string} HTTP/1.1\r\n",
|
125
|
+
"Cookie: #{cookie}\r\n",
|
126
|
+
"If-none-match: #{etag}\r\n",
|
127
|
+
"\r\n"
|
128
|
+
].join
|
129
|
+
tcp.write(data)
|
130
|
+
received_response = tcp.read
|
131
|
+
end
|
132
|
+
eb = proc { EventMachine.stop }
|
133
|
+
EventMachine.defer cb, eb
|
134
|
+
end
|
135
|
+
|
136
|
+
assert_equal( TestResponse_1, received_response )
|
137
|
+
assert_equal( path_info, request_parms["PATH_INFO"] )
|
138
|
+
assert_equal( query_string, request_parms["QUERY_STRING"] )
|
139
|
+
assert_equal( cookie, request_parms["HTTP_COOKIE"] )
|
140
|
+
assert_equal( etag, request_parms["IF_NONE_MATCH"] )
|
141
|
+
assert_equal( nil, request_parms["CONTENT_TYPE"] )
|
142
|
+
assert_equal( "GET", request_parms["REQUEST_METHOD"] )
|
143
|
+
assert_equal( path_info, request_parms["REQUEST_URI"] )
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
def test_headers
|
148
|
+
received_header_string = nil
|
149
|
+
received_header_ary = nil
|
150
|
+
|
151
|
+
EventMachine.run do
|
152
|
+
EventMachine.start_server(TestHost, TestPort, MyTestServer) do |conn|
|
153
|
+
# In each accepted connection, set up a procedure that will copy
|
154
|
+
# the request parameters into a local variable visible here, so
|
155
|
+
# we can assert the values later.
|
156
|
+
# The @http_headers is set automatically and can easily be parsed.
|
157
|
+
# It isn't automatically parsed into Ruby values because that is
|
158
|
+
# a costly operation, but we should provide an optional method that
|
159
|
+
# does the parsing so it doesn't need to be done by users.
|
160
|
+
conn.instance_eval do
|
161
|
+
@assertions = proc do
|
162
|
+
received_header_string = @http_headers
|
163
|
+
received_header_ary = @http_headers.split(/\0/).map {|line| line.split(/:\s*/, 2) }
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
cb = proc do
|
169
|
+
tcp = TCPSocket.new TestHost, TestPort
|
170
|
+
data = [
|
171
|
+
"GET / HTTP/1.1\r\n",
|
172
|
+
"aaa: 111\r\n",
|
173
|
+
"bbb: 222\r\n",
|
174
|
+
"ccc: 333\r\n",
|
175
|
+
"ddd: 444\r\n",
|
176
|
+
"\r\n"
|
177
|
+
].join
|
178
|
+
tcp.write data
|
179
|
+
received_response = tcp.read
|
180
|
+
end
|
181
|
+
eb = proc { EventMachine.stop }
|
182
|
+
EventMachine.defer cb, eb
|
183
|
+
|
184
|
+
EventMachine.add_timer(1) {raise "timed out"} # make sure the test completes
|
185
|
+
end
|
186
|
+
|
187
|
+
assert_equal( "aaa: 111\0bbb: 222\0ccc: 333\0ddd: 444\0\0", received_header_string )
|
188
|
+
assert_equal( [["aaa","111"], ["bbb","222"], ["ccc","333"], ["ddd","444"]], received_header_ary )
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
def test_post
|
196
|
+
received_header_string = nil
|
197
|
+
post_content = "1234567890"
|
198
|
+
content_type = "text/plain"
|
199
|
+
received_post_content = ""
|
200
|
+
received_content_type = ""
|
201
|
+
|
202
|
+
EventMachine.run do
|
203
|
+
EventMachine.start_server(TestHost, TestPort, MyTestServer) do |conn|
|
204
|
+
# In each accepted connection, set up a procedure that will copy
|
205
|
+
# the request parameters into a local variable visible here, so
|
206
|
+
# we can assert the values later.
|
207
|
+
# The @http_post_content variable is set automatically.
|
208
|
+
conn.instance_eval do
|
209
|
+
@assertions = proc do
|
210
|
+
received_post_content = @http_post_content
|
211
|
+
received_content_type = ENV["CONTENT_TYPE"]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
EventMachine.add_timer(1) {raise "timed out"} # make sure the test completes
|
216
|
+
|
217
|
+
cb = proc do
|
218
|
+
tcp = TCPSocket.new TestHost, TestPort
|
219
|
+
data = [
|
220
|
+
"POST / HTTP/1.1\r\n",
|
221
|
+
"Content-type: #{content_type}\r\n",
|
222
|
+
"Content-length: #{post_content.length}\r\n",
|
223
|
+
"\r\n",
|
224
|
+
post_content
|
225
|
+
].join
|
226
|
+
tcp.write(data)
|
227
|
+
received_response = tcp.read
|
228
|
+
end
|
229
|
+
eb = proc do
|
230
|
+
EventMachine.stop
|
231
|
+
end
|
232
|
+
EventMachine.defer cb, eb
|
233
|
+
end
|
234
|
+
|
235
|
+
assert_equal( received_post_content, post_content )
|
236
|
+
assert_equal( received_content_type, content_type )
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|