Browse Source

Slight change in tcp connection constructor

For server-side sockets, no longer pass the server object to the
js constructor. This is set later with SetAcceptor.

I think the change is a bit strage and convoluted but it allows one give
protocol /classes/ to the c++ constructors instead of protocol instances.
This is nice because derived classes (like HTTP) don't need to copy the
protocol instanciation code.
v0.7.4-release
Ryan 16 years ago
parent
commit
09c2ae5c3e
  1. 67
      src/http.cc
  2. 6
      src/http.h
  3. 45
      src/net.cc
  4. 6
      src/net.h
  5. 4
      test/test-pingpong.js

67
src/http.cc

@ -12,6 +12,10 @@
#define ON_MESSAGE_COMPLETE_SYMBOL String::NewSymbol("onMessageComplete")
#define PATH_SYMBOL String::NewSymbol("path")
#define QUERY_STRING_SYMBOL String::NewSymbol("query_string")
#define URI_SYMBOL String::NewSymbol("uri")
#define FRAGMENT_SYMBOL String::NewSymbol("fragment")
#define STATUS_CODE_SYMBOL String::NewSymbol("status_code")
#define HTTP_VERSION_SYMBOL String::NewSymbol("http_version")
@ -20,7 +24,7 @@ using namespace node;
using namespace std;
// Helper Functions
// Native Helper Functions
static Persistent<Function> _fill_field;
static Persistent<Function> _append_header_field;
@ -91,20 +95,10 @@ HTTPConnection::v8New (const Arguments& args)
if (args[0]->IsFunction() == false)
return ThrowException(String::New("Must pass a class as the first argument."));
Handle<Function> protocol = Handle<Function>::Cast(args[0]);
int argc = args.Length();
Handle<Value> argv[argc];
argv[0] = args.This();
for (int i = 1; i < args.Length(); i++) {
argv[i] = args[i];
}
Local<Object> protocol_instance = protocol->NewInstance(argc, argv);
Local<Function> protocol_class = Local<Function>::Cast(args[0]);
// changeme the type should come from javascript
new HTTPConnection(args.This(), protocol_instance, HTTP_RESPONSE);
new HTTPConnection(args.This(), protocol_class, HTTP_RESPONSE);
return args.This();
}
@ -136,19 +130,21 @@ HTTPConnection::on_message_begin (http_parser *parser)
return 0;
}
int
HTTPConnection::on_path (http_parser *parser, const char *buf, size_t len)
{
HTTPConnection *connection = static_cast<HTTPConnection*> (parser->data);
HandleScope scope;
Local<Value> message_handler_v =
connection->handle_->GetHiddenValue(MESSAGE_HANDLER_SYMBOL);
fillField(message_handler_v, PATH_SYMBOL, String::New(buf, len));
return 0;
#define DEFINE_FILL_VALUE_CALLBACK(callback_name, symbol) \
int \
HTTPConnection::callback_name (http_parser *parser, const char *buf, size_t len) \
{ \
HTTPConnection *connection = static_cast<HTTPConnection*> (parser->data); \
HandleScope scope; \
Local<Value> message_handler_v = \
connection->handle_->GetHiddenValue(MESSAGE_HANDLER_SYMBOL); \
fillField(message_handler_v, symbol, String::New(buf, len)); \
return 0; \
}
DEFINE_FILL_VALUE_CALLBACK(on_path, PATH_SYMBOL)
DEFINE_FILL_VALUE_CALLBACK(on_query_string, QUERY_STRING_SYMBOL)
DEFINE_FILL_VALUE_CALLBACK(on_uri, URI_SYMBOL)
DEFINE_FILL_VALUE_CALLBACK(on_fragment, FRAGMENT_SYMBOL)
int
HTTPConnection::on_header_field (http_parser *parser, const char *buf, size_t len)
@ -188,7 +184,12 @@ HTTPConnection::on_headers_complete (http_parser *parser)
// VERSION
char version[10];
snprintf(version, 10, "%d.%d", connection->parser_.version_major, connection->parser_.version_minor);
snprintf( version
, 10
, "%d.%d"
, connection->parser_.version_major
, connection->parser_.version_minor
);
message_handler->Set(HTTP_VERSION_SYMBOL, String::New(version));
@ -237,9 +238,7 @@ HTTPConnection::on_body (http_parser *parser, const char *buf, size_t len)
}
argv[0] = array;
}
on_body->Call(message_handler, 1, argv);
return 0;
}
@ -258,21 +257,19 @@ HTTPConnection::on_message_complete (http_parser *parser)
Handle<Function> on_msg_complete = Handle<Function>::Cast(on_msg_complete_v);
on_msg_complete->Call(message_handler, 0, NULL);
}
connection->handle_->DeleteHiddenValue(MESSAGE_HANDLER_SYMBOL);
return 0;
}
HTTPConnection::HTTPConnection (Handle<Object> handle, Handle<Object> protocol, enum http_parser_type type)
: Connection(handle, protocol)
HTTPConnection::HTTPConnection (Handle<Object> handle, Handle<Function> protocol_class, enum http_parser_type type)
: Connection(handle, protocol_class)
{
http_parser_init (&parser_, type);
parser_.on_message_begin = on_message_begin;
parser_.on_path = on_path;
parser_.on_query_string = NULL;
parser_.on_uri = NULL;
parser_.on_fragment = NULL;
parser_.on_query_string = on_query_string;
parser_.on_uri = on_uri;
parser_.on_fragment = on_fragment;
parser_.on_header_field = on_header_field;
parser_.on_header_value = on_header_value;
parser_.on_headers_complete = on_headers_complete;

6
src/http.h

@ -12,15 +12,19 @@ public:
static void Initialize (v8::Handle<v8::Object> target);
HTTPConnection (v8::Handle<v8::Object> handle,
v8::Handle<v8::Object> protocol,
v8::Handle<v8::Function> protocol_class,
enum http_parser_type type);
static v8::Handle<v8::Value> v8New (const v8::Arguments& args);
protected:
void OnReceive (const void *buf, size_t len);
static int on_message_begin (http_parser *parser);
static int on_path (http_parser *parser, const char *at, size_t length);
static int on_query_string (http_parser *parser, const char *at, size_t length);
static int on_uri (http_parser *parser, const char *at, size_t length);
static int on_fragment (http_parser *parser, const char *at, size_t length);
static int on_header_field (http_parser *parser, const char *buf, size_t len);
static int on_header_value (http_parser *parser, const char *buf, size_t len);
static int on_headers_complete (http_parser *parser);

45
src/net.cc

@ -26,6 +26,7 @@ using namespace node;
#define CONNECT_SYMBOL String::NewSymbol("connect")
#define ENCODING_SYMBOL String::NewSymbol("encoding")
#define TIMEOUT_SYMBOL String::NewSymbol("timeout")
#define SERVER_SYMBOL String::NewSymbol("server")
#define PROTOCOL_SYMBOL String::NewSymbol("protocol")
@ -59,13 +60,19 @@ Connection::Initialize (v8::Handle<v8::Object> target)
NODE_SET_METHOD(t->InstanceTemplate(), "sendEOF", Connection::v8SendEOF);
}
Connection::Connection (Handle<Object> handle, Handle<Object> protocol)
Connection::Connection (Handle<Object> handle, Handle<Function> protocol_class)
: ObjectWrap(handle)
{
HandleScope scope;
// Instanciate the protocol object
Handle<Value> argv[] = { handle_ };
Local<Object> protocol = protocol_class->NewInstance(1, argv);
handle_->Set(PROTOCOL_SYMBOL, protocol);
// TODO use SetNamedPropertyHandler (or whatever) for encoding and timeout
// instead of just reading it once?
encoding_ = RAW;
Local<Value> encoding_v = protocol->Get(ENCODING_SYMBOL);
if (encoding_v->IsString()) {
@ -108,28 +115,21 @@ Connection::GetProtocol (void)
return Local<Object>();
}
void
Connection::SetAcceptor (Handle<Object> acceptor_handle)
{
HandleScope scope;
handle_->Set(SERVER_SYMBOL, acceptor_handle);
}
Handle<Value>
Connection::v8New (const Arguments& args)
{
HandleScope scope;
if (args[0]->IsFunction() == false)
return ThrowException(String::New("Must pass a class as the first argument."));
Handle<Function> protocol = Handle<Function>::Cast(args[0]);
int argc = args.Length();
Handle<Value> argv[argc];
argv[0] = args.This();
for (int i = 1; i < args.Length(); i++) {
argv[i] = args[i];
}
Local<Object> protocol_instance = protocol->NewInstance(argc, argv);
new Connection(args.This(), protocol_instance);
Handle<Function> protocol_class = Handle<Function>::Cast(args[0]);
new Connection(args.This(), protocol_class);
return args.This();
}
@ -370,17 +370,18 @@ Acceptor::OnConnection (struct sockaddr *addr, socklen_t len)
{
HandleScope scope;
Local<Value> protocol_v = handle_->GetHiddenValue(PROTOCOL_SYMBOL);
if (!protocol_v->IsFunction()) {
Local<Value> protocol_class_v = handle_->GetHiddenValue(PROTOCOL_SYMBOL);
if (!protocol_class_v->IsFunction()) {
Close();
return NULL;
}
Local<Function> protocol = Local<Function>::Cast(protocol_v);
Local<Function> protocol_class = Local<Function>::Cast(protocol_class_v);
Handle<Value> argv[] = { protocol, handle_ };
Local<Object> connection_handle = tcp_connection_constructor->NewInstance(2, argv);
Handle<Value> argv[] = { protocol_class };
Local<Object> connection_handle = tcp_connection_constructor->NewInstance(1, argv);
Connection *connection = NODE_UNWRAP(Connection, connection_handle);
connection->SetAcceptor(handle_);
return connection;
}

6
src/net.h

@ -7,11 +7,13 @@
namespace node {
class Acceptor;
class Connection : public ObjectWrap {
public:
static void Initialize (v8::Handle<v8::Object> target);
Connection (v8::Handle<v8::Object> handle, v8::Handle<v8::Object> protocol);
Connection (v8::Handle<v8::Object> handle, v8::Handle<v8::Function> protocol_class);
virtual ~Connection () { Close(); }
int Connect (struct addrinfo *address) {
@ -30,6 +32,8 @@ public:
oi_socket_close (&socket_);
}
void SetAcceptor (v8::Handle<v8::Object> acceptor_handle);
protected:
static v8::Handle<v8::Value> v8New (const v8::Arguments& args);
static v8::Handle<v8::Value> v8Connect (const v8::Arguments& args);

4
test/test-pingpong.js

@ -4,7 +4,7 @@ var port = 12123;
var N = 1000;
var count = 0;
function Ponger (socket, server) {
function Ponger (socket) {
this.encoding = "UTF8";
this.timeout = 0;
@ -28,7 +28,7 @@ function Ponger (socket, server) {
this.onDisconnect = function () {
puts("ponger: onDisconnect");
server.close();
socket.server.close();
};
}

Loading…
Cancel
Save