[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/bionicpill/node/debugger/src/node_http.cc [Back]  [Original]

#include 

#include 
#include 
#include 

#define METHOD_SYMBOL               String::NewSymbol("method")
#define STATUS_CODE_SYMBOL          String::NewSymbol("statusCode")
#define HTTP_VERSION_SYMBOL         String::NewSymbol("httpVersion")
#define SHOULD_KEEP_ALIVE_SYMBOL    String::NewSymbol("should_keep_alive")

using namespace v8;
using namespace node;

Persistent HTTPConnection::client_constructor_template;
Persistent HTTPConnection::server_constructor_template;

void
HTTPConnection::Initialize (Handle target)
{
  HandleScope scope;

  Local t = FunctionTemplate::New(NewClient);
  client_constructor_template = Persistent::New(t);
  client_constructor_template->Inherit(Connection::constructor_template);
  client_constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
  client_constructor_template->SetClassName(String::NewSymbol("Client"));
  target->Set(String::NewSymbol("Client"), client_constructor_template->GetFunction());

  t = FunctionTemplate::New(NewServer);
  server_constructor_template = Persistent::New(t);
  server_constructor_template->Inherit(Connection::constructor_template);
  server_constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
  server_constructor_template->SetClassName(String::NewSymbol("ServerSideConnection"));
}

Handle
HTTPConnection::NewClient (const Arguments& args)
{
  HandleScope scope;

  HTTPConnection *connection = new HTTPConnection(HTTP_RESPONSE);
  connection->Wrap(args.This());

  return args.This();
}

Handle
HTTPConnection::NewServer (const Arguments& args)
{
  HandleScope scope;

  HTTPConnection *connection = new HTTPConnection(HTTP_REQUEST);
  connection->Wrap(args.This());

  return args.This();
}

void
HTTPConnection::OnReceive (const void *buf, size_t len)
{
  assert(attached_);
  http_parser_execute(&parser_, static_cast(buf), len);
  if (http_parser_has_error(&parser_)) ForceClose();
}

int
HTTPConnection::on_message_begin (http_parser *parser)
{
  HTTPConnection *connection = static_cast (parser->data);
  assert(connection->attached_);
  connection->Emit("messageBegin", 0, NULL);
  return 0;
}

int
HTTPConnection::on_message_complete (http_parser *parser)
{
  HTTPConnection *connection = static_cast (parser->data);
  assert(connection->attached_);
  connection->Emit("messageComplete", 0, NULL);
  return 0;
}

int
HTTPConnection::on_uri (http_parser *parser, const char *buf, size_t len)
{
  HandleScope scope;
  HTTPConnection *connection = static_cast(parser->data);
  assert(connection->attached_);
  Local argv[1] = { String::New(buf, len) };
  connection->Emit("uri", 1, argv);
  return 0;
}

int
HTTPConnection::on_query_string (http_parser *parser, const char *buf, size_t len)
{
  HandleScope scope;
  HTTPConnection *connection = static_cast(parser->data);
  assert(connection->attached_);
  Local argv[1] = { String::New(buf, len) };
  connection->Emit("queryString", 1, argv);
  return 0;
}

int
HTTPConnection::on_path (http_parser *parser, const char *buf, size_t len)
{
  HandleScope scope;
  HTTPConnection *connection = static_cast(parser->data);
  assert(connection->attached_);
  Local argv[1] = { String::New(buf, len) };
  connection->Emit("path", 1, argv);
  return 0;
}

int
HTTPConnection::on_fragment (http_parser *parser, const char *buf, size_t len)
{
  HandleScope scope;
  HTTPConnection *connection = static_cast(parser->data);
  assert(connection->attached_);
  Local argv[1] = { String::New(buf, len) };
  connection->Emit("fragment", 1, argv);
  return 0;
}

const static char normalizer[] =
  "\0------------------------------"
  "-----------------0123456789-----"
  "--abcdefghijklmnopqrstuvwxyz----"
  "--abcdefghijklmnopqrstuvwxyz----"
  "--------------------------------"
  "--------------------------------"
  "--------------------------------"
  "--------------------------------";

int
HTTPConnection::on_header_field (http_parser *parser, const char *buf, size_t len)
{
  HandleScope scope;
  HTTPConnection *connection = static_cast(parser->data);
  assert(connection->attached_);

  // NORMALIZE
  size_t i;
  char *nonconstbuf = (char*)buf; // FIXME
  for (i = 0; i < len; i++) { nonconstbuf[i] = normalizer[buf[i]]; }

  Local argv[1] = { String::New(buf, len) };
  connection->Emit("headerField", 1, argv);
  return 0;
}

int
HTTPConnection::on_header_value (http_parser *parser, const char *buf, size_t len)
{
  HandleScope scope;
  HTTPConnection *connection = static_cast(parser->data);
  assert(connection->attached_);

  Local argv[1] = { String::New(buf, len) };
  connection->Emit("headerValue", 1, argv);
  return 0;
}

static inline Local
GetMethod (int method)
{
  const char *s;
  switch (method) {
    case HTTP_COPY:       s = "COPY"; break;
    case HTTP_DELETE:     s = "DELETE"; break;
    case HTTP_GET:        s = "GET"; break;
    case HTTP_HEAD:       s = "HEAD"; break;
    case HTTP_LOCK:       s = "LOCK"; break;
    case HTTP_MKCOL:      s = "MKCOL"; break;
    case HTTP_MOVE:       s = "MOVE"; break;
    case HTTP_OPTIONS:    s = "OPTIONS"; break;
    case HTTP_POST:       s = "POST"; break;
    case HTTP_PROPFIND:   s = "PROPFIND"; break;
    case HTTP_PROPPATCH:  s = "PROPPATCH"; break;
    case HTTP_PUT:        s = "PUT"; break;
    case HTTP_TRACE:      s = "TRACE"; break;
    case HTTP_UNLOCK:     s = "UNLOCK"; break;
  }
  HandleScope scope;
  Local method = String::NewSymbol(s);
  return scope.Close(method);
}

int
HTTPConnection::on_headers_complete (http_parser *parser)
{
  HTTPConnection *connection = static_cast (parser->data);
  assert(connection->attached_);
  HandleScope scope;

  Local message_info = Object::New();

  // METHOD
  if (connection->parser_.type == HTTP_REQUEST)
    message_info->Set(METHOD_SYMBOL, GetMethod(connection->parser_.method));

  // STATUS
  if (connection->parser_.type == HTTP_RESPONSE)
    message_info->Set(STATUS_CODE_SYMBOL,
        Integer::New(connection->parser_.status_code));

  // VERSION
  char version[10];
  snprintf( version
          , 10
          , "%d.%d"
          , connection->parser_.version_major
          , connection->parser_.version_minor
          );
  message_info->Set(HTTP_VERSION_SYMBOL, String::New(version));

  message_info->Set(SHOULD_KEEP_ALIVE_SYMBOL,
      http_parser_should_keep_alive(&connection->parser_) ? True() : False());

  Local argv[1] = { message_info };

  connection->Emit("headerComplete", 1, argv);

  return 0;
}

int
HTTPConnection::on_body (http_parser *parser, const char *buf, size_t len)
{
  assert(len != 0);

  HTTPConnection *connection = static_cast (parser->data);
  assert(connection->attached_);
  HandleScope scope;

  // TODO each message should have their encoding.
  // don't look at the conneciton for encoding
  Local data = Encode(buf, len, connection->encoding_);
  connection->Emit("body", 1, &data);

  return 0;
}

Persistent HTTPServer::constructor_template;

void
HTTPServer::Initialize (Handle target)
{
  HandleScope scope;

  Local t = FunctionTemplate::New(New);
  constructor_template = Persistent::New(t);
  constructor_template->Inherit(Server::constructor_template);
  constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
  constructor_template->SetClassName(String::NewSymbol("Server"));
  target->Set(String::NewSymbol("Server"), constructor_template->GetFunction());
}

Handle
HTTPServer::New (const Arguments& args)
{
  HandleScope scope;

  HTTPServer *server = new HTTPServer();
  server->Wrap(args.This());

  return args.This();
}

Handle
HTTPServer::GetConnectionTemplate (void)
{
  return HTTPConnection::server_constructor_template;
}

Connection*
HTTPServer::UnwrapConnection (Local connection)
{
  HandleScope scope;
  return ObjectWrap::Unwrap(connection);
}


Web Proxy Viewer  |  New URL  |  Original Page