The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.
Please select the desired protocol below to get the URL.
This URL has Read-Only access.
main_repo / src / http.cc @ 90fc8d36
History | View | Annotate | Download (17.4 KB)
1 |
#include "node.h" |
---|---|
2 |
#include "http.h" |
3 |
|
4 |
#include <oi_socket.h> |
5 |
#include <ebb_request_parser.h> |
6 |
|
7 |
#include <string> |
8 |
#include <list> |
9 |
|
10 |
#include <assert.h> |
11 |
|
12 |
using namespace v8; |
13 |
using namespace std; |
14 |
|
15 |
static Persistent<ObjectTemplate> request_template;
|
16 |
|
17 |
// globals
|
18 |
static Persistent<String> path_str;
|
19 |
static Persistent<String> uri_str;
|
20 |
static Persistent<String> query_string_str;
|
21 |
static Persistent<String> fragment_str;
|
22 |
static Persistent<String> method_str;
|
23 |
static Persistent<String> http_version_str;
|
24 |
static Persistent<String> headers_str;
|
25 |
|
26 |
static Persistent<String> on_request_str;
|
27 |
static Persistent<String> on_body_str;
|
28 |
static Persistent<String> respond_str;
|
29 |
|
30 |
static Persistent<String> copy_str;
|
31 |
static Persistent<String> delete_str;
|
32 |
static Persistent<String> get_str;
|
33 |
static Persistent<String> head_str;
|
34 |
static Persistent<String> lock_str;
|
35 |
static Persistent<String> mkcol_str;
|
36 |
static Persistent<String> move_str;
|
37 |
static Persistent<String> options_str;
|
38 |
static Persistent<String> post_str;
|
39 |
static Persistent<String> propfind_str;
|
40 |
static Persistent<String> proppatch_str;
|
41 |
static Persistent<String> put_str;
|
42 |
static Persistent<String> trace_str;
|
43 |
static Persistent<String> unlock_str;
|
44 |
|
45 |
#define INVALID_STATE_ERR 1 |
46 |
|
47 |
class HttpServer { |
48 |
public:
|
49 |
HttpServer (Handle<Object> _js_server); |
50 |
~HttpServer (); |
51 |
|
52 |
int Start(struct addrinfo *servinfo); |
53 |
void Stop();
|
54 |
|
55 |
Handle<Value> Callback() |
56 |
{ |
57 |
HandleScope scope; |
58 |
Handle<Value> value = js_server->Get(on_request_str); |
59 |
return scope.Close(value);
|
60 |
} |
61 |
|
62 |
private:
|
63 |
oi_server server; |
64 |
Persistent<Object> js_server; |
65 |
}; |
66 |
|
67 |
class HttpRequest; |
68 |
|
69 |
class Connection { |
70 |
public:
|
71 |
Connection(); |
72 |
~Connection(); |
73 |
|
74 |
void Parse(const void *buf, size_t count); |
75 |
void Write();
|
76 |
void Close();
|
77 |
void AddRequest (HttpRequest *request);
|
78 |
|
79 |
oi_socket socket; |
80 |
Persistent<Function> js_onrequest; |
81 |
|
82 |
private:
|
83 |
ebb_request_parser parser; |
84 |
list<HttpRequest*> requests; |
85 |
list<HttpRequest*> finished_requests; |
86 |
friend class HttpServer; |
87 |
}; |
88 |
|
89 |
class HttpRequest { |
90 |
public:
|
91 |
HttpRequest (Connection &c); |
92 |
/* Deleted from C++ as soon as possible.
|
93 |
* Javascript object might linger. This is okay
|
94 |
*/
|
95 |
~HttpRequest(); |
96 |
|
97 |
void MakeBodyCallback (const char *base, size_t length); |
98 |
Local<Object> CreateJSObject (); |
99 |
void Respond (Handle<Value> data);
|
100 |
|
101 |
string path;
|
102 |
string query_string;
|
103 |
string fragment;
|
104 |
string uri;
|
105 |
|
106 |
list<string> header_fields;
|
107 |
list<string> header_values;
|
108 |
|
109 |
Connection &connection; |
110 |
ebb_request parser_info; |
111 |
|
112 |
list<oi_buf*> output; |
113 |
bool done;
|
114 |
Persistent<Object> js_object; |
115 |
}; |
116 |
|
117 |
static Handle<Value>
|
118 |
GetMethodString (int method)
|
119 |
{ |
120 |
switch(method) {
|
121 |
case EBB_COPY: return copy_str; |
122 |
case EBB_DELETE: return delete_str; |
123 |
case EBB_GET: return get_str; |
124 |
case EBB_HEAD: return head_str; |
125 |
case EBB_LOCK: return lock_str; |
126 |
case EBB_MKCOL: return mkcol_str; |
127 |
case EBB_MOVE: return move_str; |
128 |
case EBB_OPTIONS: return options_str; |
129 |
case EBB_POST: return post_str; |
130 |
case EBB_PROPFIND: return propfind_str; |
131 |
case EBB_PROPPATCH: return proppatch_str; |
132 |
case EBB_PUT: return put_str; |
133 |
case EBB_TRACE: return trace_str; |
134 |
case EBB_UNLOCK: return unlock_str; |
135 |
} |
136 |
return Null();
|
137 |
} |
138 |
|
139 |
static Handle<Value>
|
140 |
RespondCallback (const Arguments& args)
|
141 |
{ |
142 |
HandleScope scope; |
143 |
|
144 |
Handle<Value> v = args.Holder()->GetInternalField(0);
|
145 |
if(v->IsUndefined()) {
|
146 |
// check that args.Holder()->GetInternalField(0)
|
147 |
// is not NULL if so raise INVALID_STATE_ERR
|
148 |
printf("null request external\n");
|
149 |
ThrowException(Integer::New(INVALID_STATE_ERR)); |
150 |
return Undefined();
|
151 |
} |
152 |
Handle<External> field = Handle<External>::Cast(v); |
153 |
HttpRequest* request = static_cast<HttpRequest*>(field->Value());
|
154 |
request->Respond(args[0]);
|
155 |
return Undefined();
|
156 |
} |
157 |
|
158 |
void
|
159 |
HttpRequest::Respond (Handle<Value> data) |
160 |
{ |
161 |
if(data == Null()) {
|
162 |
done = true;
|
163 |
} else {
|
164 |
Handle<String> s = data->ToString(); |
165 |
|
166 |
size_t l1 = s->Utf8Length(), l2; |
167 |
oi_buf *buf = oi_buf_new2(l1); |
168 |
l2 = s->WriteUtf8(buf->base, l1); |
169 |
assert(l1 == l2); |
170 |
|
171 |
output.push_back(buf); |
172 |
} |
173 |
connection.Write(); |
174 |
} |
175 |
|
176 |
|
177 |
static void |
178 |
on_path (ebb_request *req, const char *buf, size_t len) |
179 |
{ |
180 |
HttpRequest *request = static_cast<HttpRequest*> (req->data);
|
181 |
request->path.append(buf, len); |
182 |
} |
183 |
|
184 |
static void |
185 |
on_uri (ebb_request *req, const char *buf, size_t len) |
186 |
{ |
187 |
HttpRequest *request = static_cast<HttpRequest*> (req->data);
|
188 |
request->uri.append(buf, len); |
189 |
} |
190 |
|
191 |
static void |
192 |
on_query_string (ebb_request *req, const char *buf, size_t len) |
193 |
{ |
194 |
HttpRequest *request = static_cast<HttpRequest*> (req->data);
|
195 |
request->query_string.append(buf, len); |
196 |
} |
197 |
|
198 |
static void |
199 |
on_fragment (ebb_request *req, const char *buf, size_t len) |
200 |
{ |
201 |
HttpRequest *request = static_cast<HttpRequest*> (req->data);
|
202 |
request->fragment.append(buf, len); |
203 |
} |
204 |
|
205 |
static const char upcase[] = |
206 |
"\0______________________________"
|
207 |
"_________________0123456789_____"
|
208 |
"__ABCDEFGHIJKLMNOPQRSTUVWXYZ____"
|
209 |
"__ABCDEFGHIJKLMNOPQRSTUVWXYZ____"
|
210 |
"________________________________"
|
211 |
"________________________________"
|
212 |
"________________________________"
|
213 |
"________________________________";
|
214 |
|
215 |
static void |
216 |
on_header_field (ebb_request *req, const char *buf, size_t len, int header_index) |
217 |
{ |
218 |
HttpRequest *request = static_cast<HttpRequest*> (req->data);
|
219 |
|
220 |
char upbuf[len];
|
221 |
|
222 |
for(int i = 0; i < len; i++) |
223 |
upbuf[i] = upcase[buf[i]]; |
224 |
|
225 |
if( request->header_fields.size() == header_index - 1) { |
226 |
request->header_fields.back().append(upbuf, len); |
227 |
} else {
|
228 |
request->header_fields.push_back( string(upbuf, len) );
|
229 |
} |
230 |
} |
231 |
|
232 |
static void |
233 |
on_header_value (ebb_request *req, const char *buf, size_t len, int header_index) |
234 |
{ |
235 |
HttpRequest *request = static_cast<HttpRequest*> (req->data);
|
236 |
|
237 |
if( request->header_values.size() == header_index - 1) { |
238 |
request->header_values.back().append(buf, len); |
239 |
} else {
|
240 |
request->header_values.push_back( string(buf, len) );
|
241 |
} |
242 |
} |
243 |
|
244 |
static void |
245 |
on_headers_complete (ebb_request *req) |
246 |
{ |
247 |
HttpRequest *request = static_cast<HttpRequest*> (req->data);
|
248 |
|
249 |
HandleScope scope; |
250 |
|
251 |
Handle<Object> js_request = request->CreateJSObject(); |
252 |
|
253 |
// Set up an exception handler before calling the Process function
|
254 |
TryCatch try_catch; |
255 |
|
256 |
// Invoke the process function, giving the global object as 'this'
|
257 |
// and one argument, the request.
|
258 |
const int argc = 1; |
259 |
Handle<Value> argv[argc] = { js_request }; |
260 |
Handle<Value> r = request->connection.js_onrequest->Call(Context::GetCurrent()->Global(), argc, argv); |
261 |
|
262 |
if(try_catch.HasCaught())
|
263 |
node_fatal_exception(try_catch); |
264 |
} |
265 |
|
266 |
static void |
267 |
on_request_complete (ebb_request *req) |
268 |
{ |
269 |
HttpRequest *request = static_cast<HttpRequest*> (req->data);
|
270 |
request->MakeBodyCallback(NULL, 0); // EOF |
271 |
} |
272 |
|
273 |
static void |
274 |
on_body (ebb_request *req, const char *base, size_t length) |
275 |
{ |
276 |
HttpRequest *request = static_cast<HttpRequest*> (req->data);
|
277 |
|
278 |
if(length)
|
279 |
request->MakeBodyCallback(base, length); |
280 |
} |
281 |
|
282 |
static ebb_request * on_request
|
283 |
( void *data
|
284 |
) |
285 |
{ |
286 |
Connection *connection = static_cast<Connection*> (data);
|
287 |
|
288 |
HttpRequest *request = new HttpRequest(*connection);
|
289 |
connection->AddRequest(request); |
290 |
|
291 |
return &request->parser_info;
|
292 |
} |
293 |
|
294 |
static void on_read |
295 |
( oi_socket *socket |
296 |
, const void *buf |
297 |
, size_t count |
298 |
) |
299 |
{ |
300 |
Connection *connection = static_cast<Connection*> (socket->data);
|
301 |
if(count == 0) { |
302 |
connection->Close(); |
303 |
} else {
|
304 |
//write(1, buf, count);
|
305 |
connection->Parse(buf, count); |
306 |
} |
307 |
} |
308 |
|
309 |
static void on_close |
310 |
( oi_socket *socket |
311 |
) |
312 |
{ |
313 |
Connection *connection = static_cast<Connection*> (socket->data);
|
314 |
delete connection;
|
315 |
} |
316 |
|
317 |
HttpRequest::~HttpRequest () |
318 |
{ |
319 |
HandleScope scope; // needed?
|
320 |
// delete a reference c++ HttpRequest
|
321 |
js_object->SetInternalField(0, Undefined());
|
322 |
js_object->Delete(respond_str); |
323 |
// dispose of Persistent handle so that
|
324 |
// it can be GC'd normally.
|
325 |
js_object.Dispose(); |
326 |
} |
327 |
|
328 |
HttpRequest::HttpRequest (Connection &c) : connection(c) |
329 |
{ |
330 |
ebb_request_init(&parser_info); |
331 |
parser_info.on_path = on_path; |
332 |
parser_info.on_query_string = on_query_string; |
333 |
parser_info.on_uri = on_uri; |
334 |
parser_info.on_fragment = on_fragment; |
335 |
parser_info.on_header_field = on_header_field; |
336 |
parser_info.on_header_value = on_header_value; |
337 |
parser_info.on_headers_complete = on_headers_complete; |
338 |
parser_info.on_body = on_body; |
339 |
parser_info.on_complete = on_request_complete; |
340 |
parser_info.data = this;
|
341 |
|
342 |
done = false;
|
343 |
} |
344 |
|
345 |
void
|
346 |
HttpRequest::MakeBodyCallback (const char *base, size_t length) |
347 |
{ |
348 |
HandleScope handle_scope; |
349 |
|
350 |
Handle<Value> onbody_val = js_object->Get(on_body_str); |
351 |
if (!onbody_val->IsFunction()) return; |
352 |
Handle<Function> onbody = Handle<Function>::Cast(onbody_val); |
353 |
|
354 |
TryCatch try_catch; |
355 |
const int argc = 1; |
356 |
Handle<Value> argv[argc]; |
357 |
|
358 |
if(length) {
|
359 |
// TODO ByteArray?
|
360 |
//
|
361 |
|
362 |
uint16_t expanded_base[length]; |
363 |
for(int i = 0; i < length; i++) { |
364 |
expanded_base[i] = base[i]; |
365 |
} |
366 |
|
367 |
Handle<String> chunk = String::New(expanded_base, length); |
368 |
argv[0] = chunk;
|
369 |
} else {
|
370 |
argv[0] = Null();
|
371 |
} |
372 |
|
373 |
Handle<Value> result = onbody->Call(js_object, argc, argv); |
374 |
|
375 |
if(try_catch.HasCaught())
|
376 |
node_fatal_exception(try_catch); |
377 |
} |
378 |
|
379 |
Local<Object> |
380 |
HttpRequest::CreateJSObject () |
381 |
{ |
382 |
HandleScope scope; |
383 |
|
384 |
if (request_template.IsEmpty()) {
|
385 |
Handle<ObjectTemplate> raw_template = ObjectTemplate::New(); |
386 |
raw_template->SetInternalFieldCount(1);
|
387 |
raw_template->Set(respond_str, FunctionTemplate::New(RespondCallback)); |
388 |
|
389 |
request_template = Persistent<ObjectTemplate>::New(raw_template); |
390 |
} |
391 |
|
392 |
// Create an empty http request wrapper.
|
393 |
Handle<Object> result = request_template->NewInstance(); |
394 |
|
395 |
// Wrap the raw C++ pointer in an External so it can be referenced
|
396 |
// from within JavaScript.
|
397 |
Handle<External> request_ptr = External::New(this);
|
398 |
|
399 |
// Store the request pointer in the JavaScript wrapper.
|
400 |
result->SetInternalField(0, request_ptr);
|
401 |
|
402 |
result->Set ( path_str |
403 |
, String::New(path.c_str(), path.length()) |
404 |
); |
405 |
|
406 |
result->Set ( uri_str |
407 |
, String::New(uri.c_str(), uri.length()) |
408 |
); |
409 |
|
410 |
result->Set ( query_string_str |
411 |
, String::New(query_string.c_str(), query_string.length()) |
412 |
); |
413 |
|
414 |
result->Set ( fragment_str |
415 |
, String::New(fragment.c_str(), fragment.length()) |
416 |
); |
417 |
|
418 |
result->Set ( method_str |
419 |
, GetMethodString(parser_info.method) |
420 |
); |
421 |
|
422 |
char version[10]; |
423 |
snprintf ( version |
424 |
, 10 // big enough? :) |
425 |
, "%d.%d"
|
426 |
, parser_info.version_major |
427 |
, parser_info.version_minor |
428 |
); |
429 |
result->Set ( http_version_str |
430 |
, String::New(version) |
431 |
); |
432 |
|
433 |
|
434 |
Handle<Object> headers = Object::New(); |
435 |
list<string>::iterator field_iterator = header_fields.begin();
|
436 |
list<string>::iterator value_iterator = header_values.begin();
|
437 |
while( value_iterator != header_values.end() ) {
|
438 |
string &f = *field_iterator;
|
439 |
string &v = *value_iterator;
|
440 |
|
441 |
headers->Set( String::NewSymbol(f.c_str(), f.length()) |
442 |
, String::New(v.c_str(), v.length() ) |
443 |
); |
444 |
|
445 |
field_iterator++; |
446 |
value_iterator++; |
447 |
} |
448 |
result->Set(headers_str, headers); |
449 |
|
450 |
js_object = Persistent<Object>::New(result); |
451 |
// XXX does the request's js_object need a MakeWeak callback?
|
452 |
// i dont think so because at some point the connection closes
|
453 |
// and we're going to delete the request.
|
454 |
|
455 |
return scope.Close(result);
|
456 |
} |
457 |
|
458 |
|
459 |
static oi_socket*
|
460 |
on_connection (oi_server *_server, struct sockaddr *addr, socklen_t len)
|
461 |
{ |
462 |
HandleScope scope; |
463 |
|
464 |
HttpServer *server = static_cast<HttpServer*> (_server->data);
|
465 |
|
466 |
Handle<Value> callback_v = server->Callback(); |
467 |
|
468 |
if(callback_v == Undefined())
|
469 |
return NULL; |
470 |
|
471 |
Connection *connection = new Connection();
|
472 |
|
473 |
Handle<Function> f = Handle<Function>::Cast(callback_v); |
474 |
connection->js_onrequest = Persistent<Function>::New(f); |
475 |
|
476 |
return &connection->socket;
|
477 |
} |
478 |
|
479 |
Connection::Connection () |
480 |
{ |
481 |
oi_socket_init (&socket, 30.0); // TODO make timeout adjustable |
482 |
socket.on_read = on_read; |
483 |
socket.on_error = NULL;
|
484 |
socket.on_close = on_close; |
485 |
socket.on_timeout = NULL;
|
486 |
socket.on_drain = NULL;
|
487 |
socket.data = this;
|
488 |
|
489 |
ebb_request_parser_init (&parser); |
490 |
parser.new_request = on_request; |
491 |
parser.data = this;
|
492 |
} |
493 |
|
494 |
Connection::~Connection () |
495 |
{ |
496 |
list<HttpRequest*>::iterator it = requests.begin(); |
497 |
|
498 |
// delete all the requests
|
499 |
|
500 |
for(it = requests.begin(); it != requests.end(); it++)
|
501 |
delete *it;
|
502 |
|
503 |
for(it = finished_requests.begin(); it != finished_requests.end(); it++)
|
504 |
delete *it;
|
505 |
} |
506 |
|
507 |
void
|
508 |
Connection::Parse(const void *buf, size_t count) |
509 |
{ |
510 |
// FIXME change ebb_request_parser to have void* arg
|
511 |
ebb_request_parser_execute ( &parser |
512 |
, static_cast<const char*> (buf) |
513 |
, count |
514 |
); |
515 |
|
516 |
if(ebb_request_parser_has_error(&parser)) {
|
517 |
fprintf(stderr, "parse error closing connection\n");
|
518 |
oi_socket_close(&socket); |
519 |
} |
520 |
} |
521 |
|
522 |
void
|
523 |
Connection::AddRequest(HttpRequest *request) |
524 |
{ |
525 |
requests.push_back(request); |
526 |
} |
527 |
|
528 |
void
|
529 |
Connection::Write ( ) |
530 |
{ |
531 |
if(requests.size() == 0) |
532 |
return;
|
533 |
|
534 |
HttpRequest *request = requests.front(); |
535 |
|
536 |
while(request->output.size() > 0) { |
537 |
oi_buf *buf = request->output.front(); |
538 |
oi_socket_write(&socket, buf); |
539 |
request->output.pop_front(); |
540 |
} |
541 |
|
542 |
if(request->done) {
|
543 |
if(!ebb_request_should_keep_alive(&request->parser_info)) {
|
544 |
socket.on_drain = oi_socket_close; |
545 |
} |
546 |
|
547 |
requests.pop_front(); |
548 |
finished_requests.push_back(request); |
549 |
|
550 |
Write(); |
551 |
} |
552 |
} |
553 |
|
554 |
void
|
555 |
Connection::Close ( ) |
556 |
{ |
557 |
oi_socket_close(&socket); |
558 |
} |
559 |
|
560 |
static void |
561 |
server_destroy (Persistent<Value> _, void *data)
|
562 |
{ |
563 |
HttpServer *server = static_cast<HttpServer *> (data);
|
564 |
delete server;
|
565 |
} |
566 |
|
567 |
HttpServer::HttpServer (Handle<Object> _js_server) |
568 |
{ |
569 |
oi_server_init(&server, 1024);
|
570 |
server.on_connection = on_connection; |
571 |
server.data = this;
|
572 |
HandleScope scope; |
573 |
js_server = Persistent<Object>::New (_js_server); |
574 |
// are we ever going to need this external?
|
575 |
js_server->SetInternalField (0, External::New(this)); |
576 |
js_server.MakeWeak (this, server_destroy);
|
577 |
} |
578 |
|
579 |
HttpServer::~HttpServer () |
580 |
{ |
581 |
Stop(); |
582 |
js_server.Dispose(); |
583 |
js_server.Clear(); // necessary?
|
584 |
} |
585 |
|
586 |
int
|
587 |
HttpServer::Start(struct addrinfo *servinfo)
|
588 |
{ |
589 |
int r = oi_server_listen(&server, servinfo);
|
590 |
if(r == 0) |
591 |
oi_server_attach(EV_DEFAULT_UC_ &server); |
592 |
return r;
|
593 |
} |
594 |
|
595 |
void
|
596 |
HttpServer::Stop() |
597 |
{ |
598 |
oi_server_close (&server); |
599 |
oi_server_detach (&server); |
600 |
} |
601 |
|
602 |
/* This constructor takes 2 arguments: host, port. */
|
603 |
static Handle<Value>
|
604 |
newHTTPHttpServer (const Arguments& args)
|
605 |
{ |
606 |
if (args.Length() < 3) |
607 |
return Undefined();
|
608 |
|
609 |
HandleScope scope; |
610 |
|
611 |
char *host = NULL; |
612 |
String::AsciiValue host_v(args[0]->ToString());
|
613 |
if(args[0]->IsString()) { |
614 |
host = *host_v; |
615 |
} |
616 |
String::AsciiValue port(args[1]->ToString());
|
617 |
|
618 |
Handle<Function> onrequest = Handle<Function>::Cast(args[2]);
|
619 |
args.This()->Set(on_request_str, onrequest); |
620 |
|
621 |
// get addrinfo for localhost, PORT
|
622 |
struct addrinfo *servinfo;
|
623 |
struct addrinfo hints;
|
624 |
memset(&hints, 0, sizeof hints); |
625 |
hints.ai_family = AF_UNSPEC; |
626 |
hints.ai_socktype = SOCK_STREAM; |
627 |
hints.ai_flags = AI_PASSIVE; |
628 |
// FIXME BLOCKING
|
629 |
int r = getaddrinfo(host, *port, &hints, &servinfo);
|
630 |
if (r != 0) |
631 |
return Undefined(); // XXX raise error? |
632 |
|
633 |
//
|
634 |
//
|
635 |
//
|
636 |
// TODO host is ignored for now assumed localhost
|
637 |
//
|
638 |
//
|
639 |
//
|
640 |
//
|
641 |
|
642 |
HttpServer *server = new HttpServer(args.This());
|
643 |
if(server == NULL) |
644 |
return Undefined(); // XXX raise error? |
645 |
|
646 |
r = server->Start(servinfo); |
647 |
if (r != 0) |
648 |
return Undefined(); // XXX raise error? |
649 |
|
650 |
return args.This();
|
651 |
} |
652 |
|
653 |
void
|
654 |
NodeInit_http (Handle<Object> target) |
655 |
{ |
656 |
HandleScope scope; |
657 |
|
658 |
Local<FunctionTemplate> server_t = FunctionTemplate::New(newHTTPHttpServer); |
659 |
server_t->InstanceTemplate()->SetInternalFieldCount(1);
|
660 |
|
661 |
server_t->Set("INVALID_STATE_ERR", Integer::New(INVALID_STATE_ERR));
|
662 |
|
663 |
target->Set(String::New("HTTPServer"), server_t->GetFunction());
|
664 |
|
665 |
path_str = Persistent<String>::New( String::NewSymbol("path") );
|
666 |
uri_str = Persistent<String>::New( String::NewSymbol("uri") );
|
667 |
query_string_str = Persistent<String>::New( String::NewSymbol("query_string") );
|
668 |
fragment_str = Persistent<String>::New( String::NewSymbol("fragment") );
|
669 |
method_str = Persistent<String>::New( String::NewSymbol("method") );
|
670 |
http_version_str = Persistent<String>::New( String::NewSymbol("http_version") );
|
671 |
headers_str = Persistent<String>::New( String::NewSymbol("headers") );
|
672 |
|
673 |
on_request_str = Persistent<String>::New( String::NewSymbol("onrequest") );
|
674 |
on_body_str = Persistent<String>::New( String::NewSymbol("onbody") );
|
675 |
respond_str = Persistent<String>::New( String::NewSymbol("respond") );
|
676 |
|
677 |
copy_str = Persistent<String>::New( String::New("COPY") );
|
678 |
delete_str = Persistent<String>::New( String::New("DELETE") );
|
679 |
get_str = Persistent<String>::New( String::New("GET") );
|
680 |
head_str = Persistent<String>::New( String::New("HEAD") );
|
681 |
lock_str = Persistent<String>::New( String::New("LOCK") );
|
682 |
mkcol_str = Persistent<String>::New( String::New("MKCOL") );
|
683 |
move_str = Persistent<String>::New( String::New("MOVE") );
|
684 |
options_str = Persistent<String>::New( String::New("OPTIONS") );
|
685 |
post_str = Persistent<String>::New( String::New("POST") );
|
686 |
propfind_str = Persistent<String>::New( String::New("PROPFIND") );
|
687 |
proppatch_str = Persistent<String>::New( String::New("PROPPATCH") );
|
688 |
put_str = Persistent<String>::New( String::New("PUT") );
|
689 |
trace_str = Persistent<String>::New( String::New("TRACE") );
|
690 |
unlock_str = Persistent<String>::New( String::New("UNLOCK") );
|
691 |
} |