2323 #include < stdio.h>
2424 #include < stdlib.h>
2525
26- /* Obtain a backtrace and print it to stdout. */
27- void
28- print_trace (void )
29- {
30- void *array[10 ];
31- size_t size;
32- char **strings;
33- size_t i;
34-
35- size = backtrace (array, 10 );
36- strings = backtrace_symbols (array, size);
37-
38- printf (" Obtained %zd stack frames.\n " , size);
39-
40- for (i = 0 ; i < size; i++)
41- printf (" %s\n " , strings[i]);
42-
43- free (strings);
44- }
45-
4626namespace node {
4727
4828using namespace v8 ;
4929
30+ static int deep = 0 ;
31+
5032static Persistent<String> on_message_begin_sym;
5133static Persistent<String> on_path_sym;
5234static Persistent<String> on_query_string_sym;
@@ -92,7 +74,6 @@ static Persistent<String> should_keep_alive_sym;
9274 Local<Value> cb_value = parser->handle_ ->Get (name##_sym); \
9375 if (!cb_value->IsFunction ()) return 0 ; \
9476 Local<Function> cb = Local<Function>::Cast (cb_value); \
95- \
9677 Local<Value> ret = cb->Call (parser->handle_ , 0 , NULL ); \
9778 return ret.IsEmpty () ? -1 : 0 ; \
9879 }
@@ -149,21 +130,7 @@ class Parser : public ObjectWrap {
149130 public:
150131 Parser (enum http_parser_type type) : ObjectWrap() {
151132 buffer_ = NULL ;
152-
153- http_parser_init (&parser_, type);
154-
155- parser_.on_message_begin = on_message_begin;
156- parser_.on_path = on_path;
157- parser_.on_query_string = on_query_string;
158- parser_.on_url = on_url;
159- parser_.on_fragment = on_fragment;
160- parser_.on_header_field = on_header_field;
161- parser_.on_header_value = on_header_value;
162- parser_.on_headers_complete = on_headers_complete;
163- parser_.on_body = on_body;
164- parser_.on_message_complete = on_message_complete;
165-
166- parser_.data = this ;
133+ Init (type);
167134 }
168135
169136 ~Parser () {
@@ -213,6 +180,7 @@ class Parser : public ObjectWrap {
213180 Local<Value> argv[1 ] = { message_info };
214181
215182 Local<Value> ret = cb->Call (parser->handle_ , 1 , argv);
183+
216184 return ret.IsEmpty () ? -1 : 0 ;
217185 }
218186
@@ -233,6 +201,7 @@ class Parser : public ObjectWrap {
233201 }
234202
235203 parser->Wrap (args.This ());
204+ assert (!parser->buffer_ );
236205
237206 return args.This ();
238207 }
@@ -243,8 +212,8 @@ class Parser : public ObjectWrap {
243212
244213 Parser *parser = ObjectWrap::Unwrap<Parser>(args.This ());
245214
215+ assert (!parser->buffer_ );
246216 if (parser->buffer_ ) {
247- print_trace ();
248217 return ThrowException (Exception::TypeError (
249218 String::New (" Already parsing a buffer" )));
250219 }
@@ -273,13 +242,9 @@ class Parser : public ObjectWrap {
273242 // Assign 'buffer_' while we parse. The callbacks will access that varible.
274243 parser->buffer_ = buffer;
275244
276- buffer_ref (parser->buffer_ );
277-
278245 size_t nparsed =
279246 http_parser_execute (&(parser->parser_ ), buffer_p (buffer, off), len);
280247
281- buffer_unref (parser->buffer_ );
282-
283248 // Unassign the 'buffer_' variable
284249 assert (parser->buffer_ );
285250 parser->buffer_ = NULL ;
@@ -297,25 +262,64 @@ class Parser : public ObjectWrap {
297262 return ThrowException (e);
298263 }
299264
265+ assert (!parser->buffer_ );
300266 return scope.Close (nparsed_obj);
301267 }
302268
303- static Handle<Value> ExecuteEOF (const Arguments& args) {
269+ static Handle<Value> Finish (const Arguments& args) {
304270 HandleScope scope;
305271
306272 Parser *parser = ObjectWrap::Unwrap<Parser>(args.This ());
307273
308274 assert (!parser->buffer_ );
309- http_parser_execute (&parser->parser_ , NULL , 0 );
310275
276+ parser->Ref ();
277+ http_parser_execute (&(parser->parser_ ), NULL , 0 );
278+ parser->Unref ();
279+
280+ return Undefined ();
281+ }
282+
283+ static Handle<Value> Reinitialize (const Arguments& args) {
284+ HandleScope scope;
285+ Parser *parser = ObjectWrap::Unwrap<Parser>(args.This ());
286+
287+ String::Utf8Value type (args[0 ]->ToString ());
288+
289+ if (0 == strcasecmp (*type, " request" )) {
290+ parser->Init (HTTP_REQUEST );
291+ } else if (0 == strcasecmp (*type, " response" )) {
292+ parser->Init (HTTP_RESPONSE );
293+ } else {
294+ return ThrowException (Exception::Error (
295+ String::New (" Argument be 'request' or 'response'" )));
296+ }
311297 return Undefined ();
312298 }
313299
314300
315301 private:
316302
317- http_parser parser_;
303+ void Init (enum http_parser_type type) {
304+ assert (buffer_ == NULL ); // don't call this during Execute()
305+ http_parser_init (&parser_, type);
306+
307+ parser_.on_message_begin = on_message_begin;
308+ parser_.on_path = on_path;
309+ parser_.on_query_string = on_query_string;
310+ parser_.on_url = on_url;
311+ parser_.on_fragment = on_fragment;
312+ parser_.on_header_field = on_header_field;
313+ parser_.on_header_value = on_header_value;
314+ parser_.on_headers_complete = on_headers_complete;
315+ parser_.on_body = on_body;
316+ parser_.on_message_complete = on_message_complete;
317+
318+ parser_.data = this ;
319+ }
320+
318321 struct buffer * buffer_; // The buffer currently being parsed.
322+ http_parser parser_;
319323};
320324
321325
@@ -324,10 +328,11 @@ void InitHttpParser(Handle<Object> target) {
324328
325329 Local<FunctionTemplate> t = FunctionTemplate::New (Parser::New);
326330 t->InstanceTemplate ()->SetInternalFieldCount (1 );
327- // t->SetClassName(String::NewSymbol("HTTPParser"));
331+ t->SetClassName (String::NewSymbol (" HTTPParser" ));
328332
329333 NODE_SET_PROTOTYPE_METHOD (t, " execute" , Parser::Execute);
330- NODE_SET_PROTOTYPE_METHOD (t, " executeEOF" , Parser::ExecuteEOF);
334+ NODE_SET_PROTOTYPE_METHOD (t, " finish" , Parser::Finish);
335+ NODE_SET_PROTOTYPE_METHOD (t, " reinitialize" , Parser::Reinitialize);
331336
332337 target->Set (String::NewSymbol (" HTTPParser" ), t->GetFunction ());
333338
0 commit comments