eventmachine_httpserver 0.0.1 → 0.1.1
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.
- 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
|