Implement HTTPServer (untested!)
Mostly this is setting up the proper interface to be able to create the HTTP server.
This commit is contained in:
Родитель
b763ee0ad4
Коммит
9c3770d999
65
src/http.cc
65
src/http.cc
|
@ -70,7 +70,8 @@ appendHeaderValue (Handle<Value> message, Handle<Value> d)
|
|||
_append_header_value->Call(message->ToObject(), 2, argv);
|
||||
}
|
||||
|
||||
Persistent<FunctionTemplate> HTTPConnection::constructor_template;
|
||||
Persistent<FunctionTemplate> HTTPConnection::client_constructor_template;
|
||||
Persistent<FunctionTemplate> HTTPConnection::server_constructor_template;
|
||||
|
||||
void
|
||||
HTTPConnection::Initialize (Handle<Object> target)
|
||||
|
@ -78,11 +79,17 @@ HTTPConnection::Initialize (Handle<Object> target)
|
|||
HandleScope scope;
|
||||
|
||||
Local<FunctionTemplate> t = FunctionTemplate::New(HTTPConnection::v8NewClient);
|
||||
constructor_template = Persistent<FunctionTemplate>::New(t);
|
||||
client_constructor_template = Persistent<FunctionTemplate>::New(t);
|
||||
client_constructor_template->Inherit(Connection::constructor_template);
|
||||
client_constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
target->Set(String::NewSymbol("HTTPClient"), client_constructor_template->GetFunction());
|
||||
|
||||
constructor_template->Inherit(Connection::constructor_template);
|
||||
constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
target->Set(String::NewSymbol("HTTPClient"), constructor_template->GetFunction());
|
||||
t = FunctionTemplate::New(HTTPConnection::v8NewServer);
|
||||
server_constructor_template = Persistent<FunctionTemplate>::New(t);
|
||||
server_constructor_template->Inherit(Connection::constructor_template);
|
||||
server_constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
target->Set(String::NewSymbol("HTTPServerSideSocket"),
|
||||
server_constructor_template->GetFunction());
|
||||
}
|
||||
|
||||
Handle<Value>
|
||||
|
@ -284,19 +291,61 @@ HTTPConnection::HTTPConnection (Handle<Object> handle, Handle<Function> protocol
|
|||
parser_.data = this;
|
||||
}
|
||||
|
||||
HTTPServer::HTTPServer (Handle<Object> handle, Handle<Object> options)
|
||||
:Acceptor(handle, options)
|
||||
Persistent<FunctionTemplate> HTTPServer::constructor_template;
|
||||
|
||||
void
|
||||
HTTPServer::Initialize (Handle<Object> target)
|
||||
{
|
||||
HandleScope scope;
|
||||
|
||||
Local<FunctionTemplate> t = FunctionTemplate::New(HTTPServer::v8New);
|
||||
constructor_template = Persistent<FunctionTemplate>::New(t);
|
||||
|
||||
constructor_template->Inherit(Acceptor::constructor_template);
|
||||
constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
target->Set(String::NewSymbol("HTTPServer"), constructor_template->GetFunction());
|
||||
}
|
||||
|
||||
Handle<Value>
|
||||
HTTPServer::v8New (const Arguments& args)
|
||||
{
|
||||
HandleScope scope;
|
||||
|
||||
if (args.Length() < 1 || args[0]->IsFunction() == false)
|
||||
return ThrowException(String::New("Must at give connection handler as the first argument"));
|
||||
|
||||
Local<Function> protocol_class = Local<Function>::Cast(args[0]);
|
||||
Local<Object> options;
|
||||
|
||||
if (args.Length() > 1 && args[1]->IsObject()) {
|
||||
options = args[1]->ToObject();
|
||||
} else {
|
||||
options = Object::New();
|
||||
}
|
||||
|
||||
new HTTPServer(args.Holder(), protocol_class, options);
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
||||
Connection*
|
||||
HTTPServer::OnConnection (struct sockaddr *addr, socklen_t len)
|
||||
{
|
||||
HandleScope scope;
|
||||
|
||||
Local<Function> protocol_class = GetProtocolClass();
|
||||
if (protocol_class.IsEmpty()) {
|
||||
Close();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Handle<Value> argv[] = { protocol_class };
|
||||
Local<Object> connection_handle =
|
||||
HTTPConnection::server_constructor_template->GetFunction()->NewInstance(1, argv);
|
||||
|
||||
HTTPConnection *connection = NODE_UNWRAP(HTTPConnection, connection_handle);
|
||||
connection->SetAcceptor(handle_);
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
||||
|
|
15
src/http.h
15
src/http.h
|
@ -11,8 +11,10 @@ class HTTPConnection : public Connection {
|
|||
public:
|
||||
static void Initialize (v8::Handle<v8::Object> target);
|
||||
|
||||
static v8::Persistent<v8::FunctionTemplate> client_constructor_template;
|
||||
static v8::Persistent<v8::FunctionTemplate> server_constructor_template;
|
||||
|
||||
protected:
|
||||
static v8::Persistent<v8::FunctionTemplate> constructor_template;
|
||||
static v8::Handle<v8::Value> v8NewClient (const v8::Arguments& args);
|
||||
static v8::Handle<v8::Value> v8NewServer (const v8::Arguments& args);
|
||||
|
||||
|
@ -34,14 +36,23 @@ protected:
|
|||
static int on_message_complete (http_parser *parser);
|
||||
|
||||
http_parser parser_;
|
||||
|
||||
friend class HTTPServer;
|
||||
};
|
||||
|
||||
class HTTPServer : public Acceptor {
|
||||
public:
|
||||
HTTPServer (v8::Handle<v8::Object> handle, v8::Handle<v8::Object> options);
|
||||
static void Initialize (v8::Handle<v8::Object> target);
|
||||
|
||||
protected:
|
||||
static v8::Persistent<v8::FunctionTemplate> constructor_template;
|
||||
static v8::Handle<v8::Value> v8New (const v8::Arguments& args);
|
||||
|
||||
HTTPServer (v8::Handle<v8::Object> handle,
|
||||
v8::Handle<v8::Function> protocol_class,
|
||||
v8::Handle<v8::Object> options)
|
||||
:Acceptor(handle, protocol_class, options) {};
|
||||
|
||||
Connection* OnConnection (struct sockaddr *addr, socklen_t len);
|
||||
};
|
||||
|
||||
|
|
31
src/net.cc
31
src/net.cc
|
@ -29,6 +29,7 @@ using namespace node;
|
|||
#define SERVER_SYMBOL String::NewSymbol("server")
|
||||
|
||||
#define PROTOCOL_SYMBOL String::NewSymbol("protocol")
|
||||
#define PROTOCOL_CLASS_SYMBOL String::NewSymbol("protocol_class")
|
||||
|
||||
static const struct addrinfo tcp_hints =
|
||||
/* ai_flags */ { AI_PASSIVE
|
||||
|
@ -350,11 +351,13 @@ Acceptor::Initialize (Handle<Object> target)
|
|||
constructor_template = Persistent<FunctionTemplate>::New(t);
|
||||
}
|
||||
|
||||
Acceptor::Acceptor (Handle<Object> handle, Handle<Object> options)
|
||||
Acceptor::Acceptor (Handle<Object> handle, Handle<Function> protocol_class, Handle<Object> options)
|
||||
: ObjectWrap(handle)
|
||||
{
|
||||
HandleScope scope;
|
||||
|
||||
handle_->SetHiddenValue(PROTOCOL_CLASS_SYMBOL, protocol_class);
|
||||
|
||||
int backlog = 1024; // default value
|
||||
Local<Value> backlog_v = options->Get(String::NewSymbol("backlog"));
|
||||
if (backlog_v->IsInt32()) {
|
||||
|
@ -377,12 +380,12 @@ Acceptor::OnConnection (struct sockaddr *addr, socklen_t len)
|
|||
{
|
||||
HandleScope scope;
|
||||
|
||||
Local<Value> protocol_class_v = handle_->GetHiddenValue(PROTOCOL_SYMBOL);
|
||||
if (!protocol_class_v->IsFunction()) {
|
||||
Local<Function> protocol_class = GetProtocolClass();
|
||||
if (protocol_class.IsEmpty()) {
|
||||
printf("protocol class was empty!");
|
||||
Close();
|
||||
return NULL;
|
||||
}
|
||||
Local<Function> protocol_class = Local<Function>::Cast(protocol_class_v);
|
||||
|
||||
Handle<Value> argv[] = { protocol_class };
|
||||
Local<Object> connection_handle =
|
||||
|
@ -413,9 +416,7 @@ Acceptor::v8New (const Arguments& args)
|
|||
if (args.Length() < 1 || args[0]->IsFunction() == false)
|
||||
return ThrowException(String::New("Must at give connection handler as the first argument"));
|
||||
|
||||
/// set the handler
|
||||
args.Holder()->SetHiddenValue(PROTOCOL_SYMBOL, args[0]);
|
||||
|
||||
Local<Function> protocol_class = Local<Function>::Cast(args[0]);
|
||||
Local<Object> options;
|
||||
|
||||
if (args.Length() > 1 && args[1]->IsObject()) {
|
||||
|
@ -424,7 +425,7 @@ Acceptor::v8New (const Arguments& args)
|
|||
options = Object::New();
|
||||
}
|
||||
|
||||
new Acceptor(args.Holder(), options);
|
||||
new Acceptor(args.This(), protocol_class, options);
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
@ -466,3 +467,17 @@ Acceptor::v8Close (const Arguments& args)
|
|||
acceptor->Close();
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
Local<v8::Function>
|
||||
Acceptor::GetProtocolClass (void)
|
||||
{
|
||||
HandleScope scope;
|
||||
|
||||
Local<Value> protocol_class_v = handle_->GetHiddenValue(PROTOCOL_CLASS_SYMBOL);
|
||||
if (protocol_class_v->IsFunction()) {
|
||||
Local<Function> protocol_class = Local<Function>::Cast(protocol_class_v);
|
||||
return scope.Close(protocol_class);
|
||||
}
|
||||
|
||||
return Local<Function>();
|
||||
}
|
||||
|
|
|
@ -99,9 +99,13 @@ protected:
|
|||
static v8::Handle<v8::Value> v8Listen (const v8::Arguments& args);
|
||||
static v8::Handle<v8::Value> v8Close (const v8::Arguments& args);
|
||||
|
||||
Acceptor (v8::Handle<v8::Object> handle, v8::Handle<v8::Object> options);
|
||||
Acceptor (v8::Handle<v8::Object> handle,
|
||||
v8::Handle<v8::Function> protocol_class,
|
||||
v8::Handle<v8::Object> options);
|
||||
virtual ~Acceptor () { Close(); }
|
||||
|
||||
v8::Local<v8::Function> GetProtocolClass (void);
|
||||
|
||||
int Listen (struct addrinfo *address) {
|
||||
int r = oi_server_listen (&server_, address);
|
||||
if(r != 0) return r;
|
||||
|
|
|
@ -250,7 +250,9 @@ main (int argc, char *argv[])
|
|||
|
||||
Acceptor::Initialize(g);
|
||||
Connection::Initialize(g);
|
||||
|
||||
HTTPConnection::Initialize(g);
|
||||
HTTPServer::Initialize(g);
|
||||
|
||||
// NATIVE JAVASCRIPT MODULES
|
||||
TryCatch try_catch;
|
||||
|
|
Загрузка…
Ссылка в новой задаче