eventmachine_httpserver 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +48 -0
- data/eventmachine_httpserver.gemspec +3 -4
- data/eventmachine_httpserver.gemspec.tmpl +2 -2
- data/ext/http.cpp +20 -1
- data/ext/rubyhttp.cpp +17 -19
- metadata +6 -3
data/README
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
= eventmachine_httpserver
|
2
|
+
|
3
|
+
== EM::HttpServer vs Thin
|
4
|
+
|
5
|
+
+careo | is there a 25 word version of how it differs from thin?
|
6
|
+
+tmm1 | good question.. its probably faster, but only because it doesn't have a real http parser like thin
|
7
|
+
+wyhaines | It is faster. It's more of an nginx style parser than the mongrel, grammar based parser.
|
8
|
+
+careo | so perhaps a better fit for putting an http interface on top of a bunch of already-evented code?
|
9
|
+
+wyhaines | careo: It depends. There are very valid arguments for using an RFC-compliant parser a lot of the time.
|
10
|
+
+wyhaines | But, yeah, sometimes being strictly RFC compliant isn't something that you care about.
|
11
|
+
|
12
|
+
== Usage example
|
13
|
+
|
14
|
+
require 'eventmachine'
|
15
|
+
require 'evma_httpserver'
|
16
|
+
|
17
|
+
class MyHttpServer < EM::Connection
|
18
|
+
include EM::HttpServer
|
19
|
+
|
20
|
+
def post_init
|
21
|
+
super
|
22
|
+
no_environment_strings
|
23
|
+
end
|
24
|
+
|
25
|
+
def process_http_request
|
26
|
+
# the http request details are available via the following instance variables:
|
27
|
+
# @http_protocol
|
28
|
+
# @http_request_method
|
29
|
+
# @http_cookie
|
30
|
+
# @http_if_none_match
|
31
|
+
# @http_content_type
|
32
|
+
# @http_path_info
|
33
|
+
# @http_request_uri
|
34
|
+
# @http_query_string
|
35
|
+
# @http_post_content
|
36
|
+
# @http_headers
|
37
|
+
|
38
|
+
response = EM::DelegatedHttpResponse.new(self)
|
39
|
+
response.status = 200
|
40
|
+
response.content_type 'text/html'
|
41
|
+
response.content = '<center><h1>Hi there</h1></center>'
|
42
|
+
response.send_response
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
EM.run{
|
47
|
+
EM.start_server '0.0.0.0', 8080, MyHttpServer
|
48
|
+
}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{eventmachine_httpserver}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.2.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Francis Cianfrocca"]
|
@@ -12,13 +12,12 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.email = %q{garbagecat10@gmail.com}
|
13
13
|
s.extensions = ["ext/extconf.rb"]
|
14
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
|
15
|
+
s.files = ["README", "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"]
|
17
16
|
s.homepage = %q{http://rubyeventmachine.com}
|
18
17
|
s.rdoc_options = ["--title", "EventMachine_HttpServer", "--main", "docs/README", "--line-numbers"]
|
19
18
|
s.require_paths = ["lib"]
|
20
19
|
s.required_ruby_version = Gem::Requirement.new("> 0.0.0")
|
21
|
-
s.rubygems_version = %q{1.3.
|
20
|
+
s.rubygems_version = %q{1.3.4}
|
22
21
|
s.summary = %q{EventMachine HTTP Server}
|
23
22
|
|
24
23
|
if s.respond_to? :specification_version then
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = %q{eventmachine_httpserver}
|
3
|
-
s.version = "0.1.
|
3
|
+
s.version = "0.1.2"
|
4
4
|
|
5
5
|
s.specification_version = 1 if s.respond_to? :specification_version=
|
6
6
|
|
@@ -20,4 +20,4 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.required_ruby_version = Gem::Requirement.new("> 0.0.0")
|
21
21
|
s.rubygems_version = %q{1.3.1}
|
22
22
|
s.summary = %q{EventMachine HTTP Server}
|
23
|
-
end
|
23
|
+
end
|
data/ext/http.cpp
CHANGED
@@ -170,6 +170,15 @@ void HttpConnection_t::ConsumeData (const char *data, int length)
|
|
170
170
|
_Content = NULL;
|
171
171
|
}
|
172
172
|
RequestMethod = NULL;
|
173
|
+
#ifdef OS_WIN32
|
174
|
+
Cookie.erase(Cookie.begin(),Cookie.end());
|
175
|
+
IfNoneMatch.erase(IfNoneMatch.begin(),IfNoneMatch.end());
|
176
|
+
ContentType.erase(ContentType.begin(),ContentType.end());
|
177
|
+
PathInfo.erase(PathInfo.begin(),PathInfo.end());
|
178
|
+
RequestUri.erase(RequestUri.begin(),RequestUri.end());
|
179
|
+
QueryString.erase(QueryString.begin(),QueryString.end());
|
180
|
+
Protocol.erase(Protocol.begin(),Protocol.end());
|
181
|
+
#else
|
173
182
|
Cookie.clear();
|
174
183
|
IfNoneMatch.clear();
|
175
184
|
ContentType.clear();
|
@@ -177,6 +186,7 @@ void HttpConnection_t::ConsumeData (const char *data, int length)
|
|
177
186
|
RequestUri.clear();
|
178
187
|
QueryString.clear();
|
179
188
|
Protocol.clear();
|
189
|
+
#endif
|
180
190
|
|
181
191
|
if (bSetEnvironmentStrings) {
|
182
192
|
unsetenv ("REQUEST_METHOD");
|
@@ -460,7 +470,8 @@ bool HttpConnection_t::_InterpretRequest (const char *header)
|
|
460
470
|
const char *questionmark = strchr (blank, '?');
|
461
471
|
if (questionmark && (questionmark >= blank2))
|
462
472
|
questionmark = NULL;
|
463
|
-
const char *fragment = strpbrk ((questionmark ? (questionmark+1) : blank), "#;");
|
473
|
+
// const char *fragment = strpbrk ((questionmark ? (questionmark+1) : blank), "#;");
|
474
|
+
const char *fragment = strpbrk ((questionmark ? (questionmark+1) : blank), "#");
|
464
475
|
if (fragment && (fragment >= blank2))
|
465
476
|
fragment = NULL;
|
466
477
|
|
@@ -482,7 +493,11 @@ bool HttpConnection_t::_InterpretRequest (const char *header)
|
|
482
493
|
string req (blank, fragment - blank);
|
483
494
|
PathInfo = req.c_str();
|
484
495
|
RequestUri = req.c_str();
|
496
|
+
#ifdef OS_WIN32
|
497
|
+
QueryString.erase(QueryString.begin(),QueryString.end());
|
498
|
+
#else
|
485
499
|
QueryString.clear();
|
500
|
+
#endif
|
486
501
|
if (bSetEnvironmentStrings) {
|
487
502
|
setenv ("PATH_INFO", req.c_str(), true);
|
488
503
|
setenv ("REQUEST_URI", req.c_str(), true);
|
@@ -494,7 +509,11 @@ bool HttpConnection_t::_InterpretRequest (const char *header)
|
|
494
509
|
string req (blank, blank2 - blank);
|
495
510
|
PathInfo = req.c_str();
|
496
511
|
RequestUri = req.c_str();
|
512
|
+
#ifdef OS_WIN32
|
513
|
+
QueryString.erase(QueryString.begin(),QueryString.end());
|
514
|
+
#else
|
497
515
|
QueryString.clear();
|
516
|
+
#endif
|
498
517
|
if (bSetEnvironmentStrings) {
|
499
518
|
setenv ("PATH_INFO", req.c_str(), true);
|
500
519
|
setenv ("REQUEST_URI", req.c_str(), true);
|
data/ext/rubyhttp.cpp
CHANGED
@@ -170,7 +170,7 @@ void RubyHttpConnection_t::ProcessRequest (const char *request_method,
|
|
170
170
|
Statics
|
171
171
|
*******/
|
172
172
|
|
173
|
-
|
173
|
+
VALUE Intern_http_conn;
|
174
174
|
|
175
175
|
/***********
|
176
176
|
t_post_init
|
@@ -182,7 +182,7 @@ static VALUE t_post_init (VALUE self)
|
|
182
182
|
if (!hc)
|
183
183
|
throw std::runtime_error ("no http-connection object");
|
184
184
|
|
185
|
-
rb_ivar_set (self,
|
185
|
+
rb_ivar_set (self, Intern_http_conn, LONG2NUM ((long)hc));
|
186
186
|
return Qnil;
|
187
187
|
}
|
188
188
|
|
@@ -194,7 +194,7 @@ t_receive_data
|
|
194
194
|
static VALUE t_receive_data (VALUE self, VALUE data)
|
195
195
|
{
|
196
196
|
int length = NUM2INT (rb_funcall (data, rb_intern ("length"), 0));
|
197
|
-
RubyHttpConnection_t *hc = (RubyHttpConnection_t*)(
|
197
|
+
RubyHttpConnection_t *hc = (RubyHttpConnection_t*)(NUM2LONG (rb_ivar_get (self, Intern_http_conn)));
|
198
198
|
if (hc)
|
199
199
|
hc->ConsumeData (StringValuePtr (data), length);
|
200
200
|
return Qnil;
|
@@ -216,7 +216,7 @@ t_unbind
|
|
216
216
|
|
217
217
|
static VALUE t_unbind (VALUE self)
|
218
218
|
{
|
219
|
-
RubyHttpConnection_t *hc = (RubyHttpConnection_t*)(
|
219
|
+
RubyHttpConnection_t *hc = (RubyHttpConnection_t*)(NUM2LONG (rb_ivar_get (self, Intern_http_conn)));
|
220
220
|
if (hc)
|
221
221
|
delete hc;
|
222
222
|
return Qnil;
|
@@ -240,7 +240,7 @@ t_no_environment_strings
|
|
240
240
|
|
241
241
|
static VALUE t_no_environment_strings (VALUE self)
|
242
242
|
{
|
243
|
-
RubyHttpConnection_t *hc = (RubyHttpConnection_t*)(
|
243
|
+
RubyHttpConnection_t *hc = (RubyHttpConnection_t*)(NUM2LONG (rb_ivar_get (self, Intern_http_conn)));
|
244
244
|
if (hc)
|
245
245
|
hc->SetNoEnvironmentStrings();
|
246
246
|
return Qnil;
|
@@ -252,7 +252,7 @@ t_dont_accumulate_post
|
|
252
252
|
|
253
253
|
static VALUE t_dont_accumulate_post (VALUE self)
|
254
254
|
{
|
255
|
-
RubyHttpConnection_t *hc = (RubyHttpConnection_t*)(
|
255
|
+
RubyHttpConnection_t *hc = (RubyHttpConnection_t*)(NUM2LONG (rb_ivar_get (self, Intern_http_conn)));
|
256
256
|
if (hc)
|
257
257
|
hc->SetDontAccumulatePost();
|
258
258
|
return Qnil;
|
@@ -265,17 +265,15 @@ Init_eventmachine_httpserver
|
|
265
265
|
|
266
266
|
extern "C" void Init_eventmachine_httpserver()
|
267
267
|
{
|
268
|
-
|
269
|
-
|
270
|
-
VALUE
|
271
|
-
VALUE
|
272
|
-
rb_define_method (
|
273
|
-
rb_define_method (
|
274
|
-
rb_define_method (
|
275
|
-
rb_define_method (
|
276
|
-
rb_define_method (
|
277
|
-
rb_define_method (
|
278
|
-
rb_define_method (
|
268
|
+
Intern_http_conn = rb_intern ("http_conn");
|
269
|
+
|
270
|
+
VALUE EmModule = rb_define_module ("EventMachine");
|
271
|
+
VALUE HttpServer = rb_define_module_under (EmModule, "HttpServer");
|
272
|
+
rb_define_method (HttpServer, "post_init", (VALUE(*)(...))t_post_init, 0);
|
273
|
+
rb_define_method (HttpServer, "receive_data", (VALUE(*)(...))t_receive_data, 1);
|
274
|
+
rb_define_method (HttpServer, "receive_post_data", (VALUE(*)(...))t_receive_post_data, 1);
|
275
|
+
rb_define_method (HttpServer, "unbind", (VALUE(*)(...))t_unbind, 0);
|
276
|
+
rb_define_method (HttpServer, "process_http_request", (VALUE(*)(...))t_process_http_request, 0);
|
277
|
+
rb_define_method (HttpServer, "no_environment_strings", (VALUE(*)(...))t_no_environment_strings, 0);
|
278
|
+
rb_define_method (HttpServer, "dont_accumulate_post", (VALUE(*)(...))t_dont_accumulate_post, 0);
|
279
279
|
}
|
280
|
-
|
281
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eventmachine_httpserver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Francis Cianfrocca
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain:
|
11
|
-
date: 2007-03-16 00:00:00
|
11
|
+
date: 2007-03-16 00:00:00 -07:00
|
12
12
|
default_executable:
|
13
13
|
dependencies: []
|
14
14
|
|
@@ -23,6 +23,7 @@ extra_rdoc_files:
|
|
23
23
|
- docs/README
|
24
24
|
- docs/RELEASE_NOTES
|
25
25
|
files:
|
26
|
+
- README
|
26
27
|
- Rakefile
|
27
28
|
- docs/COPYING
|
28
29
|
- docs/README
|
@@ -40,6 +41,8 @@ files:
|
|
40
41
|
- test/test_response.rb
|
41
42
|
has_rdoc: true
|
42
43
|
homepage: http://rubyeventmachine.com
|
44
|
+
licenses: []
|
45
|
+
|
43
46
|
post_install_message:
|
44
47
|
rdoc_options:
|
45
48
|
- --title
|
@@ -64,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
67
|
requirements: []
|
65
68
|
|
66
69
|
rubyforge_project:
|
67
|
-
rubygems_version: 1.3.
|
70
|
+
rubygems_version: 1.3.4
|
68
71
|
signing_key:
|
69
72
|
specification_version: 1
|
70
73
|
summary: EventMachine HTTP Server
|