0
0
mirror of https://github.com/nodejs/node.git synced 2024-11-22 15:47:56 +01:00
nodejs/server.cc

248 lines
5.2 KiB
C++
Raw Normal View History

2009-02-16 01:34:45 +01:00
#include <v8.h>
extern "C" {
#include <oi.h>
#include <ebb_request_parser.h>
}
#include <assert.h>
#include <string>
#include <map>
using namespace v8;
using namespace std;
#define PORT "1981"
#define MAX_URL 500
static oi_server server;
static struct ev_loop *loop;
class Connection {
public:
Connection(void);
ebb_request_parser parser;
oi_socket socket;
};
class Request {
public:
Request(Connection &);
string path;
Connection &connection_;
ebb_request parser_info;
};
Request::Request
( Connection &connection
)
: connection_(connection)
{
ebb_request_init(&parser_info);
}
Connection::Connection
( void
)
{
oi_socket_init (&socket, 30.0);
ebb_request_parser_init (&parser);
}
void on_path
( ebb_request *req
, const char *buf
, size_t len
)
{
Request *request = static_cast<Request*> (req->data);
request->path.append(buf, len);
}
void on_request_complete
( ebb_request *req
)
{
Request *request = static_cast<Request*> (req->data);
// dispatch to javascript
}
ebb_request * on_request
( void *data
)
{
Connection *connection = static_cast<Connection*> (data);
Request *request = new Request(*connection);
request->parser_info.on_path = on_path;
request->parser_info.on_query_string = NULL;
request->parser_info.on_uri = NULL;
request->parser_info.on_fragment = NULL;
request->parser_info.on_header_field = NULL;
request->parser_info.on_header_value = NULL;
request->parser_info.on_headers_complete = NULL;
request->parser_info.on_body = NULL;
request->parser_info.on_complete = on_request_complete;
request->parser_info.data = request;
return &request->parser_info;
}
static void on_read
( oi_socket *socket
, const void *buf
, size_t count
)
{
Connection *connection = static_cast<Connection*> (socket->data);
ebb_request_parser_execute ( &connection->parser
, static_cast<const char*> (buf) // FIXME change ebb to use void*
, count
);
/* TODO check for errors */
}
static void on_close
( oi_socket *socket
)
{
Connection *connection = static_cast<Connection*> (socket->data);
/* TODO free requests */
free(connection);
}
static void on_drain
( oi_socket *socket
)
{
Connection *connection = static_cast<Connection*> (socket->data);
//oi_socket_close(&connection->socket);
}
static oi_socket* new_connection
( oi_server *server
, struct sockaddr *addr
, socklen_t len
)
{
Connection *connection = new Connection();
/* initialize the components of Connection */
oi_socket_init(&connection->socket, 30.0);
connection->socket.on_read = on_read;
connection->socket.on_error = NULL;
connection->socket.on_close = on_close;
connection->socket.on_timeout = NULL;
connection->socket.on_drain = on_drain;
connection->socket.data = connection;
ebb_request_parser_init(&connection->parser);
connection->parser.new_request = on_request;
connection->parser.data = connection;
return &connection->socket;
}
// Reads a file into a v8 string.
Handle<String> ReadFile
( const string& name
)
{
FILE* file = fopen(name.c_str(), "rb");
if (file == NULL) return Handle<String>();
fseek(file, 0, SEEK_END);
int size = ftell(file);
rewind(file);
char* chars = new char[size + 1];
chars[size] = '\0';
for (int i = 0; i < size;) {
int read = fread(&chars[i], 1, size - i, file);
i += read;
}
fclose(file);
Handle<String> result = String::New(chars, size);
delete[] chars;
return result;
}
void ParseOptions
( int argc
, char* argv[]
, map<string, string>& options
, string* file
)
{
for (int i = 1; i < argc; i++) {
string arg = argv[i];
int index = arg.find('=', 0);
if (index == string::npos) {
*file = arg;
} else {
string key = arg.substr(0, index);
string value = arg.substr(index+1);
options[key] = value;
}
}
}
int main
( int argc
, char *argv[]
)
{
map<string, string> options;
string file;
ParseOptions(argc, argv, options, &file);
if (file.empty()) {
fprintf(stderr, "No script was specified.\n");
return 1;
}
HandleScope scope;
Handle<String> source = ReadFile(file);
if (source.IsEmpty()) {
fprintf(stderr, "Error reading '%s'.\n", file.c_str());
return 1;
}
/*
HttpRequestProcessor processor(source);
map<string, string> output;
if (!processor.Initialize(&options, &output)) {
fprintf(stderr, "Error initializing processor.\n");
return 1;
}
*/
/////////////////////////////////////
loop = ev_default_loop(0);
oi_server_init(&server, 1024);
server.on_connection = new_connection;
// get addrinfo for localhost, PORT
struct addrinfo *servinfo;
struct addrinfo hints;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
int r = getaddrinfo(NULL, PORT, &hints, &servinfo);
assert(r == 0);
r = oi_server_listen(&server, servinfo);
assert(r == 0);
oi_server_attach(&server, loop);
printf("Running at http://localhost:%s/\n", PORT);
ev_loop(loop, 0);
return 0;
}