Skip to content

Commit a668d07

Browse files
committed
Clean up http_parser binding - add asserts
1 parent 824a2fd commit a668d07

1 file changed

Lines changed: 51 additions & 46 deletions

File tree

src/node_http_parser.cc

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,12 @@
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-
4626
namespace node {
4727

4828
using namespace v8;
4929

30+
static int deep = 0;
31+
5032
static Persistent<String> on_message_begin_sym;
5133
static Persistent<String> on_path_sym;
5234
static 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

Comments
 (0)