Permalink
Browse files

Merge commit 'v0.1.93'

  • Loading branch information...
2 parents 6da7ebe + 557ba6b commit 1769ec81e7be7c766d244bc94c10400de7f67a86 Herbert Vojčík committed Apr 30, 2010
View
@@ -66,3 +66,5 @@ Carson McDonald <carson@ioncannon.net>
Julian Lamb <thepurlieu@gmail.com>
Brian Hammond <brian@fictorial.com>
Mathias Pettersson <mape@mape.me>
+Trevor Blackwell <tlb@tlb.org>
+Thomas Lee <tom@tom-debian.sensis.com.au>
View
@@ -1,4 +1,23 @@
-2010.04.23, Version 0.1.92
+2010.04.29, Version 0.1.93
+
+ * Fixed no 'end' event on long chunked HTTP messages
+ http://github.com/ry/node/issues/#issue/77
+
+ * Remove legacy modules http_old and tcp_old
+
+ * Support DNS MX queries (Jérémy Lal)
+
+ * Fix large socket write (tlb@tlb.org)
+
+ * Fix child process exit codes (Felix Geisendörfer)
+
+ * Allow callers to disable PHP/Rails style parameter mungeing in
+ querystring.stringify (Thomas Lee)
+
+ * Upgrade V8 to 2.2.6
+
+
+2010.04.23, Version 0.1.92, caa828a242f39b6158084ef4376355161c14fe34
* OpenSSL support. Still undocumented (see tests). (Rhys Jones)
@@ -1,3 +1,4 @@
tags
*.o
test
+test_g
View
@@ -2,17 +2,23 @@ OPT_DEBUG=-O0 -g -Wall -Wextra -Werror -I.
OPT_FAST=-O3 -DHTTP_PARSER_STRICT=0 -I.
-test: test_debug
- ./test_debug
+test: test_g
+ ./test_g
-test_debug: http_parser_debug.o test.c
- gcc $(OPT_DEBUG) http_parser.o test.c -o $@
+test_g: http_parser_g.o test_g.o
+ gcc $(OPT_DEBUG) http_parser_g.o test_g.o -o $@
-http_parser_debug.o: http_parser.c http_parser.h Makefile
- gcc $(OPT_DEBUG) -c http_parser.c
+test_g.o: test.c Makefile
+ gcc $(OPT_DEBUG) -c test.c -o $@
-test-valgrind: test_debug
- valgrind ./test_debug
+test.o: test.c Makefile
+ gcc $(OPT_FAST) -c test.c -o $@
+
+http_parser_g.o: http_parser.c http_parser.h Makefile
+ gcc $(OPT_DEBUG) -c http_parser.c -o $@
+
+test-valgrind: test_g
+ valgrind ./test_g
http_parser.o: http_parser.c http_parser.h Makefile
gcc $(OPT_FAST) -c http_parser.c
@@ -28,6 +34,6 @@ tags: http_parser.c http_parser.h test.c
ctags $^
clean:
- rm -f *.o test test_fast test_debug http_parser.tar tags
+ rm -f *.o test test_fast test_g http_parser.tar tags
.PHONY: clean package test-run test-run-timed test-valgrind
@@ -195,7 +195,8 @@ enum state
, s_body_identity_eof
};
-#define PARSING_HEADER(state) (state <= s_headers_almost_done)
+
+#define PARSING_HEADER(state) (state <= s_headers_almost_done && 0 == (parser->flags & F_TRAILING))
enum header_states
View
@@ -34,6 +34,8 @@
#define MAX_HEADERS 10
#define MAX_ELEMENT_SIZE 500
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
static http_parser *parser;
struct message {
@@ -47,6 +49,7 @@ struct message {
char fragment[MAX_ELEMENT_SIZE];
char query_string[MAX_ELEMENT_SIZE];
char body[MAX_ELEMENT_SIZE];
+ size_t body_size;
int num_headers;
enum { NONE=0, FIELD, VALUE } last_header_element;
char headers [MAX_HEADERS][2][MAX_ELEMENT_SIZE];
@@ -597,6 +600,7 @@ const struct message responses[] =
,.status_code= 404
,.num_headers= 0
,.headers= {}
+ ,.body_size= 0
,.body= ""
}
@@ -639,6 +643,7 @@ const struct message responses[] =
{ {"Content-Type", "text/plain" }
, {"Transfer-Encoding", "chunked" }
}
+ ,.body_size = 37+28
,.body =
"This is the data in the first chunk\r\n"
"and this is the second one\r\n"
@@ -785,11 +790,21 @@ body_cb (http_parser *p, const char *buf, size_t len)
{
assert(p == parser);
strncat(messages[num_messages].body, buf, len);
+ messages[num_messages].body_size += len;
// printf("body_cb: '%s'\n", requests[num_messages].body);
return 0;
}
int
+count_body_cb (http_parser *p, const char *buf, size_t len)
+{
+ assert(p == parser);
+ assert(buf);
+ messages[num_messages].body_size += len;
+ return 0;
+}
+
+int
message_begin_cb (http_parser *p)
{
assert(p == parser);
@@ -830,7 +845,7 @@ message_complete_cb (http_parser *p)
return 0;
}
-static http_parser_settings settings =
+static http_parser_settings settings =
{.on_message_begin = message_begin_cb
,.on_header_field = header_field_cb
,.on_header_value = header_value_cb
@@ -843,6 +858,19 @@ static http_parser_settings settings =
,.on_message_complete = message_complete_cb
};
+static http_parser_settings settings_count_body =
+ {.on_message_begin = message_begin_cb
+ ,.on_header_field = header_field_cb
+ ,.on_header_value = header_value_cb
+ ,.on_path = request_path_cb
+ ,.on_url = request_url_cb
+ ,.on_fragment = fragment_cb
+ ,.on_query_string = query_string_cb
+ ,.on_body = count_body_cb
+ ,.on_headers_complete = headers_complete_cb
+ ,.on_message_complete = message_complete_cb
+ };
+
void
parser_init (enum http_parser_type type)
{
@@ -874,6 +902,14 @@ inline size_t parse (const char *buf, size_t len)
return nparsed;
}
+inline size_t parse_count_body (const char *buf, size_t len)
+{
+ size_t nparsed;
+ currently_parsing_eof = (len == 0);
+ nparsed = http_parser_execute(parser, settings_count_body, buf, len);
+ return nparsed;
+}
+
static inline int
check_str_eq (const struct message *m,
const char *prop,
@@ -936,7 +972,11 @@ message_eq (int index, const struct message *expected)
MESSAGE_CHECK_STR_EQ(expected, m, query_string);
MESSAGE_CHECK_STR_EQ(expected, m, fragment);
MESSAGE_CHECK_STR_EQ(expected, m, request_url);
- MESSAGE_CHECK_STR_EQ(expected, m, body);
+ if (expected->body_size) {
+ MESSAGE_CHECK_NUM_EQ(expected, m, body_size);
+ } else {
+ MESSAGE_CHECK_STR_EQ(expected, m, body);
+ }
MESSAGE_CHECK_NUM_EQ(expected, m, num_headers);
@@ -1031,6 +1071,42 @@ test_message (const struct message *message)
}
void
+test_message_count_body (const struct message *message)
+{
+ parser_init(message->type);
+
+ size_t read;
+ size_t l = strlen(message->raw);
+ size_t i, toread;
+ size_t chunk = 4024;
+
+ for (i = 0; i < l; i+= chunk) {
+ toread = MIN(l-i, chunk);
+ read = parse_count_body(message->raw + i, toread);
+ if (read != toread) {
+ print_error(message->raw, read);
+ exit(1);
+ }
+ }
+
+
+ read = parse_count_body(NULL, 0);
+ if (read != 0) {
+ print_error(message->raw, read);
+ exit(1);
+ }
+
+ if (num_messages != 1) {
+ printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name);
+ exit(1);
+ }
+
+ if(!message_eq(0, message)) exit(1);
+
+ parser_free();
+}
+
+void
test_error (const char *buf)
{
parser_init(HTTP_REQUEST);
@@ -1214,6 +1290,50 @@ test_scan (const struct message *r1, const struct message *r2, const struct mess
exit(1);
}
+// user required to free the result
+// string terminated by \0
+char *
+create_large_chunked_message (int body_size_in_kb, const char* headers)
+{
+ int i;
+ size_t needed, wrote = 0;
+ size_t headers_len = strlen(headers);
+ size_t bufsize = headers_len + 10;
+ char * buf = malloc(bufsize);
+
+ strncpy(buf, headers, headers_len);
+ wrote += headers_len;
+
+ for (i = 0; i < body_size_in_kb; i++) {
+ // write 1kb chunk into the body.
+ needed = 5 + 1024 + 2; // "400\r\nCCCC...CCCC\r\n"
+ if (bufsize - wrote < needed) {
+ buf = realloc(buf, bufsize + needed);
+ bufsize += needed;
+ }
+
+ strcpy(buf + wrote, "400\r\n");
+ wrote += 5;
+ memset(buf + wrote, 'C', 1024);
+ wrote += 1024;
+ strcpy(buf + wrote, "\r\n");
+ wrote += 2;
+ }
+
+ needed = 5; // "0\r\n\r\n"
+ if (bufsize - wrote < needed) {
+ buf = realloc(buf, bufsize + needed);
+ bufsize += needed;
+ }
+ strcpy(buf + wrote, "0\r\n\r\n");
+ wrote += 5;
+
+ assert(buf[wrote] == 0);
+
+ return buf;
+}
+
+
int
main (void)
{
@@ -1243,6 +1363,38 @@ main (void)
}
}
+ test_message_count_body(&responses[NO_HEADERS_NO_BODY_404]);
+ test_message_count_body(&responses[TRAILING_SPACE_ON_CHUNKED_BODY]);
+
+ // test very large chunked response
+ {
+ char * msg = create_large_chunked_message(31337,
+ "HTTP/1.0 200 OK\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "Content-Type: text/plain\r\n"
+ "\r\n");
+ struct message large_chunked =
+ {.name= "large chunked"
+ ,.type= HTTP_RESPONSE
+ ,.raw= msg
+ ,.should_keep_alive= FALSE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 0
+ ,.status_code= 200
+ ,.num_headers= 2
+ ,.headers=
+ { { "Transfer-Encoding", "chunked" }
+ , { "Content-Type", "text/plain" }
+ }
+ ,.body_size= 31337*1024
+ };
+ test_message_count_body(&large_chunked);
+ free(msg);
+ }
+
+
+
printf("response scan 1/1 ");
test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY]
, &responses[NO_HEADERS_NO_BODY_404]
View
@@ -2380,7 +2380,7 @@ is no '.' then it returns an empty string. Examples:
Test whether or not the given path exists. Then, call the `callback` argument with either true or false. Example:
path.exists('/etc/passwd', function (exists) {
- sys.debug(exists ? 'it's there' : 'no passwd!');
+ sys.debug(exists ? "it's there" : "no passwd!");
});
View
@@ -295,7 +295,7 @@
<body>
<div id="toc">
- <div id="toctitle">Node v0.1.92</div>
+ <div id="toctitle">Node v0.1.93</div>
<noscript>JavaScript must be enabled in your browser to display the table of contents.</noscript>
</div>
<div id='man'>
View
@@ -95,8 +95,8 @@ <h2 id="download">Download</h2>
<a href="http://github.com/ry/node/tree/master">git repo</a>
</p>
<p>
- 2010.04.23
- <a href="http://nodejs.org/dist/node-v0.1.92.tar.gz">node-v0.1.92.tar.gz</a>
+ 2010.04.29
+ <a href="http://nodejs.org/dist/node-v0.1.93.tar.gz">node-v0.1.93.tar.gz</a>
</p>
<p>Historical: <a href="http://nodejs.org/dist">versions</a>, <a href="http://nodejs.org/docs">docs</a></p>
View
@@ -504,8 +504,15 @@ Stream.prototype.write = function (data, encoding) {
if (this._writeQueueLast() === END_OF_FILE) {
throw new Error('Stream.close() called already; cannot write.');
}
- this._writeQueue.push(data); // TODO if string of the same encoding concat?
- this._writeQueueEncoding.push(encoding);
+
+ if (typeof data == 'string' &&
+ this._writeQueueEncoding[this._writeQueueEncoding.length-1] === encoding) {
+ // optimization - concat onto last
+ this._writeQueue[this._writeQueue.length-1] += data;
+ } else {
+ this._writeQueue.push(data);
+ this._writeQueueEncoding.push(encoding);
+ }
return false;
} else {
// Fast.
@@ -12,7 +12,7 @@ var chargen = http.createServer(function (req, res) {
assert.ok(len > 0);
res.writeHead(200, {"transfer-encoding":"chunked"});
for (var i=0; i<len; i++) {
- //print(',');
+ if (i % 1000 == 0) print(',');
res.write(chunk);
}
res.end();
@@ -38,8 +38,10 @@ var proxy = http.createServer(function (req, res) {
proxy_req.addListener('response', function(proxy_res) {
res.writeHead(proxy_res.statusCode, proxy_res.headers);
+ var count = 0;
+
proxy_res.addListener('data', function(d) {
- //print('.');
+ if (count++ % 1000 == 0) print('.');
res.write(d);
sent += d.length;
assert.ok(sent <= (len*chunk.length));
Oops, something went wrong.

0 comments on commit 1769ec8

Please sign in to comment.