});
socket.ondata = function (d, start, end) {
- var bytesParsed = parser.execute(d, start, end - start);
- if (parser.incoming && parser.incoming.upgrade) {
+ var ret = parser.execute(d, start, end - start);
+ if (ret instanceof Error) {
+ socket.destroy(ret);
+ } else if (parser.incoming && parser.incoming.upgrade) {
+ var bytesParsed = ret;
socket.ondata = null;
socket.onend = null;
socket.onend = function () {
parser.finish();
+
// unref the parser for easy gc
parsers.free(parser);
if (!parser) {
throw new Error("parser not initialized prior to Client.ondata call");
}
- var bytesParsed = parser.execute(d, start, end - start);
- if (parser.incoming && parser.incoming.upgrade) {
+ var ret = parser.execute(d, start, end - start);
+ if (ret instanceof Error) {
+ self.destroy(ret);
+ } else if (parser.incoming && parser.incoming.upgrade) {
+ var bytesParsed = ret;
var upgradeHead = d.slice(start + bytesParsed, end - start);
parser.incoming.upgradeHead = upgradeHead;
currentRequest.emit("response", parser.incoming);
self.onend = function () {
parser.finish();
-
debug("self got end closing. readyState = " + self.readyState);
self.end();
};
// Stream becomes writeable on connect() but don't flush if there's
// nothing actually to write
if (socket.flush()) {
- try {
- if (socket._events && socket._events['drain']) socket.emit("drain");
- if (socket.ondrain) socket.ondrain(); // Optimization
- } catch (e) {
- socket.destroy(e);
- return;
- }
+ if (socket._events && socket._events['drain']) socket.emit("drain");
+ if (socket.ondrain) socket.ondrain(); // Optimization
}
}
if (!self.writable) self.destroy();
// Note: 'close' not emitted until nextTick.
- try {
- if (self._events && self._events['end']) self.emit('end');
- if (self.onend) self.onend();
- } catch (e) {
- self.destroy(e);
- return;
- }
+ if (self._events && self._events['end']) self.emit('end');
+ if (self.onend) self.onend();
} else if (bytesRead > 0) {
timeout.active(self);
var end = pool.used + bytesRead;
pool.used += bytesRead;
- try {
- if (!self._encoding) {
- if (self._events && self._events['data']) {
- // emit a slice
- self.emit('data', pool.slice(start, end));
- }
-
- // Optimization: emit the original buffer with end points
- if (self.ondata) self.ondata(pool, start, end);
- } else if (this._decoder) {
- this._decoder.write(pool.slice(start, end));
- } else {
- var string = pool.toString(self._encoding, start, end);
- self.emit('data', string);
+ if (!self._encoding) {
+ if (self._events && self._events['data']) {
+ // emit a slice
+ self.emit('data', pool.slice(start, end));
}
- } catch (e) {
- self.destroy(e);
- return;
+
+ // Optimization: emit the original buffer with end points
+ if (self.ondata) self.ondata(pool, start, end);
+ } else if (this._decoder) {
+ this._decoder.write(pool.slice(start, end));
+ } else {
+ var string = pool.toString(self._encoding, start, end);
+ self.emit('data', string);
}
}
};
process.openStdin = function () {
if (stdin) return stdin;
-var binding = process.binding('stdio'),
- net = module.requireNative('net'),
- fs = module.requireNative('fs'),
- fd = binding.openStdin();
+ var binding = process.binding('stdio'),
+ net = module.requireNative('net'),
+ fs = module.requireNative('fs'),
+ fd = binding.openStdin();
if (binding.isStdinBlocking()) {
stdin = new net.Stream(fd);
if (!cb_value->IsFunction()) return 0; \
Local<Function> cb = Local<Function>::Cast(cb_value); \
Local<Value> ret = cb->Call(parser->handle_, 0, NULL); \
- return ret.IsEmpty() ? -1 : 0; \
+ if (ret.IsEmpty()) { \
+ parser->got_exception_ = true; \
+ return -1; \
+ } else { \
+ return 0; \
+ } \
}
// Callback prototype for http_data_cb
}; \
Local<Value> ret = cb->Call(parser->handle_, 3, argv); \
assert(parser->buffer_); \
- return ret.IsEmpty() ? -1 : 0; \
+ if (ret.IsEmpty()) { \
+ parser->got_exception_ = true; \
+ return -1; \
+ } else { \
+ return 0; \
+ } \
}
Local<Value> ret = cb->Call(parser->handle_, 1, argv);
- return ret.IsEmpty() ? -1 : 0;
+ if (ret.IsEmpty()) {
+ parser->got_exception_ = true;
+ return -1;
+ } else {
+ return 0;
+ }
}
static Handle<Value> New(const Arguments& args) {
String::New("Length is extends beyond buffer")));
}
- TryCatch try_catch;
-
// Assign 'buffer_' while we parse. The callbacks will access that varible.
parser->buffer_ = buffer;
+ parser->got_exception_ = false;
size_t nparsed =
http_parser_execute(&parser->parser_, settings, buffer->data()+off, len);
parser->buffer_ = NULL;
// If there was an exception in one of the callbacks
- if (try_catch.HasCaught()) return try_catch.ReThrow();
+ if (parser->got_exception_) return Local<Value>();
Local<Integer> nparsed_obj = Integer::New(nparsed);
// If there was a parse error in one of the callbacks
// TODO What if there is an error on EOF?
if (!parser->parser_.upgrade && nparsed != len) {
- Local<Value> e = Exception::Error(String::New("Parse Error"));
+ Local<Value> e = Exception::Error(String::NewSymbol("Parse Error"));
Local<Object> obj = e->ToObject();
obj->Set(String::NewSymbol("bytesParsed"), nparsed_obj);
- return ThrowException(e);
+ return scope.Close(e);
+ } else {
+ return scope.Close(nparsed_obj);
}
-
- assert(!parser->buffer_);
- return scope.Close(nparsed_obj);
}
static Handle<Value> Finish(const Arguments& args) {
Parser *parser = ObjectWrap::Unwrap<Parser>(args.This());
assert(!parser->buffer_);
+ parser->got_exception_ = false;
http_parser_execute(&(parser->parser_), settings, NULL, 0);
+ if (parser->got_exception_) return Local<Value>();
+
return Undefined();
}
}
Buffer * buffer_; // The buffer currently being parsed.
+ bool got_exception_;
http_parser parser_;
};
server.addListener('upgrade', function (req, socket, upgradeHead) {
error('got upgrade event');
- // test that throwing an error from upgrade gets forworded
- // to the server'server 'error' event.
+ // test that throwing an error from upgrade gets
+ // is uncaught
throw new Error('upgrade error');
});
gotError = false;
-server.addListener('clientError', function (e) {
+process.addListener('uncaughtException', function (e) {
error('got "clientError" event');
assert.equal('upgrade error', e.message);
gotError = true;
+ process.exit(0);
});
+
server.listen(PORT);