Skip to content

Commit

Permalink
Add http-parser dependency and bind HttpParser.parseUrl()
Browse files Browse the repository at this point in the history
  • Loading branch information
creationix committed Mar 20, 2012
1 parent 6bcfe7e commit 7cd757a
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "deps/candor"]
path = deps/candor
url = https://github.com/indutny/candor.git
[submodule "deps/http-parser"]
path = deps/http-parser
url = https://github.com/joyent/http-parser.git
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
UVDIR=deps/libuv
CANDIR=deps/candor

HTTPDIR=deps/http-parser

# verbose build
export Q=
MAKEFLAGS+=-e

DEPS=${CANDIR}/candor.a \
${HTTPDIR}/http_parser.o \
${UVDIR}/uv.a

LIBS=build/main.o \
build/lhttp_parser.o \
build/cio.o \
build/cio_string.o \
build/luv.o \
Expand All @@ -25,11 +27,15 @@ ${CANDIR}/candor.a: ${CANDIR}/Makefile
${UVDIR}/uv.a: ${UVDIR}/Makefile
$(MAKE) -C ${UVDIR} uv.a

${HTTPDIR}/http_parser.o: ${HTTPDIR}/Makefile
$(MAKE) -C ${HTTPDIR} http_parser.o


build:
mkdir -p build

build/%.o: src/%.cc build src/%.h ${DEPS}
g++ -g -Wall -Werror -c $< -o $@ -I${UVDIR}/include -I${CANDIR}/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
g++ -g -Wall -Werror -c $< -o $@ -I${HTTPDIR} -I${UVDIR}/include -I${CANDIR}/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64

build/canio: ${DEPS} ${LIBS}
g++ -g -o build/canio ${LIBS} ${DEPS} -pthread -lrt
Expand All @@ -40,6 +46,7 @@ clean:
distclean: clean
${MAKE} -C ${CANDIR} clean
${MAKE} -C ${UVDIR} distclean
${MAKE} -C ${HTTPDIR} clean

.PHONY: clean distclean all

1 change: 1 addition & 0 deletions deps/http-parser
Submodule http-parser added at 8bec3e
52 changes: 52 additions & 0 deletions src/lhttp_parser.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "candor.h"
#include "http_parser.h"
#include "lhttp_parser.h"
#include <assert.h>

static Value* ParseUrl(uint32_t argc, Arguments& argv) {
assert(argc >= 1 && argv[0]->Is<String>());
String* str = argv[0]->ToString();
size_t buflen = str->Length();
const char* buf = str->Value();
int is_connect = 0;
if (argc > 1 && argv[1]->Is<Boolean>()) {
is_connect = argv[1]->ToBoolean()->IsTrue() ? 1 : 0;
}
http_parser_url u;
int status = http_parser_parse_url(buf, buflen, is_connect, &u);
if (status) {
return Number::NewIntegral(status);
}

Object* url = Object::New();
if (u.field_set & (1 << UF_SCHEMA)) {
url->Set("schema", String::New(buf + u.field_data[UF_SCHEMA].off, u.field_data[UF_SCHEMA].len));
}
if (u.field_set & (1 << UF_HOST)) {
url->Set("host", String::New(buf + u.field_data[UF_HOST].off, u.field_data[UF_HOST].len));
}
if (u.field_set & (1 << UF_PORT)) {
url->Set("port_string", String::New(buf + u.field_data[UF_PORT].off, u.field_data[UF_PORT].len));
url->Set("port", Number::NewIntegral(u.port));
}
if (u.field_set & (1 << UF_PATH)) {
url->Set("path", String::New(buf + u.field_data[UF_PATH].off, u.field_data[UF_PATH].len));
}
if (u.field_set & (1 << UF_QUERY)) {
url->Set("query", String::New(buf + u.field_data[UF_QUERY].off, u.field_data[UF_QUERY].len));
}
if (u.field_set & (1 << UF_FRAGMENT)) {
url->Set("fragment", String::New(buf + u.field_data[UF_FRAGMENT].off, u.field_data[UF_FRAGMENT].len));
}

return url;
}

void lhttp_parser_init(Object* global) {

Object* http_parser = Object::New();
global->Set("HttpParser", http_parser);
http_parser->Set("parseUrl", Function::New(ParseUrl));

}

10 changes: 10 additions & 0 deletions src/lhttp_parser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef LHTTP_PARSER_H
#define LHTTP_PARSER_H

#include "candor.h"

using namespace candor;

void lhttp_parser_init(Object* global);

#endif
7 changes: 6 additions & 1 deletion src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "main.h"
#include "cio.h"
#include "luv.h"
#include "lhttp_parser.h"

#include <stdio.h> // fprintf
#include <stdlib.h> // abort
Expand Down Expand Up @@ -76,6 +77,9 @@ int main(int argc, char** argv) {
// Inject uv module into global scope
luv_init(*global);

// Inject http_parser
lhttp_parser_init(*global);

code->SetContext(*global);

code->Call(0, NULL);
Expand All @@ -84,4 +88,5 @@ int main(int argc, char** argv) {
uv_run(uv_default_loop());

return 0;
}
}

67 changes: 67 additions & 0 deletions test-http.can
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
print = global.print

// Simple pretty printer
dump = (value) {
type = typeof value
if (type == "nil") {
return "nil"
}
if (type == "boolean" || type == "number") {
return "" + value
}
if (type == "string") {
return '"' + value + '"'
}
if (type == "object") {
keys = keysof value
length = sizeof keys
i = 0
escaped = "{ "
while (i < length) {
key = keys[i]
part = dump(value[key])
escaped = escaped + key + ": " + part
if (i < length - 1) {
escaped = escaped + ", "
}
i++
}
return escaped + " }"
}
if (type == "array") {
length = sizeof value
i = 0
escaped = "[ "
while (i < length) {
escaped = escaped + dump(value[i])
print(escaped)
if (i < length - 1) {
escaped = escaped + ", "
}
i++
}
return escaped + " ]"
}
return "[" + type + "]"
}

// Quick and dirty pretty printer
p = (label, value) {
print(label, dump(value))
}

throw = (err) {
print(err.name + ": " + err.error)
global.exit()
}

// Used to emit on errors when libuv badness happens
check = (status) {
if (status) {
throw(global.uv.lastError())
}
}


url = "http://candor.io:8080/foo/bar/baz.zip?magic=yes#instant"
p("parsed", global.HttpParser.parseUrl(url))

0 comments on commit 7cd757a

Please sign in to comment.