aspirin 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/VERSION +1 -1
  2. data/ext/aspirin.c +132 -177
  3. data/ext/aspirin.h +87 -0
  4. metadata +4 -3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.0.1
@@ -1,19 +1,4 @@
1
- #include <ruby.h>
2
- #ifdef HAVE_RUBY_ST_H
3
- #include <ruby/st.h>
4
- #else
5
- #include <st.h>
6
- #endif
7
- #include <signal.h>
8
- #include <sys/queue.h>
9
- #include <stdio.h>
10
- #include <ctype.h>
11
-
12
- #include <event.h>
13
- #include <evhttp.h>
14
- #include <evutil.h>
15
-
16
- #define INSPECT(obj) {VALUE __obj__ = rb_inspect((obj)); fprintf(stderr, "%d:%s\n", __LINE__, RSTRING_PTR(__obj__));}
1
+ #include "aspirin.h"
17
2
 
18
3
  static VALUE rb_mAspirin;
19
4
  static VALUE rb_cAspirin_Server;
@@ -26,79 +11,21 @@ static const char* const status_code_str[] = {
26
11
  "Continue","Switching Protocols","Processing","OK","Created","Accepted","Non-Authoritative Information","No Content","Reset Content","Partial Content","Multi-Status","Already Reported","IM Used","Multiple Choices","Moved Permanently","Found","See Other","Not Modified","Use Proxy","","Temporary Redirect","Bad Request","Unauthorized","Payment Required","Forbidden","Not Found","Method Not Allowed","Not Acceptable","Proxy Authentication Required","Request Timeout","Conflict","Gone","Length Required","Precondition Failed","Request Entity Too Large","Request-URI Too Long","Unsupported Media Type","Requested Range Not Satisfiable","Expectation Failed","","","Unprocessable Entity","Locked","Failed Dependency","","Upgrade Required","Internal Server Error","Not Implemented","Bad Gateway","Service Unavailable","Gateway Timeout","HTTP Version Not Supported","Variant Also Negotiates","Insufficient Storage","Loop Detected","Not Extended"
27
12
  };
28
13
  static VALUE default_env;
29
-
30
- typedef struct
31
- {
32
- struct event_base* base;
33
- struct evhttp* http;
34
- struct event signal;
35
- VALUE app;
36
- VALUE options;
37
- VALUE env;
38
- } Aspirin_Server;
39
-
40
- // Aspirin::Server.new
41
- static VALUE aspirin_server_initialize(VALUE, VALUE, VALUE);
42
- // Aspirin::Server.start
43
- static VALUE aspirin_server_start(VALUE);
44
- // Rack::Handler::Aspirin.run
45
- static VALUE rack_handler_aspirin_run(int, VALUE*, VALUE);
46
-
47
- static VALUE aspirin_server_address(VALUE);
48
- static int aspirin_server_port(VALUE);
49
-
50
- static VALUE aspirin_server_alloc(VALUE);
51
- static void aspirin_server_mark(Aspirin_Server*);
52
- static void aspirin_server_free(Aspirin_Server*);
53
-
54
- static void aspirin_server_http_request(struct evhttp_request*, void*);
55
- static VALUE aspirin_server_create_env(struct evhttp_request*, Aspirin_Server*);
56
-
57
- static void aspirin_server_base_initialize(Aspirin_Server*);
58
- static void aspirin_server_signal_initialize(Aspirin_Server*);
59
- static void aspirin_server_sigint(int, short, void*);
60
- static void aspirin_server_http_initialize(Aspirin_Server*);
61
-
62
- static void set_http_version(VALUE, struct evhttp_request*);
63
- static void set_path_info(VALUE, struct evhttp_request*);
64
- static void set_response_header(struct evhttp_request*, VALUE);
65
- static void set_additional_header(struct evhttp_request*);
66
-
67
- static void init_default_env();
68
- static VALUE dupe_default_env();
69
- static void init_status_code_tbl();
70
- static char* get_status_code_message(int);
71
-
72
- static char* upcase(char*);
73
- static char* hyphen_to_under(char*);
14
+ static VALUE global_envs[GLOBAL_ENVS_NUM];
74
15
 
75
16
  static void
76
17
  init_default_env()
77
18
  {
78
- VALUE rack_url_scheme, rack_version, gateway_interface, server_protocol, script_name;
79
-
80
- rack_url_scheme = rb_str_new2("http");
81
- rack_version = rb_ary_new3(2, INT2FIX(1), INT2FIX(1));
82
- gateway_interface = rb_str_new2("CGI/1.2");
83
- server_protocol = rb_str_new2("HTTP/1.1");
84
- script_name = rb_str_new2("");
85
-
86
- OBJ_FREEZE(rack_url_scheme);
87
- OBJ_FREEZE(rack_version);
88
- OBJ_FREEZE(gateway_interface);
89
- OBJ_FREEZE(server_protocol);
90
- OBJ_FREEZE(script_name);
91
-
92
19
  default_env = rb_hash_new();
93
20
 
94
21
  rb_hash_aset(default_env, rb_str_new2("rack.multiprocess"), Qfalse);
95
22
  rb_hash_aset(default_env, rb_str_new2("rack.multithread"), Qfalse);
96
23
  rb_hash_aset(default_env, rb_str_new2("rack.run_once"), Qfalse);
97
- rb_hash_aset(default_env, rb_str_new2("rack.url_scheme"), rack_url_scheme);
98
- rb_hash_aset(default_env, rb_str_new2("rack.version"), rack_version);
99
- rb_hash_aset(default_env, rb_str_new2("GATEWAY_INTERFACE"), gateway_interface);
100
- rb_hash_aset(default_env, rb_str_new2("SCRIPT_NAME"), script_name);
101
- rb_hash_aset(default_env, rb_str_new2("SERVER_PROTOCOL"), server_protocol);
24
+ rb_hash_aset(default_env, rb_str_new2("rack.url_scheme"), rb_obj_freeze(rb_str_new2("http")));
25
+ rb_hash_aset(default_env, rb_str_new2("rack.version"), rb_obj_freeze(rb_ary_new3(2, INT2FIX(1), INT2FIX(1))));
26
+ rb_hash_aset(default_env, rb_str_new2("GATEWAY_INTERFACE"), rb_obj_freeze(rb_str_new2("CGI/1.2")));
27
+ rb_hash_aset(default_env, rb_str_new2("SCRIPT_NAME"), rb_obj_freeze(rb_str_new2("")));
28
+ rb_hash_aset(default_env, rb_str_new2("SERVER_PROTOCOL"), rb_obj_freeze(rb_str_new2("HTTP/1.1")));
102
29
  }
103
30
 
104
31
  static VALUE
@@ -107,6 +34,30 @@ dupe_default_env()
107
34
  return rb_funcall(default_env, rb_intern("dup"), 0);
108
35
  }
109
36
 
37
+ static void
38
+ init_global_envs()
39
+ {
40
+ int i;
41
+ global_envs[GE_GET ] = rb_str_new2("GET");
42
+ global_envs[GE_HEAD ] = rb_str_new2("HEAD");
43
+ global_envs[GE_HTTP_VERSION ] = rb_str_new2("HTTP_VERSION");
44
+ global_envs[GE_PATH_INFO ] = rb_str_new2("PATH_INFO");
45
+ global_envs[GE_POST ] = rb_str_new2("POST");
46
+ global_envs[GE_QUERY_STRING ] = rb_str_new2("QUERY_STRING");
47
+ global_envs[GE_RACK_ERRORS ] = rb_str_new2("rack.errors");
48
+ global_envs[GE_RACK_INPUT ] = rb_str_new2("rack.input");
49
+ global_envs[GE_REMOTE_ADDR ] = rb_str_new2("REMOTE_ADDR");
50
+ global_envs[GE_REQUEST_METHOD] = rb_str_new2("REQUEST_METHOD");
51
+ global_envs[GE_REQUEST_PATH ] = rb_str_new2("REQUEST_PATH");
52
+ global_envs[GE_REQUEST_URI ] = rb_str_new2("REQUEST_URI");
53
+ global_envs[GE_SERVER_NAME ] = rb_str_new2("SERVER_NAME");
54
+ global_envs[GE_SERVER_PORT ] = rb_str_new2("SERVER_PORT");
55
+ for(i=0; i<GLOBAL_ENVS_NUM; i++)
56
+ {
57
+ global_envs[i] = rb_obj_freeze(global_envs[i]);
58
+ }
59
+ }
60
+
110
61
  static void
111
62
  init_status_code_tbl()
112
63
  {
@@ -131,7 +82,7 @@ set_http_version(VALUE env, struct evhttp_request *req)
131
82
  {
132
83
  char buf[8 + 1]; // HTTP/x.y
133
84
  snprintf(buf, 9, "HTTP/%d.%d", req->major, req->minor);
134
- rb_hash_aset(env, rb_str_new2("HTTP_VERSION"), rb_str_new2(buf));
85
+ rb_hash_aset(env, global_envs[GE_HTTP_VERSION], rb_obj_freeze(rb_str_new2(buf)));
135
86
  }
136
87
 
137
88
  static void
@@ -157,12 +108,12 @@ set_path_info(VALUE env, struct evhttp_request *req)
157
108
  request_uri = rb_str_new2(buf);
158
109
  query_string = rb_str_new2(query);
159
110
 
160
- OBJ_FREEZE(request_uri);
161
- OBJ_FREEZE(query_string);
111
+ rb_obj_freeze(request_uri);
112
+ rb_obj_freeze(query_string);
162
113
 
163
- rb_hash_aset(env, rb_str_new2("PATH_INFO"), request_uri);
164
- rb_hash_aset(env, rb_str_new2("REQUEST_PATH"), request_uri);
165
- rb_hash_aset(env, rb_str_new2("QUERY_STRING"), query_string);
114
+ rb_hash_aset(env, global_envs[GE_PATH_INFO], request_uri);
115
+ rb_hash_aset(env, global_envs[GE_REQUEST_PATH], request_uri);
116
+ rb_hash_aset(env, global_envs[GE_QUERY_STRING], query_string);
166
117
 
167
118
  xfree(buf);
168
119
  }
@@ -173,7 +124,6 @@ set_http_header(VALUE env, struct evhttp_request *req)
173
124
  char *buf;
174
125
  size_t len;
175
126
  struct evkeyval *header;
176
- VALUE key, val;
177
127
 
178
128
  TAILQ_FOREACH(header, req->input_headers, next)
179
129
  {
@@ -187,10 +137,7 @@ set_http_header(VALUE env, struct evhttp_request *req)
187
137
  buf[len + 5] = '\0';
188
138
  hyphen_to_under(upcase(buf));
189
139
 
190
- key = rb_str_new2(buf);
191
- val = rb_str_new2(header->value);
192
- OBJ_FREEZE(val);
193
- rb_hash_aset(env, key, val);
140
+ rb_hash_aset(env, rb_str_new2(buf), rb_obj_freeze(rb_str_new2(header->value)));
194
141
 
195
142
  xfree(buf);
196
143
  }
@@ -200,37 +147,36 @@ set_http_header(VALUE env, struct evhttp_request *req)
200
147
  static VALUE
201
148
  aspirin_server_create_env(struct evhttp_request *req, Aspirin_Server *srv)
202
149
  {
203
- VALUE env, rack_input, strio, remote_host, request_uri, method;
150
+ VALUE env, rack_input, strio, remote_host, request_uri;
204
151
 
205
152
  env = rb_funcall(srv->env, rb_intern("dup"), 0);
206
153
 
207
- rb_hash_aset(env, rb_str_new2("rack.errors"), rb_gv_get("$stderr"));
154
+ rb_hash_aset(env, global_envs[GE_RACK_ERRORS], rb_gv_get("$stderr"));
208
155
 
209
156
  rack_input = rb_str_new((const char*)EVBUFFER_DATA(req->input_buffer),
210
157
  EVBUFFER_LENGTH(req->input_buffer));
211
- OBJ_FREEZE(rack_input);
158
+ rb_obj_freeze(rack_input);
212
159
  strio = rb_funcall(rb_cStringIO, rb_intern("new"), 1, rack_input);
213
- rb_hash_aset(env, rb_str_new2("rack.input"), strio);
160
+ rb_hash_aset(env, global_envs[GE_RACK_INPUT], strio);
214
161
 
215
- remote_host = rb_str_new2(req->remote_host);
216
- OBJ_FREEZE(remote_host);
217
- rb_hash_aset(env, rb_str_new2("REMOTE_ADDR"), remote_host);
162
+ rb_hash_aset(env,
163
+ global_envs[GE_REMOTE_ADDR],
164
+ rb_obj_freeze(rb_str_new2(req->remote_host)));
218
165
 
219
- request_uri = rb_str_new2(evhttp_request_uri(req));
220
- OBJ_FREEZE(request_uri);
221
- rb_hash_aset(env, rb_str_new2("REQUEST_URI"), request_uri);
166
+ rb_hash_aset(env,
167
+ global_envs[GE_REQUEST_URI],
168
+ rb_obj_freeze(rb_str_new2(evhttp_request_uri(req))));
222
169
 
223
- method = rb_str_new2("REQUEST_METHOD");
224
170
  switch(req->type)
225
171
  {
226
172
  case EVHTTP_REQ_GET:
227
- rb_hash_aset(env, method, rb_str_new2("GET"));
173
+ rb_hash_aset(env, global_envs[GE_REQUEST_METHOD], global_envs[GE_GET]);
228
174
  break;
229
175
  case EVHTTP_REQ_POST:
230
- rb_hash_aset(env, method, rb_str_new2("POST"));
176
+ rb_hash_aset(env, global_envs[GE_REQUEST_METHOD], global_envs[GE_POST]);
231
177
  break;
232
178
  case EVHTTP_REQ_HEAD:
233
- rb_hash_aset(env, method, rb_str_new2("HEAD"));
179
+ rb_hash_aset(env, global_envs[GE_REQUEST_METHOD], global_envs[GE_HEAD]);
234
180
  break;
235
181
  }
236
182
 
@@ -271,13 +217,39 @@ set_additional_header(struct evhttp_request *req)
271
217
  evhttp_add_header(req->output_headers, "Connection", "close");
272
218
  }
273
219
 
220
+ static VALUE
221
+ body_concat(VALUE chunk, VALUE* buff)
222
+ {
223
+ struct evbuffer *buf = DATA_PTR(*buff);
224
+ StringValue(chunk);
225
+ evbuffer_add(buf, RSTRING_PTR(chunk), RSTRING_LEN(chunk));
226
+ return Qnil;
227
+ }
228
+
229
+ static VALUE
230
+ body_each(VALUE body)
231
+ {
232
+ VALUE data = rb_ary_entry(body, 1);
233
+ rb_iterate(rb_each, rb_ary_entry(body, 0), body_concat, (VALUE)&data);
234
+ return Qnil;
235
+ }
236
+
237
+ static VALUE
238
+ body_close(VALUE body)
239
+ {
240
+ if(rb_respond_to(body, rb_intern("close")))
241
+ {
242
+ rb_funcall(body, rb_intern("close"), 0);
243
+ }
244
+ return Qnil;
245
+ }
246
+
274
247
  static void
275
248
  aspirin_server_http_request(struct evhttp_request *req, void *arg)
276
249
  {
277
- static VALUE args[][1] = {{INT2FIX(0)},{INT2FIX(1)},{INT2FIX(2)}};
278
250
  struct evbuffer *buf;
279
251
  Aspirin_Server *srv;
280
- VALUE env, result, bodies;
252
+ VALUE env, result, body, buff;
281
253
  int status_code;
282
254
  char *status_code_msg;
283
255
 
@@ -285,22 +257,25 @@ aspirin_server_http_request(struct evhttp_request *req, void *arg)
285
257
  env = aspirin_server_create_env(req, srv);
286
258
  result = rb_funcall(srv->app, rb_intern("call"), 1, env);
287
259
 
288
- status_code = NUM2INT(rb_ary_aref(1, args[0], result));
260
+ status_code = NUM2INT(rb_ary_entry(result, 0));
289
261
  status_code_msg = get_status_code_message(status_code);
290
262
  if(status_code_msg == NULL)
291
263
  {
292
264
  status_code_msg = "";
293
265
  }
294
266
 
295
- set_response_header(req, rb_ary_aref(1, args[1], result));
267
+ set_response_header(req, rb_ary_entry(result, 1));
296
268
  set_additional_header(req);
297
269
 
298
- bodies = rb_funcall(rb_ary_aref(1, args[2], result), rb_intern("to_s"), 0);
270
+ buff = Data_Wrap_Struct(rb_cData, 0, 0, 0);
271
+ DATA_PTR(buff) = req->output_buffer;
272
+
273
+ body = rb_ary_new3(2, rb_ary_entry(result, 2), buff);
274
+
275
+ rb_ensure(body_each, body, body_close, rb_ary_entry(result, 2));
276
+ evhttp_send_reply(req, status_code, status_code_msg, NULL);
299
277
 
300
- buf = evbuffer_new();
301
- evbuffer_add(buf, RSTRING_PTR(bodies), RSTRING_LEN(bodies));
302
- evhttp_send_reply(req, status_code, status_code_msg, buf);
303
- evbuffer_free(buf);
278
+ DATA_PTR(buff) = NULL;
304
279
  }
305
280
 
306
281
  static Aspirin_Server*
@@ -368,7 +343,9 @@ aspirin_server_free(Aspirin_Server* srv)
368
343
  return;
369
344
  }
370
345
 
371
- event_del(&srv->signal);
346
+ event_del(&srv->sig_int);
347
+ event_del(&srv->sig_quit);
348
+ event_del(&srv->sig_term);
372
349
 
373
350
  if(srv->http)
374
351
  {
@@ -393,11 +370,18 @@ aspirin_server_alloc(VALUE klass)
393
370
  }
394
371
 
395
372
  static void
396
- aspirin_server_sigint(int fd, short event, void *arg)
373
+ aspirin_server_stop_bang(int fd, short event, void *arg)
374
+ {
375
+ Aspirin_Server *srv = arg;
376
+ event_base_loopbreak(srv->base);
377
+ }
378
+
379
+ static void
380
+ aspirin_server_stop(int fd, short event, void *arg)
397
381
  {
398
382
  Aspirin_Server *srv = arg;
399
383
  struct timeval delay = {1, 0};
400
- event_del(&srv->signal);
384
+ event_del(&srv->sig_quit);
401
385
  event_base_loopexit(srv->base, &delay);
402
386
  }
403
387
 
@@ -407,61 +391,21 @@ aspirin_server_port(VALUE options)
407
391
  VALUE port = Qnil;
408
392
  if(TYPE(options) == T_HASH)
409
393
  {
410
- port = rb_hash_aref(options, ID2SYM(rb_intern("port")));
411
- if(!NIL_P(port)){
412
- return NUM2INT(port);
413
- }
414
- port = rb_hash_aref(options, rb_str_new2("port"));
415
- if(!NIL_P(port)){
416
- return NUM2INT(port);
417
- }
418
394
  port = rb_hash_aref(options, ID2SYM(rb_intern("Port")));
419
395
  if(!NIL_P(port)){
420
396
  return NUM2INT(port);
421
397
  }
422
- port = rb_hash_aref(options, rb_str_new2("Port"));
423
- if(!NIL_P(port)){
424
- return NUM2INT(port);
425
- }
426
- port = rb_hash_aref(options, ID2SYM(rb_intern("PORT")));
427
- if(!NIL_P(port)){
428
- return NUM2INT(port);
429
- }
430
- port = rb_hash_aref(options, rb_str_new2("PORT"));
431
- if(!NIL_P(port)){
432
- return NUM2INT(port);
433
- }
434
398
  }
435
399
  return 9292;
436
400
  }
437
401
 
438
402
  static VALUE
439
- aspirin_server_address(VALUE options)
403
+ aspirin_server_host(VALUE options)
440
404
  {
441
405
  VALUE address = Qnil;
442
406
  if(TYPE(options) == T_HASH)
443
407
  {
444
- address = rb_hash_aref(options, ID2SYM(rb_intern("address")));
445
- if(!NIL_P(address)){
446
- return address;
447
- }
448
- address = rb_hash_aref(options, rb_str_new2("address"));
449
- if(!NIL_P(address)){
450
- return address;
451
- }
452
- address = rb_hash_aref(options, ID2SYM(rb_intern("Address")));
453
- if(!NIL_P(address)){
454
- return address;
455
- }
456
- address = rb_hash_aref(options, rb_str_new2("Address"));
457
- if(!NIL_P(address)){
458
- return address;
459
- }
460
- address = rb_hash_aref(options, ID2SYM(rb_intern("ADDRESS")));
461
- if(!NIL_P(address)){
462
- return address;
463
- }
464
- address = rb_hash_aref(options, rb_str_new2("ADDRESS"));
408
+ address = rb_hash_aref(options, ID2SYM(rb_intern("Host")));
465
409
  if(!NIL_P(address)){
466
410
  return address;
467
411
  }
@@ -478,26 +422,34 @@ aspirin_server_base_initialize(Aspirin_Server *srv)
478
422
  static void
479
423
  aspirin_server_signal_initialize(Aspirin_Server *srv)
480
424
  {
481
- event_set(&srv->signal, SIGINT, EV_SIGNAL|EV_PERSIST, aspirin_server_sigint, srv);
482
- event_base_set(srv->base, &srv->signal);
483
- event_add(&srv->signal, NULL);
425
+ event_set(&srv->sig_quit, SIGQUIT, EV_SIGNAL|EV_PERSIST, aspirin_server_stop, srv);
426
+ event_base_set(srv->base, &srv->sig_quit);
427
+ event_add(&srv->sig_quit, NULL);
428
+
429
+ event_set(&srv->sig_int, SIGINT, EV_SIGNAL|EV_PERSIST, aspirin_server_stop_bang, srv);
430
+ event_base_set(srv->base, &srv->sig_int);
431
+ event_add(&srv->sig_int, NULL);
432
+
433
+ event_set(&srv->sig_term, SIGTERM, EV_SIGNAL|EV_PERSIST, aspirin_server_stop_bang, srv);
434
+ event_base_set(srv->base, &srv->sig_term);
435
+ event_add(&srv->sig_term, NULL);
484
436
  }
485
437
 
486
438
  static void
487
439
  aspirin_server_http_initialize(Aspirin_Server *srv)
488
440
  {
489
- VALUE addr = aspirin_server_address(srv->options);
441
+ VALUE host = aspirin_server_host(srv->options);
490
442
  int port = aspirin_server_port(srv->options);
491
443
 
492
- StringValue(addr);
493
- rb_hash_aset(srv->env, rb_str_new2("SERVER_NAME"), addr);
444
+ StringValue(host);
445
+ rb_hash_aset(srv->env, global_envs[GE_SERVER_NAME], host);
494
446
 
495
447
  char port_str[6];
496
448
  snprintf(port_str, 5, "%d", port);
497
- rb_hash_aset(srv->env, rb_str_new2("SERVER_PORT"), rb_str_new2(port_str));
449
+ rb_hash_aset(srv->env, global_envs[GE_SERVER_PORT], rb_str_new2(port_str));
498
450
 
499
451
  srv->http = evhttp_new(srv->base);
500
- evhttp_bind_socket(srv->http, RSTRING_PTR(addr), port);
452
+ evhttp_bind_socket(srv->http, RSTRING_PTR(host), port);
501
453
  evhttp_set_gencb(srv->http, aspirin_server_http_request, srv);
502
454
  }
503
455
 
@@ -505,10 +457,10 @@ static char*
505
457
  upcase(char* str)
506
458
  {
507
459
  if(str){
508
- int i, n=strlen(str);
509
- for(i=0; i<n; i++)
460
+ char* tmp;
461
+ for(tmp=str; *tmp; tmp++)
510
462
  {
511
- str[i] = toupper(str[i]);
463
+ *tmp = toupper(*tmp);
512
464
  }
513
465
  }
514
466
  return str;
@@ -518,12 +470,12 @@ static char*
518
470
  hyphen_to_under(char* str)
519
471
  {
520
472
  if(str){
521
- int i, n=strlen(str);
522
- for(i=0; i<n; i++)
473
+ char* tmp;
474
+ for(tmp=str; *tmp; tmp++)
523
475
  {
524
- if(str[i] == '-')
476
+ if(*tmp == '-')
525
477
  {
526
- str[i] = '_';
478
+ *tmp = '_';
527
479
  }
528
480
  }
529
481
  }
@@ -544,8 +496,11 @@ rack_handler_aspirin_run(int argc, VALUE *argv, VALUE obj)
544
496
 
545
497
  void Init_aspirin(void)
546
498
  {
499
+ VALUE rb_mRack, rb_mRack_Handler, rb_mRack_Handler_Aspirin;
500
+
547
501
  init_default_env();
548
502
  init_status_code_tbl();
503
+ init_global_envs();
549
504
 
550
505
  rb_require("stringio");
551
506
  rb_cStringIO = rb_const_get(rb_cObject, rb_intern("StringIO"));
@@ -559,8 +514,8 @@ void Init_aspirin(void)
559
514
  rb_define_method(rb_cAspirin_Server, "start", aspirin_server_start, 0);
560
515
 
561
516
  // Rack::Handler::Aspirin
562
- VALUE rb_mRack = rb_define_module("Rack");
563
- VALUE rb_mRack_Handler = rb_define_module_under(rb_mRack, "Handler");
564
- VALUE rb_mRack_Handler_Aspirin = rb_define_module_under(rb_mRack_Handler, "Aspirin");
517
+ rb_mRack = rb_define_module("Rack");
518
+ rb_mRack_Handler = rb_define_module_under(rb_mRack, "Handler");
519
+ rb_mRack_Handler_Aspirin = rb_define_module_under(rb_mRack_Handler, "Aspirin");
565
520
  rb_define_singleton_method(rb_mRack_Handler_Aspirin, "run", rack_handler_aspirin_run, -1);
566
521
  }
@@ -0,0 +1,87 @@
1
+ #ifndef __ASPIRIN_H__
2
+ #define __ASPIRIN_H__
3
+
4
+ #include <ruby.h>
5
+ #ifdef HAVE_RUBY_ST_H
6
+ #include <ruby/st.h>
7
+ #else
8
+ #include <st.h>
9
+ #endif
10
+
11
+ #include <ctype.h>
12
+ #include <signal.h>
13
+ #include <stdio.h>
14
+ #include <sys/queue.h>
15
+
16
+ #include <event.h>
17
+ #include <evhttp.h>
18
+ #include <evutil.h>
19
+
20
+ #define INSPECT(obj) {VALUE __obj__ = rb_inspect((obj)); fprintf(stderr, "%d:%s\n", __LINE__, RSTRING_PTR(__obj__));}
21
+
22
+ enum{
23
+ GE_GET,
24
+ GE_HEAD,
25
+ GE_HTTP_VERSION,
26
+ GE_PATH_INFO,
27
+ GE_POST,
28
+ GE_QUERY_STRING,
29
+ GE_RACK_ERRORS,
30
+ GE_RACK_INPUT,
31
+ GE_REMOTE_ADDR,
32
+ GE_REQUEST_METHOD,
33
+ GE_REQUEST_PATH,
34
+ GE_REQUEST_URI,
35
+ GE_SERVER_NAME,
36
+ GE_SERVER_PORT,
37
+ GLOBAL_ENVS_NUM,
38
+ };
39
+
40
+ typedef struct
41
+ {
42
+ struct event_base* base;
43
+ struct evhttp* http;
44
+ struct event sig_int;
45
+ struct event sig_quit;
46
+ struct event sig_term;
47
+ VALUE app;
48
+ VALUE options;
49
+ VALUE env;
50
+ } Aspirin_Server;
51
+
52
+ // Aspirin::Server.new
53
+ static VALUE aspirin_server_initialize(VALUE, VALUE, VALUE);
54
+ // Aspirin::Server#start
55
+ static VALUE aspirin_server_start(VALUE);
56
+ // Rack::Handler::Aspirin.run
57
+ static VALUE rack_handler_aspirin_run(int, VALUE*, VALUE);
58
+
59
+ static VALUE aspirin_server_address(VALUE);
60
+ static int aspirin_server_port(VALUE);
61
+
62
+ static VALUE aspirin_server_alloc(VALUE);
63
+ static void aspirin_server_mark(Aspirin_Server*);
64
+ static void aspirin_server_free(Aspirin_Server*);
65
+
66
+ static void aspirin_server_http_request(struct evhttp_request*, void*);
67
+ static VALUE aspirin_server_create_env(struct evhttp_request*, Aspirin_Server*);
68
+
69
+ static void aspirin_server_base_initialize(Aspirin_Server*);
70
+ static void aspirin_server_signal_initialize(Aspirin_Server*);
71
+ static void aspirin_server_stop(int, short, void*);
72
+ static void aspirin_server_stop_bang(int, short, void*);
73
+ static void aspirin_server_http_initialize(Aspirin_Server*);
74
+
75
+ static void set_http_version(VALUE, struct evhttp_request*);
76
+ static void set_path_info(VALUE, struct evhttp_request*);
77
+ static void set_response_header(struct evhttp_request*, VALUE);
78
+ static void set_additional_header(struct evhttp_request*);
79
+
80
+ static void init_default_env();
81
+ static VALUE dupe_default_env();
82
+ static void init_status_code_tbl();
83
+ static char* get_status_code_message(int);
84
+
85
+ static char* upcase(char*);
86
+ static char* hyphen_to_under(char*);
87
+ #endif
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 0
9
- version: 0.0.0
8
+ - 1
9
+ version: 0.0.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - fistfvck
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-29 00:00:00 +09:00
17
+ date: 2010-06-30 00:00:00 +09:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -51,6 +51,7 @@ files:
51
51
  - example/test.rb
52
52
  - example/thn.rb
53
53
  - ext/aspirin.c
54
+ - ext/aspirin.h
54
55
  - ext/extconf.rb
55
56
  - spec/aspirin_spec.rb
56
57
  - spec/spec.opts