aspirin 0.0.0 → 0.0.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.
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