Permalink
Browse files

Add http-parser dependency and bind HttpParser.parseUrl()

  • Loading branch information...
1 parent 6bcfe7e commit 7cd757acddb34d6d702206ca56400f37c14ff9ae @creationix committed Mar 20, 2012
Showing with 148 additions and 3 deletions.
  1. +3 −0 .gitmodules
  2. +9 −2 Makefile
  3. +1 −0 deps/http-parser
  4. +52 −0 src/lhttp_parser.cc
  5. +10 −0 src/lhttp_parser.h
  6. +6 −1 src/main.cc
  7. +67 −0 test-http.can
View
@@ -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
View
@@ -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 \
@@ -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
@@ -40,6 +46,7 @@ clean:
distclean: clean
${MAKE} -C ${CANDIR} clean
${MAKE} -C ${UVDIR} distclean
+ ${MAKE} -C ${HTTPDIR} clean
.PHONY: clean distclean all
Submodule http-parser added at 8bec3e
View
@@ -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));
+
+}
+
View
@@ -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
View
@@ -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
@@ -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);
@@ -84,4 +88,5 @@ int main(int argc, char** argv) {
uv_run(uv_default_loop());
return 0;
-}
+}
+
View
@@ -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.