diff --git a/AUTHORS b/AUTHORS
index d0beefff9c..38de58b7cc 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -300,3 +300,4 @@ Aaron Jacobs
Mustansir Golawala
fukayatsu
Domenic Denicola
+Bryan Cantrill
diff --git a/ChangeLog b/ChangeLog
index f1aaa7d10f..1d4f8667d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -255,6 +255,52 @@
* Bug fixes
+2012.04.09 Version 0.6.15 (stable)
+
+* Update npm to 1.1.16
+
+* Show licenses in binary installers.
+
+* unix: add uv_fs_read64, uv_fs_write64 and uv_fs_ftruncate64 (Ben Noordhuis)
+
+* add 64bit offset fs functions (Igor Zinkovsky)
+
+* windows: don't report ENOTSOCK when attempting to bind an udp handle twice (Bert Belder)
+
+* windows: backport pipe-connect-to-file fixes from master (Bert Belder)
+
+* windows: never call fs event callbacks after closing the watcher (Bert Belder)
+
+* fs.readFile: don't make the callback before the fd is closed (Bert Belder)
+
+* windows: use 64bit offsets for uv_fs apis (Igor Zinkovsky)
+
+* Fix #2061: segmentation fault on OS X due to stat size mismatch (Ben Noordhuis)
+
+
+2012.03.22 Version 0.6.14 (stable), e513ffef7549a56a5af728e1f0c2c0c8f290518a
+
+* net: don't crash when queued write fails (Igor Zinkovsky)
+
+* sunos: fix EMFILE on process.memoryUsage() (Bryan Cantrill)
+
+* crypto: fix compile-time error with openssl 0.9.7e (Ben Noordhuis)
+
+* unix: ignore ECONNABORTED errors from accept() (Ben Noordhuis)
+
+* Add UV_ENOSPC and mappings to it (Bert Belder)
+
+* http-parser: Fix response body is not read (koichik)
+
+* Upgrade npm to 1.1.12
+ - upgrade node-gyp to 0.3.7
+ - work around AV-locked directories on Windows
+ - Fix isaacs/npm#2293 Don't try to 'uninstall' /
+ - Exclude symbolic links from packages.
+ - Fix isaacs/npm#2275 Spurious 'unresolvable cycle' error.
+ - Exclude/include dot files as if they were normal files
+
+
2012.03.15 Version 0.6.13 (stable), 9f7f86b534f8556290eb8cad915984ff4ca54996
* Windows: Many libuv test fixes (Bert Belder)
diff --git a/LICENSE b/LICENSE
index 3f7393c44c..a6bc8813ea 100644
--- a/LICENSE
+++ b/LICENSE
@@ -361,13 +361,6 @@ maintained libraries. The externally maintained libraries used by Node are:
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- # Here are some issues that I've had people identify in my code during reviews,
- # that I think are possible to flag automatically in a lint tool. If these were
- # caught by lint, it would save time both for myself and that of my reviewers.
- # Most likely, some of these are beyond the scope of the current lint framework,
- # but I think it is valuable to retain these wish-list items even if they cannot
- # be immediately implemented.
"""
- lib/buffer_ieee754.js. Its license follows:
diff --git a/Makefile b/Makefile
index 56cb631b05..c6e2e09a24 100644
--- a/Makefile
+++ b/Makefile
@@ -150,6 +150,13 @@ blog.html: email.md
website-upload: doc
rsync -r out/doc/ node@nodejs.org:~/web/nodejs.org/
+ ssh node@nodejs.org '\
+ rm -f ~/web/nodejs.org/dist/latest &&\
+ ln -s $(VERSION) ~/web/nodejs.org/dist/latest &&\
+ rm -f ~/web/nodejs.org/docs/latest &&\
+ ln -s $(VERSION) ~/web/nodejs.org/docs/latest &&\
+ rm -f ~/web/nodejs.org/dist/node-latest.tar.gz &&\
+ ln -s $(VERSION)/node-$(VERSION).tar.gz ~/web/nodejs.org/dist/node-latest.tar.gz'
docopen: out/doc/api/all.html
-google-chrome out/doc/api/all.html
diff --git a/deps/http_parser/test.c b/deps/http_parser/test.c
index db4fc32e39..6af0e787e9 100644
--- a/deps/http_parser/test.c
+++ b/deps/http_parser/test.c
@@ -44,13 +44,9 @@ struct message {
enum http_parser_type type;
enum http_method method;
int status_code;
- char request_path[MAX_ELEMENT_SIZE];
char request_url[MAX_ELEMENT_SIZE];
- char fragment[MAX_ELEMENT_SIZE];
- char query_string[MAX_ELEMENT_SIZE];
char body[MAX_ELEMENT_SIZE];
size_t body_size;
- uint16_t port;
int num_headers;
enum { NONE=0, FIELD, VALUE } last_header_element;
char headers [MAX_HEADERS][2][MAX_ELEMENT_SIZE];
@@ -71,7 +67,6 @@ static int currently_parsing_eof;
static struct message messages[5];
static int num_messages;
-static http_parser_settings *current_pause_parser;
/* * R E Q U E S T S * */
const struct message requests[] =
@@ -88,9 +83,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/test"
,.request_url= "/test"
,.num_headers= 3
,.headers=
@@ -119,9 +111,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/favicon.ico"
,.request_url= "/favicon.ico"
,.num_headers= 8
,.headers=
@@ -148,9 +137,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/dumbfuck"
,.request_url= "/dumbfuck"
,.num_headers= 1
,.headers=
@@ -169,9 +155,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= "page=1"
- ,.fragment= "posts-17408"
- ,.request_path= "/forums/1/topics/2375"
/* XXX request url does include fragment? */
,.request_url= "/forums/1/topics/2375?page=1#posts-17408"
,.num_headers= 0
@@ -188,9 +171,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/get_no_headers_no_body/world"
,.request_url= "/get_no_headers_no_body/world"
,.num_headers= 0
,.body= ""
@@ -207,9 +187,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/get_one_header_no_body"
,.request_url= "/get_one_header_no_body"
,.num_headers= 1
,.headers=
@@ -230,9 +207,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 0
,.method= HTTP_GET
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/get_funky_content_length_body_hello"
,.request_url= "/get_funky_content_length_body_hello"
,.num_headers= 1
,.headers=
@@ -255,9 +229,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_POST
- ,.query_string= "q=search"
- ,.fragment= "hey"
- ,.request_path= "/post_identity_body_world"
,.request_url= "/post_identity_body_world?q=search#hey"
,.num_headers= 3
,.headers=
@@ -282,9 +253,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_POST
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/post_chunked_all_your_base"
,.request_url= "/post_chunked_all_your_base"
,.num_headers= 1
,.headers=
@@ -308,9 +276,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_POST
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/two_chunks_mult_zero_end"
,.request_url= "/two_chunks_mult_zero_end"
,.num_headers= 1
,.headers=
@@ -336,9 +301,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_POST
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/chunked_w_trailing_headers"
,.request_url= "/chunked_w_trailing_headers"
,.num_headers= 3
,.headers=
@@ -364,9 +326,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_POST
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/chunked_w_bullshit_after_length"
,.request_url= "/chunked_w_bullshit_after_length"
,.num_headers= 1
,.headers=
@@ -384,9 +343,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= "foo=\"bar\""
- ,.fragment= ""
- ,.request_path= "/with_\"stupid\"_quotes"
,.request_url= "/with_\"stupid\"_quotes?foo=\"bar\""
,.num_headers= 0
,.headers= { }
@@ -410,9 +366,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 0
,.method= HTTP_GET
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/test"
,.request_url= "/test"
,.num_headers= 3
,.headers= { { "Host", "0.0.0.0:5000" }
@@ -433,9 +386,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= "foo=bar?baz"
- ,.fragment= ""
- ,.request_path= "/test.cgi"
,.request_url= "/test.cgi?foo=bar?baz"
,.num_headers= 0
,.headers= {}
@@ -454,9 +404,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/test"
,.request_url= "/test"
,.num_headers= 0
,.headers= { }
@@ -481,9 +428,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/demo"
,.request_url= "/demo"
,.num_headers= 7
,.upgrade="Hot diggity dogg"
@@ -512,9 +456,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 0
,.method= HTTP_CONNECT
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= ""
,.request_url= "0-home0.netscape.com:443"
,.num_headers= 2
,.upgrade="some data\r\nand yet even more data"
@@ -534,9 +475,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_REPORT
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/test"
,.request_url= "/test"
,.num_headers= 0
,.headers= {}
@@ -553,9 +491,6 @@ const struct message requests[] =
,.http_major= 0
,.http_minor= 9
,.method= HTTP_GET
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/"
,.request_url= "/"
,.num_headers= 0
,.headers= {}
@@ -575,9 +510,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_MSEARCH
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "*"
,.request_url= "*"
,.num_headers= 3
,.headers= { { "HOST", "239.255.255.250:1900" }
@@ -587,7 +519,7 @@ const struct message requests[] =
,.body= ""
}
-#define LINE_FOLDING_IN_HEADER 21
+#define LINE_FOLDING_IN_HEADER 20
, {.name= "line folding in header value"
,.type= HTTP_REQUEST
,.raw= "GET / HTTP/1.1\r\n"
@@ -604,9 +536,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/"
,.request_url= "/"
,.num_headers= 2
,.headers= { { "Line1", "abcdefghijklmno qrs" }
@@ -616,7 +545,7 @@ const struct message requests[] =
}
-#define QUERY_TERMINATED_HOST 22
+#define QUERY_TERMINATED_HOST 21
, {.name= "host terminated by a query string"
,.type= HTTP_REQUEST
,.raw= "GET http://hypnotoad.org?hail=all HTTP/1.1\r\n"
@@ -626,16 +555,13 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= "hail=all"
- ,.fragment= ""
- ,.request_path= ""
,.request_url= "http://hypnotoad.org?hail=all"
,.num_headers= 0
,.headers= { }
,.body= ""
}
-#define QUERY_TERMINATED_HOSTPORT 23
+#define QUERY_TERMINATED_HOSTPORT 22
, {.name= "host:port terminated by a query string"
,.type= HTTP_REQUEST
,.raw= "GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n"
@@ -645,17 +571,13 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= "hail=all"
- ,.fragment= ""
- ,.request_path= ""
,.request_url= "http://hypnotoad.org:1234?hail=all"
- ,.port= 1234
,.num_headers= 0
,.headers= { }
,.body= ""
}
-#define SPACE_TERMINATED_HOSTPORT 24
+#define SPACE_TERMINATED_HOSTPORT 23
, {.name= "host:port terminated by a space"
,.type= HTTP_REQUEST
,.raw= "GET http://hypnotoad.org:1234 HTTP/1.1\r\n"
@@ -665,70 +587,14 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= ""
,.request_url= "http://hypnotoad.org:1234"
- ,.port= 1234
,.num_headers= 0
,.headers= { }
,.body= ""
}
-#define PATCH_REQ 25
-, {.name = "PATCH request"
- ,.type= HTTP_REQUEST
- ,.raw= "PATCH /file.txt HTTP/1.1\r\n"
- "Host: www.example.com\r\n"
- "Content-Type: application/example\r\n"
- "If-Match: \"e0023aa4e\"\r\n"
- "Content-Length: 10\r\n"
- "\r\n"
- "cccccccccc"
- ,.should_keep_alive= TRUE
- ,.message_complete_on_eof= FALSE
- ,.http_major= 1
- ,.http_minor= 1
- ,.method= HTTP_PATCH
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/file.txt"
- ,.request_url= "/file.txt"
- ,.num_headers= 4
- ,.headers= { { "Host", "www.example.com" }
- , { "Content-Type", "application/example" }
- , { "If-Match", "\"e0023aa4e\"" }
- , { "Content-Length", "10" }
- }
- ,.body= "cccccccccc"
- }
-
-#define CONNECT_CAPS_REQUEST 26
-, {.name = "connect caps request"
- ,.type= HTTP_REQUEST
- ,.raw= "CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\n"
- "User-agent: Mozilla/1.1N\r\n"
- "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n"
- "\r\n"
- ,.should_keep_alive= FALSE
- ,.message_complete_on_eof= FALSE
- ,.http_major= 1
- ,.http_minor= 0
- ,.method= HTTP_CONNECT
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= ""
- ,.request_url= "HOME0.NETSCAPE.COM:443"
- ,.num_headers= 2
- ,.upgrade=""
- ,.headers= { { "User-agent", "Mozilla/1.1N" }
- , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" }
- }
- ,.body= ""
- }
-
#if !HTTP_PARSER_STRICT
-#define UTF8_PATH_REQ 27
+#define UTF8_PATH_REQ 24
, {.name= "utf-8 path request"
,.type= HTTP_REQUEST
,.raw= "GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\n"
@@ -739,9 +605,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
- ,.query_string= "q=1"
- ,.fragment= "narf"
- ,.request_path= "/δ¶/δt/pope"
,.request_url= "/δ¶/δt/pope?q=1#narf"
,.num_headers= 1
,.headers= { {"Host", "github.com" }
@@ -749,7 +612,7 @@ const struct message requests[] =
,.body= ""
}
-#define HOSTNAME_UNDERSCORE 28
+#define HOSTNAME_UNDERSCORE 25
, {.name = "hostname underscore"
,.type= HTTP_REQUEST
,.raw= "CONNECT home_0.netscape.com:443 HTTP/1.0\r\n"
@@ -761,9 +624,6 @@ const struct message requests[] =
,.http_major= 1
,.http_minor= 0
,.method= HTTP_CONNECT
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= ""
,.request_url= "home_0.netscape.com:443"
,.num_headers= 2
,.upgrade=""
@@ -774,99 +634,49 @@ const struct message requests[] =
}
#endif /* !HTTP_PARSER_STRICT */
-/* see https://github.com/ry/http-parser/issues/47 */
-#define EAT_TRAILING_CRLF_NO_CONNECTION_CLOSE 29
-, {.name = "eat CRLF between requests, no \"Connection: close\" header"
- ,.raw= "POST / HTTP/1.1\r\n"
+#define PATCH_REQ 26
+, {.name = "PATCH request"
+ ,.type= HTTP_REQUEST
+ ,.raw= "PATCH /file.txt HTTP/1.1\r\n"
"Host: www.example.com\r\n"
- "Content-Type: application/x-www-form-urlencoded\r\n"
- "Content-Length: 4\r\n"
+ "Content-Type: application/example\r\n"
+ "If-Match: \"e0023aa4e\"\r\n"
+ "Content-Length: 10\r\n"
"\r\n"
- "q=42\r\n" /* note the trailing CRLF */
+ "cccccccccc"
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
- ,.method= HTTP_POST
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/"
- ,.request_url= "/"
- ,.num_headers= 3
- ,.upgrade= 0
- ,.headers= { { "Host", "www.example.com" }
- , { "Content-Type", "application/x-www-form-urlencoded" }
- , { "Content-Length", "4" }
- }
- ,.body= "q=42"
- }
-
-/* see https://github.com/ry/http-parser/issues/47 */
-#define EAT_TRAILING_CRLF_WITH_CONNECTION_CLOSE 30
-, {.name = "eat CRLF between requests even if \"Connection: close\" is set"
- ,.raw= "POST / HTTP/1.1\r\n"
- "Host: www.example.com\r\n"
- "Content-Type: application/x-www-form-urlencoded\r\n"
- "Content-Length: 4\r\n"
- "Connection: close\r\n"
- "\r\n"
- "q=42\r\n" /* note the trailing CRLF */
- ,.should_keep_alive= FALSE
- ,.message_complete_on_eof= FALSE /* input buffer isn't empty when on_message_complete is called */
- ,.http_major= 1
- ,.http_minor= 1
- ,.method= HTTP_POST
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/"
- ,.request_url= "/"
+ ,.method= HTTP_PATCH
+ ,.request_url= "/file.txt"
,.num_headers= 4
- ,.upgrade= 0
,.headers= { { "Host", "www.example.com" }
- , { "Content-Type", "application/x-www-form-urlencoded" }
- , { "Content-Length", "4" }
- , { "Connection", "close" }
+ , { "Content-Type", "application/example" }
+ , { "If-Match", "\"e0023aa4e\"" }
+ , { "Content-Length", "10" }
}
- ,.body= "q=42"
- }
-
-#define PURGE_REQ 31
-, {.name = "PURGE request"
- ,.type= HTTP_REQUEST
- ,.raw= "PURGE /file.txt HTTP/1.1\r\n"
- "Host: www.example.com\r\n"
- "\r\n"
- ,.should_keep_alive= TRUE
- ,.message_complete_on_eof= FALSE
- ,.http_major= 1
- ,.http_minor= 1
- ,.method= HTTP_PURGE
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/file.txt"
- ,.request_url= "/file.txt"
- ,.num_headers= 1
- ,.headers= { { "Host", "www.example.com" } }
- ,.body= ""
+ ,.body= "cccccccccc"
}
-#define SEARCH_REQ 32
-, {.name = "SEARCH request"
+#define CONNECT_CAPS_REQUEST 27
+, {.name = "connect caps request"
,.type= HTTP_REQUEST
- ,.raw= "SEARCH / HTTP/1.1\r\n"
- "Host: www.example.com\r\n"
+ ,.raw= "CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\n"
+ "User-agent: Mozilla/1.1N\r\n"
+ "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n"
"\r\n"
- ,.should_keep_alive= TRUE
+ ,.should_keep_alive= FALSE
,.message_complete_on_eof= FALSE
,.http_major= 1
- ,.http_minor= 1
- ,.method= HTTP_SEARCH
- ,.query_string= ""
- ,.fragment= ""
- ,.request_path= "/"
- ,.request_url= "/"
- ,.num_headers= 1
- ,.headers= { { "Host", "www.example.com" } }
+ ,.http_minor= 0
+ ,.method= HTTP_CONNECT
+ ,.request_url= "HOME0.NETSCAPE.COM:443"
+ ,.num_headers= 2
+ ,.upgrade=""
+ ,.headers= { { "User-agent", "Mozilla/1.1N" }
+ , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" }
+ }
,.body= ""
}
@@ -970,8 +780,8 @@ const struct message responses[] =
, {.name= "404 no headers no body"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 404 Not Found\r\n\r\n"
- ,.should_keep_alive= FALSE
- ,.message_complete_on_eof= TRUE
+ ,.should_keep_alive= TRUE
+ ,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.status_code= 404
@@ -985,8 +795,8 @@ const struct message responses[] =
, {.name= "301 no response phrase"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 301\r\n\r\n"
- ,.should_keep_alive = FALSE
- ,.message_complete_on_eof= TRUE
+ ,.should_keep_alive = TRUE
+ ,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.status_code= 301
@@ -1135,7 +945,40 @@ const struct message responses[] =
,.body= ""
}
-#define RES_FIELD_UNDERSCORE 9
+#define SPACE_IN_FIELD_RES 9
+/* Should handle spaces in header fields */
+, {.name= "field space"
+ ,.type= HTTP_RESPONSE
+ ,.raw= "HTTP/1.1 200 OK\r\n"
+ "Server: Microsoft-IIS/6.0\r\n"
+ "X-Powered-By: ASP.NET\r\n"
+ "en-US Content-Type: text/xml\r\n" /* this is the problem */
+ "Content-Type: text/xml\r\n"
+ "Content-Length: 16\r\n"
+ "Date: Fri, 23 Jul 2010 18:45:38 GMT\r\n"
+ "Connection: keep-alive\r\n"
+ "\r\n"
+ "hello" /* fake body */
+ ,.should_keep_alive= TRUE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 1
+ ,.status_code= 200
+ ,.num_headers= 7
+ ,.headers=
+ { { "Server", "Microsoft-IIS/6.0" }
+ , { "X-Powered-By", "ASP.NET" }
+ , { "en-US Content-Type", "text/xml" }
+ , { "Content-Type", "text/xml" }
+ , { "Content-Length", "16" }
+ , { "Date", "Fri, 23 Jul 2010 18:45:38 GMT" }
+ , { "Connection", "keep-alive" }
+ }
+ ,.body= "hello"
+ }
+
+
+#define RES_FIELD_UNDERSCORE 10
/* Should handle spaces in header fields */
, {.name= "field underscore"
,.type= HTTP_RESPONSE
@@ -1175,7 +1018,7 @@ const struct message responses[] =
,.body= ""
}
-#define NON_ASCII_IN_STATUS_LINE 10
+#define NON_ASCII_IN_STATUS_LINE 11
/* Should handle non-ASCII in status line */
, {.name= "non-ASCII in status line"
,.type= HTTP_RESPONSE
@@ -1198,7 +1041,7 @@ const struct message responses[] =
,.body= ""
}
-#define HTTP_VERSION_0_9 11
+#define HTTP_VERSION_0_9 12
/* Should handle HTTP/0.9 */
, {.name= "http version 0.9"
,.type= HTTP_RESPONSE
@@ -1214,175 +1057,8 @@ const struct message responses[] =
{}
,.body= ""
}
-
-#define NO_CONTENT_LENGTH_NO_TRANSFER_ENCODING_RESPONSE 12
-/* The client should wait for the server's EOF. That is, when neither
- * content-length nor transfer-encoding is specified, the end of body
- * is specified by the EOF.
- */
-, {.name= "neither content-length nor transfer-encoding response"
- ,.type= HTTP_RESPONSE
- ,.raw= "HTTP/1.1 200 OK\r\n"
- "Content-Type: text/plain\r\n"
- "\r\n"
- "hello world"
- ,.should_keep_alive= FALSE
- ,.message_complete_on_eof= TRUE
- ,.http_major= 1
- ,.http_minor= 1
- ,.status_code= 200
- ,.num_headers= 1
- ,.headers=
- { { "Content-Type", "text/plain" }
- }
- ,.body= "hello world"
- }
-
-#define NO_BODY_HTTP10_KA_200 13
-, {.name= "HTTP/1.0 with keep-alive and EOF-terminated 200 status"
- ,.type= HTTP_RESPONSE
- ,.raw= "HTTP/1.0 200 OK\r\n"
- "Connection: keep-alive\r\n"
- "\r\n"
- ,.should_keep_alive= FALSE
- ,.message_complete_on_eof= TRUE
- ,.http_major= 1
- ,.http_minor= 0
- ,.status_code= 200
- ,.num_headers= 1
- ,.headers=
- { { "Connection", "keep-alive" }
- }
- ,.body_size= 0
- ,.body= ""
- }
-
-#define NO_BODY_HTTP10_KA_204 14
-, {.name= "HTTP/1.0 with keep-alive and a 204 status"
- ,.type= HTTP_RESPONSE
- ,.raw= "HTTP/1.0 204 No content\r\n"
- "Connection: keep-alive\r\n"
- "\r\n"
- ,.should_keep_alive= TRUE
- ,.message_complete_on_eof= FALSE
- ,.http_major= 1
- ,.http_minor= 0
- ,.status_code= 204
- ,.num_headers= 1
- ,.headers=
- { { "Connection", "keep-alive" }
- }
- ,.body_size= 0
- ,.body= ""
- }
-
-#define NO_BODY_HTTP11_KA_200 15
-, {.name= "HTTP/1.1 with an EOF-terminated 200 status"
- ,.type= HTTP_RESPONSE
- ,.raw= "HTTP/1.1 200 OK\r\n"
- "\r\n"
- ,.should_keep_alive= FALSE
- ,.message_complete_on_eof= TRUE
- ,.http_major= 1
- ,.http_minor= 1
- ,.status_code= 200
- ,.num_headers= 0
- ,.headers={}
- ,.body_size= 0
- ,.body= ""
- }
-
-#define NO_BODY_HTTP11_KA_204 16
-, {.name= "HTTP/1.1 with a 204 status"
- ,.type= HTTP_RESPONSE
- ,.raw= "HTTP/1.1 204 No content\r\n"
- "\r\n"
- ,.should_keep_alive= TRUE
- ,.message_complete_on_eof= FALSE
- ,.http_major= 1
- ,.http_minor= 1
- ,.status_code= 204
- ,.num_headers= 0
- ,.headers={}
- ,.body_size= 0
- ,.body= ""
- }
-
-#define NO_BODY_HTTP11_NOKA_204 17
-, {.name= "HTTP/1.1 with a 204 status and keep-alive disabled"
- ,.type= HTTP_RESPONSE
- ,.raw= "HTTP/1.1 204 No content\r\n"
- "Connection: close\r\n"
- "\r\n"
- ,.should_keep_alive= FALSE
- ,.message_complete_on_eof= FALSE
- ,.http_major= 1
- ,.http_minor= 1
- ,.status_code= 204
- ,.num_headers= 1
- ,.headers=
- { { "Connection", "close" }
- }
- ,.body_size= 0
- ,.body= ""
- }
-
-#define NO_BODY_HTTP11_KA_CHUNKED_200 18
-, {.name= "HTTP/1.1 with chunked endocing and a 200 response"
- ,.type= HTTP_RESPONSE
- ,.raw= "HTTP/1.1 200 OK\r\n"
- "Transfer-Encoding: chunked\r\n"
- "\r\n"
- "0\r\n"
- "\r\n"
- ,.should_keep_alive= TRUE
- ,.message_complete_on_eof= FALSE
- ,.http_major= 1
- ,.http_minor= 1
- ,.status_code= 200
- ,.num_headers= 1
- ,.headers=
- { { "Transfer-Encoding", "chunked" }
- }
- ,.body_size= 0
- ,.body= ""
- }
-
-#if !HTTP_PARSER_STRICT
-#define SPACE_IN_FIELD_RES 19
-/* Should handle spaces in header fields */
-, {.name= "field space"
- ,.type= HTTP_RESPONSE
- ,.raw= "HTTP/1.1 200 OK\r\n"
- "Server: Microsoft-IIS/6.0\r\n"
- "X-Powered-By: ASP.NET\r\n"
- "en-US Content-Type: text/xml\r\n" /* this is the problem */
- "Content-Type: text/xml\r\n"
- "Content-Length: 16\r\n"
- "Date: Fri, 23 Jul 2010 18:45:38 GMT\r\n"
- "Connection: keep-alive\r\n"
- "\r\n"
- "hello" /* fake body */
- ,.should_keep_alive= TRUE
- ,.message_complete_on_eof= FALSE
- ,.http_major= 1
- ,.http_minor= 1
- ,.status_code= 200
- ,.num_headers= 7
- ,.headers=
- { { "Server", "Microsoft-IIS/6.0" }
- , { "X-Powered-By", "ASP.NET" }
- , { "en-US Content-Type", "text/xml" }
- , { "Content-Type", "text/xml" }
- , { "Content-Length", "16" }
- , { "Date", "Fri, 23 Jul 2010 18:45:38 GMT" }
- , { "Connection", "keep-alive" }
- }
- ,.body= "hello"
- }
-#endif /* !HTTP_PARSER_STRICT */
-
, {.name= NULL } /* sentinel */
+
};
int
@@ -1472,7 +1148,7 @@ message_complete_cb (http_parser *p)
"value in both on_message_complete and on_headers_complete "
"but it doesn't! ***\n\n");
assert(0);
- abort();
+ exit(1);
}
messages[num_messages].message_complete_cb_called = TRUE;
@@ -1482,146 +1158,6 @@ message_complete_cb (http_parser *p)
return 0;
}
-/* These dontcall_* callbacks exist so that we can verify that when we're
- * paused, no additional callbacks are invoked */
-int
-dontcall_message_begin_cb (http_parser *p)
-{
- if (p) { } // gcc
- fprintf(stderr, "\n\n*** on_message_begin() called on paused parser ***\n\n");
- abort();
-}
-
-int
-dontcall_header_field_cb (http_parser *p, const char *buf, size_t len)
-{
- if (p || buf || len) { } // gcc
- fprintf(stderr, "\n\n*** on_header_field() called on paused parser ***\n\n");
- abort();
-}
-
-int
-dontcall_header_value_cb (http_parser *p, const char *buf, size_t len)
-{
- if (p || buf || len) { } // gcc
- fprintf(stderr, "\n\n*** on_header_value() called on paused parser ***\n\n");
- abort();
-}
-
-int
-dontcall_request_url_cb (http_parser *p, const char *buf, size_t len)
-{
- if (p || buf || len) { } // gcc
- fprintf(stderr, "\n\n*** on_request_url() called on paused parser ***\n\n");
- abort();
-}
-
-int
-dontcall_body_cb (http_parser *p, const char *buf, size_t len)
-{
- if (p || buf || len) { } // gcc
- fprintf(stderr, "\n\n*** on_body_cb() called on paused parser ***\n\n");
- abort();
-}
-
-int
-dontcall_headers_complete_cb (http_parser *p)
-{
- if (p) { } // gcc
- fprintf(stderr, "\n\n*** on_headers_complete() called on paused "
- "parser ***\n\n");
- abort();
-}
-
-int
-dontcall_message_complete_cb (http_parser *p)
-{
- if (p) { } // gcc
- fprintf(stderr, "\n\n*** on_message_complete() called on paused "
- "parser ***\n\n");
- abort();
-}
-
-static http_parser_settings settings_dontcall =
- {.on_message_begin = dontcall_message_begin_cb
- ,.on_header_field = dontcall_header_field_cb
- ,.on_header_value = dontcall_header_value_cb
- ,.on_url = dontcall_request_url_cb
- ,.on_body = dontcall_body_cb
- ,.on_headers_complete = dontcall_headers_complete_cb
- ,.on_message_complete = dontcall_message_complete_cb
- };
-
-/* These pause_* callbacks always pause the parser and just invoke the regular
- * callback that tracks content. Before returning, we overwrite the parser
- * settings to point to the _dontcall variety so that we can verify that
- * the pause actually did, you know, pause. */
-int
-pause_message_begin_cb (http_parser *p)
-{
- http_parser_pause(p, 1);
- *current_pause_parser = settings_dontcall;
- return message_begin_cb(p);
-}
-
-int
-pause_header_field_cb (http_parser *p, const char *buf, size_t len)
-{
- http_parser_pause(p, 1);
- *current_pause_parser = settings_dontcall;
- return header_field_cb(p, buf, len);
-}
-
-int
-pause_header_value_cb (http_parser *p, const char *buf, size_t len)
-{
- http_parser_pause(p, 1);
- *current_pause_parser = settings_dontcall;
- return header_value_cb(p, buf, len);
-}
-
-int
-pause_request_url_cb (http_parser *p, const char *buf, size_t len)
-{
- http_parser_pause(p, 1);
- *current_pause_parser = settings_dontcall;
- return request_url_cb(p, buf, len);
-}
-
-int
-pause_body_cb (http_parser *p, const char *buf, size_t len)
-{
- http_parser_pause(p, 1);
- *current_pause_parser = settings_dontcall;
- return body_cb(p, buf, len);
-}
-
-int
-pause_headers_complete_cb (http_parser *p)
-{
- http_parser_pause(p, 1);
- *current_pause_parser = settings_dontcall;
- return headers_complete_cb(p);
-}
-
-int
-pause_message_complete_cb (http_parser *p)
-{
- http_parser_pause(p, 1);
- *current_pause_parser = settings_dontcall;
- return message_complete_cb(p);
-}
-
-static http_parser_settings settings_pause =
- {.on_message_begin = pause_message_begin_cb
- ,.on_header_field = pause_header_field_cb
- ,.on_header_value = pause_header_value_cb
- ,.on_url = pause_request_url_cb
- ,.on_body = pause_body_cb
- ,.on_headers_complete = pause_headers_complete_cb
- ,.on_message_complete = pause_message_complete_cb
- };
-
static http_parser_settings settings =
{.on_message_begin = message_begin_cb
,.on_header_field = header_field_cb
@@ -1691,17 +1227,6 @@ size_t parse_count_body (const char *buf, size_t len)
return nparsed;
}
-size_t parse_pause (const char *buf, size_t len)
-{
- size_t nparsed;
- http_parser_settings s = settings_pause;
-
- currently_parsing_eof = (len == 0);
- current_pause_parser = &s;
- nparsed = http_parser_execute(parser, current_pause_parser, buf, len);
- return nparsed;
-}
-
static inline int
check_str_eq (const struct message *m,
const char *prop,
@@ -1742,20 +1267,6 @@ check_num_eq (const struct message *m,
#define MESSAGE_CHECK_NUM_EQ(expected, found, prop) \
if (!check_num_eq(expected, #prop, expected->prop, found->prop)) return 0
-#define MESSAGE_CHECK_URL_EQ(u, expected, found, prop, fn) \
-do { \
- char ubuf[256]; \
- \
- if ((u)->field_set & (1 << (fn))) { \
- memcpy(ubuf, (found)->request_url + (u)->field_data[(fn)].off, \
- (u)->field_data[(fn)].len); \
- ubuf[(u)->field_data[(fn)].len] = '\0'; \
- } else { \
- ubuf[0] = '\0'; \
- } \
- \
- check_str_eq(expected, #prop, expected->prop, ubuf); \
-} while(0)
int
message_eq (int index, const struct message *expected)
@@ -1781,28 +1292,6 @@ message_eq (int index, const struct message *expected)
MESSAGE_CHECK_STR_EQ(expected, m, request_url);
-
- /* Check URL components; we can't do this w/ CONNECT since it doesn't
- * send us a well-formed URL.
- */
- if (*m->request_url && m->method != HTTP_CONNECT) {
- struct http_parser_url u;
-
- if (http_parser_parse_url(m->request_url, strlen(m->request_url), 0, &u)) {
- fprintf(stderr, "\n\n*** failed to parse URL %s ***\n\n",
- m->request_url);
- abort();
- }
-
- m->port = (u.field_set & (1 << UF_PORT)) ?
- u.port : 0;
-
- MESSAGE_CHECK_URL_EQ(&u, expected, m, query_string, UF_QUERY);
- MESSAGE_CHECK_URL_EQ(&u, expected, m, fragment, UF_FRAGMENT);
- MESSAGE_CHECK_URL_EQ(&u, expected, m, request_path, UF_PATH);
- MESSAGE_CHECK_NUM_EQ(expected, m, port);
- }
-
if (expected->body_size) {
MESSAGE_CHECK_NUM_EQ(expected, m, body_size);
} else {
@@ -1869,7 +1358,7 @@ upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) {
/* Check the portion of the response after its specified upgrade */
if (!check_str_eq(m, "upgrade", body + off, body + nread)) {
- abort();
+ exit(1);
}
/* Fix up the response so that message_eq() will verify the beginning
@@ -1885,7 +1374,7 @@ upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) {
va_end(ap);
printf("\n\n*** Error: expected a message with upgrade ***\n");
- abort();
+ exit(1);
}
static void
@@ -1931,218 +1420,6 @@ print_error (const char *raw, size_t error_location)
fprintf(stderr, "^\n\nerror location: %u\n", (unsigned int)error_location);
}
-void
-test_preserve_data (void)
-{
- char my_data[] = "application-specific data";
- http_parser parser;
- parser.data = my_data;
- http_parser_init(&parser, HTTP_REQUEST);
- if (parser.data != my_data) {
- printf("\n*** parser.data not preserved accross http_parser_init ***\n\n");
- abort();
- }
-}
-
-struct url_test {
- const char *name;
- const char *url;
- int is_connect;
- struct http_parser_url u;
- int rv;
-};
-
-const struct url_test url_tests[] =
-{ {.name="proxy request"
- ,.url="http://hostname/"
- ,.is_connect=0
- ,.u=
- {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH)
- ,.port=0
- ,.field_data=
- {{ 0, 4 } /* UF_SCHEMA */
- ,{ 7, 8 } /* UF_HOST */
- ,{ 0, 0 } /* UF_PORT */
- ,{ 15, 1 } /* UF_PATH */
- ,{ 0, 0 } /* UF_QUERY */
- ,{ 0, 0 } /* UF_FRAGMENT */
- }
- }
- ,.rv=0
- }
-
-, {.name="CONNECT request"
- ,.url="hostname:443"
- ,.is_connect=1
- ,.u=
- {.field_set=(1 << UF_HOST) | (1 << UF_PORT)
- ,.port=443
- ,.field_data=
- {{ 0, 0 } /* UF_SCHEMA */
- ,{ 0, 8 } /* UF_HOST */
- ,{ 9, 3 } /* UF_PORT */
- ,{ 0, 0 } /* UF_PATH */
- ,{ 0, 0 } /* UF_QUERY */
- ,{ 0, 0 } /* UF_FRAGMENT */
- }
- }
- ,.rv=0
- }
-
-, {.name="proxy ipv6 request"
- ,.url="http://[1:2::3:4]/"
- ,.is_connect=0
- ,.u=
- {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH)
- ,.port=0
- ,.field_data=
- {{ 0, 4 } /* UF_SCHEMA */
- ,{ 8, 8 } /* UF_HOST */
- ,{ 0, 0 } /* UF_PORT */
- ,{ 17, 1 } /* UF_PATH */
- ,{ 0, 0 } /* UF_QUERY */
- ,{ 0, 0 } /* UF_FRAGMENT */
- }
- }
- ,.rv=0
- }
-
-, {.name="CONNECT ipv6 address"
- ,.url="[1:2::3:4]:443"
- ,.is_connect=1
- ,.u=
- {.field_set=(1 << UF_HOST) | (1 << UF_PORT)
- ,.port=443
- ,.field_data=
- {{ 0, 0 } /* UF_SCHEMA */
- ,{ 1, 8 } /* UF_HOST */
- ,{ 11, 3 } /* UF_PORT */
- ,{ 0, 0 } /* UF_PATH */
- ,{ 0, 0 } /* UF_QUERY */
- ,{ 0, 0 } /* UF_FRAGMENT */
- }
- }
- ,.rv=0
- }
-
-, {.name="extra ? in query string"
- ,.url="http://a.tbcdn.cn/p/fp/2010c/??fp-header-min.css,fp-base-min.css,fp-channel-min.css,fp-product-min.css,fp-mall-min.css,fp-category-min.css,fp-sub-min.css,fp-gdp4p-min.css,fp-css3-min.css,fp-misc-min.css?t=20101022.css"
- ,.is_connect=0
- ,.u=
- {.field_set=(1<field_set, u->port);
- for (i = 0; i < UF_MAX; i++) {
- if ((u->field_set & (1 << i)) == 0) {
- printf("\tfield_data[%u]: unset\n", i);
- continue;
- }
-
- memcpy(part, url + u->field_data[i].off, u->field_data[i].len);
- part[u->field_data[i].len] = '\0';
-
- printf("\tfield_data[%u]: off: %u len: %u part: \"%s\"\n",
- i,
- u->field_data[i].off,
- u->field_data[i].len,
- part);
- }
-}
-
-void
-test_parse_url (void)
-{
- struct http_parser_url u;
- const struct url_test *test;
- unsigned int i;
- int rv;
-
- for (i = 0; i < (sizeof(url_tests) / sizeof(url_tests[0])); i++) {
- test = &url_tests[i];
- memset(&u, 0, sizeof(u));
-
- rv = http_parser_parse_url(test->url,
- strlen(test->url),
- test->is_connect,
- &u);
-
- if (test->rv == 0) {
- if (rv != 0) {
- printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, "
- "unexpected rv %d ***\n\n", test->url, test->name, rv);
- abort();
- }
-
- if (memcmp(&u, &test->u, sizeof(u)) != 0) {
- printf("\n*** http_parser_parse_url(\"%s\") \"%s\" failed ***\n",
- test->url, test->name);
-
- printf("target http_parser_url:\n");
- dump_url(test->url, &test->u);
- printf("result http_parser_url:\n");
- dump_url(test->url, &u);
-
- abort();
- }
- } else {
- /* test->rv != 0 */
- if (rv == 0) {
- printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, "
- "unexpected rv %d ***\n\n", test->url, test->name, rv);
- abort();
- }
- }
- }
-}
void
test_message (const struct message *message)
@@ -2167,7 +1444,7 @@ test_message (const struct message *message)
if (read != msg1len) {
print_error(msg1, read);
- abort();
+ exit(1);
}
}
@@ -2181,24 +1458,24 @@ test_message (const struct message *message)
if (read != msg2len) {
print_error(msg2, read);
- abort();
+ exit(1);
}
read = parse(NULL, 0);
if (read != 0) {
print_error(message->raw, read);
- abort();
+ exit(1);
}
test:
if (num_messages != 1) {
printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name);
- abort();
+ exit(1);
}
- if(!message_eq(0, message)) abort();
+ if(!message_eq(0, message)) exit(1);
parser_free();
}
@@ -2219,7 +1496,7 @@ test_message_count_body (const struct message *message)
read = parse_count_body(message->raw + i, toread);
if (read != toread) {
print_error(message->raw, read);
- abort();
+ exit(1);
}
}
@@ -2227,15 +1504,15 @@ test_message_count_body (const struct message *message)
read = parse_count_body(NULL, 0);
if (read != 0) {
print_error(message->raw, read);
- abort();
+ exit(1);
}
if (num_messages != 1) {
printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name);
- abort();
+ exit(1);
}
- if(!message_eq(0, message)) abort();
+ if(!message_eq(0, message)) exit(1);
parser_free();
}
@@ -2267,7 +1544,7 @@ test_simple (const char *buf, enum http_errno err_expected)
#endif
fprintf(stderr, "\n*** test_simple expected %s, but saw %s ***\n\n%s\n",
http_errno_name(err_expected), http_errno_name(err), buf);
- abort();
+ exit(1);
}
}
@@ -2296,54 +1573,7 @@ test_header_overflow_error (int req)
}
fprintf(stderr, "\n*** Error expected but none in header overflow test ***\n");
- abort();
-}
-
-static void
-test_content_length_overflow (const char *buf, size_t buflen, int expect_ok)
-{
- http_parser parser;
- http_parser_init(&parser, HTTP_RESPONSE);
- http_parser_execute(&parser, &settings_null, buf, buflen);
-
- if (expect_ok)
- assert(HTTP_PARSER_ERRNO(&parser) == HPE_OK);
- else
- assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_CONTENT_LENGTH);
-}
-
-void
-test_header_content_length_overflow_error (void)
-{
-#define X(size) \
- "HTTP/1.1 200 OK\r\n" \
- "Content-Length: " #size "\r\n" \
- "\r\n"
- const char a[] = X(18446744073709551614); /* 2^64-2 */
- const char b[] = X(18446744073709551615); /* 2^64-1 */
- const char c[] = X(18446744073709551616); /* 2^64 */
-#undef X
- test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */
- test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */
- test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */
-}
-
-void
-test_chunk_content_length_overflow_error (void)
-{
-#define X(size) \
- "HTTP/1.1 200 OK\r\n" \
- "Transfer-Encoding: chunked\r\n" \
- "\r\n" \
- #size "\r\n" \
- "..."
- const char a[] = X(FFFFFFFFFFFFFFFE); /* 2^64-2 */
- const char b[] = X(FFFFFFFFFFFFFFFF); /* 2^64-1 */
- const char c[] = X(10000000000000000); /* 2^64 */
-#undef X
- test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */
- test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */
- test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */
+ exit(1);
}
void
@@ -2376,7 +1606,7 @@ test_no_overflow_long_body (int req, size_t length)
"\n*** error in test_no_overflow_long_body %s of length %zu ***\n",
req ? "REQUEST" : "RESPONSE",
length);
- abort();
+ exit(1);
}
void
@@ -2408,26 +1638,26 @@ test_multiple3 (const struct message *r1, const struct message *r2, const struct
if (read != strlen(total)) {
print_error(total, read);
- abort();
+ exit(1);
}
read = parse(NULL, 0);
if (read != 0) {
print_error(total, read);
- abort();
+ exit(1);
}
test:
if (message_count != num_messages) {
fprintf(stderr, "\n\n*** Parser didn't see 3 messages only %d *** \n", num_messages);
- abort();
+ exit(1);
}
- if (!message_eq(0, r1)) abort();
- if (message_count > 1 && !message_eq(1, r2)) abort();
- if (message_count > 2 && !message_eq(2, r3)) abort();
+ if (!message_eq(0, r1)) exit(1);
+ if (message_count > 1 && !message_eq(1, r2)) exit(1);
+ if (message_count > 2 && !message_eq(2, r3)) exit(1);
parser_free();
}
@@ -2550,7 +1780,7 @@ test:
fprintf(stderr, "buf1 (%u) %s\n\n", (unsigned int)buf1_len, buf1);
fprintf(stderr, "buf2 (%u) %s\n\n", (unsigned int)buf2_len , buf2);
fprintf(stderr, "buf3 (%u) %s\n", (unsigned int)buf3_len, buf3);
- abort();
+ exit(1);
}
// user required to free the result
@@ -2584,58 +1814,6 @@ create_large_chunked_message (int body_size_in_kb, const char* headers)
return buf;
}
-/* Verify that we can pause parsing at any of the bytes in the
- * message and still get the result that we're expecting. */
-void
-test_message_pause (const struct message *msg)
-{
- char *buf = (char*) msg->raw;
- size_t buflen = strlen(msg->raw);
- size_t nread;
-
- parser_init(msg->type);
-
- do {
- nread = parse_pause(buf, buflen);
-
- // We can only set the upgrade buffer once we've gotten our message
- // completion callback.
- if (messages[0].message_complete_cb_called &&
- msg->upgrade &&
- parser->upgrade) {
- messages[0].upgrade = buf + nread;
- goto test;
- }
-
- if (nread < buflen) {
-
- // Not much do to if we failed a strict-mode check
- if (HTTP_PARSER_ERRNO(parser) == HPE_STRICT) {
- parser_free();
- return;
- }
-
- assert (HTTP_PARSER_ERRNO(parser) == HPE_PAUSED);
- }
-
- buf += nread;
- buflen -= nread;
- http_parser_pause(parser, 0);
- } while (buflen > 0);
-
- nread = parse_pause(NULL, 0);
- assert (nread == 0);
-
-test:
- if (num_messages != 1) {
- printf("\n*** num_messages != 1 after testing '%s' ***\n\n", msg->name);
- abort();
- }
-
- if(!message_eq(0, msg)) abort();
-
- parser_free();
-}
int
main (void)
@@ -2650,10 +1828,6 @@ main (void)
for (request_count = 0; requests[request_count].name; request_count++);
for (response_count = 0; responses[response_count].name; response_count++);
- //// API
- test_preserve_data();
- test_parse_url();
-
//// OVERFLOW CONDITIONS
test_header_overflow_error(HTTP_REQUEST);
@@ -2664,19 +1838,12 @@ main (void)
test_no_overflow_long_body(HTTP_RESPONSE, 1000);
test_no_overflow_long_body(HTTP_RESPONSE, 100000);
- test_header_content_length_overflow_error();
- test_chunk_content_length_overflow_error();
-
//// RESPONSES
for (i = 0; i < response_count; i++) {
test_message(&responses[i]);
}
- for (i = 0; i < response_count; i++) {
- test_message_pause(&responses[i]);
- }
-
for (i = 0; i < response_count; i++) {
if (!responses[i].should_keep_alive) continue;
for (j = 0; j < response_count; j++) {
@@ -2721,7 +1888,7 @@ main (void)
printf("response scan 1/2 ");
test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY]
- , &responses[NO_BODY_HTTP10_KA_204]
+ , &responses[NO_HEADERS_NO_BODY_404]
, &responses[NO_REASON_PHRASE]
);
@@ -2852,9 +2019,7 @@ main (void)
test_message(&requests[i]);
}
- for (i = 0; i < request_count; i++) {
- test_message_pause(&requests[i]);
- }
+
for (i = 0; i < request_count; i++) {
if (!requests[i].should_keep_alive) continue;
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index a8fe0abb97..8dc7147310 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -225,7 +225,6 @@ static void close_cb(uv_fs_t* req) {
uv_fs_req_cleanup(req);
if (close_cb_count == 3) {
r = uv_fs_unlink(loop, &unlink_req, "test_file2", unlink_cb);
- ASSERT(r == 0);
}
}
@@ -238,7 +237,6 @@ static void ftruncate_cb(uv_fs_t* req) {
ftruncate_cb_count++;
uv_fs_req_cleanup(req);
r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
- ASSERT(r == 0);
}
@@ -257,7 +255,6 @@ static void read_cb(uv_fs_t* req) {
ASSERT(strcmp(buf, "test-bu") == 0);
r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
}
- ASSERT(r == 0);
}
@@ -277,7 +274,6 @@ static void open_cb(uv_fs_t* req) {
memset(buf, 0, sizeof(buf));
r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
read_cb);
- ASSERT(r == 0);
}
@@ -302,7 +298,6 @@ static void fsync_cb(uv_fs_t* req) {
fsync_cb_count++;
uv_fs_req_cleanup(req);
r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
- ASSERT(r == 0);
}
@@ -314,7 +309,6 @@ static void fdatasync_cb(uv_fs_t* req) {
fdatasync_cb_count++;
uv_fs_req_cleanup(req);
r = uv_fs_fsync(loop, &fsync_req, open_req1.result, fsync_cb);
- ASSERT(r == 0);
}
@@ -326,7 +320,6 @@ static void write_cb(uv_fs_t* req) {
write_cb_count++;
uv_fs_req_cleanup(req);
r = uv_fs_fdatasync(loop, &fdatasync_req, open_req1.result, fdatasync_cb);
- ASSERT(r == 0);
}
@@ -339,7 +332,6 @@ static void create_cb(uv_fs_t* req) {
uv_fs_req_cleanup(req);
r = uv_fs_write(loop, &write_req, req->result, test_buf, sizeof(test_buf),
-1, write_cb);
- ASSERT(r == 0);
}
@@ -1673,59 +1665,3 @@ TEST_IMPL(fs_rename_to_existing_file) {
return 0;
}
-
-
-TEST_IMPL(fs_read_file_eof) {
- int r;
-
- /* Setup. */
- unlink("test_file");
-
- loop = uv_default_loop();
-
- r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
- S_IWRITE | S_IREAD, NULL);
- ASSERT(r != -1);
- ASSERT(open_req1.result != -1);
- uv_fs_req_cleanup(&open_req1);
-
- r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
- sizeof(test_buf), -1, NULL);
- ASSERT(r != -1);
- ASSERT(write_req.result != -1);
- uv_fs_req_cleanup(&write_req);
-
- r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
- ASSERT(r != -1);
- ASSERT(close_req.result != -1);
- uv_fs_req_cleanup(&close_req);
-
- r = uv_fs_open(loop, &open_req1, "test_file", O_RDONLY, 0, NULL);
- ASSERT(r != -1);
- ASSERT(open_req1.result != -1);
- uv_fs_req_cleanup(&open_req1);
-
- memset(buf, 0, sizeof(buf));
- r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
- NULL);
- ASSERT(r != -1);
- ASSERT(read_req.result != -1);
- ASSERT(strcmp(buf, test_buf) == 0);
- uv_fs_req_cleanup(&read_req);
-
- r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf),
- read_req.result, NULL);
- ASSERT(r == 0);
- ASSERT(read_req.result == 0);
- uv_fs_req_cleanup(&read_req);
-
- r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
- ASSERT(r != -1);
- ASSERT(close_req.result != -1);
- uv_fs_req_cleanup(&close_req);
-
- /* Cleanup */
- unlink("test_file");
-
- return 0;
-}
diff --git a/doc/community/index.html b/doc/community/index.html
index 7087f795f8..13f73230b0 100644
--- a/doc/community/index.html
+++ b/doc/community/index.html
@@ -134,7 +134,7 @@
nodejs.ir Iran group in Persian
- nodejs.jp Japan user group
+ nodejs.jp Japan user group
CNodeJS.org Chinese community
@@ -142,7 +142,13 @@
HKNoJ Hong Kong community
- nodejs.tw Taiwan community
+ nodejs.tw Taiwan community
+
+ Node Hispano Spanish language community
+
+ OctoberSkyJs Korea Node.js community
+
+
diff --git a/doc/images/linkedin-logo.png b/doc/images/linkedin-logo.png
index 2ad9fb2c0c..1c79cf4acd 100644
Binary files a/doc/images/linkedin-logo.png and b/doc/images/linkedin-logo.png differ
diff --git a/doc/images/microsoft-logo.png b/doc/images/microsoft-logo.png
index 6dac0f39b6..1a58d10762 100644
Binary files a/doc/images/microsoft-logo.png and b/doc/images/microsoft-logo.png differ
diff --git a/doc/images/yahoo-logo.png b/doc/images/yahoo-logo.png
index 05d75b3513..689d21b71e 100644
Binary files a/doc/images/yahoo-logo.png and b/doc/images/yahoo-logo.png differ
diff --git a/doc/pipe.css b/doc/pipe.css
index fa8b44c23d..5c1ce79b0e 100644
--- a/doc/pipe.css
+++ b/doc/pipe.css
@@ -150,16 +150,7 @@ h1 a, h2 a, h3 a, h4 a
font-size: 11px;
}
-#quotes ul li.ebay {
- margin-top: -10px;
-}
-
-#quotes ul li.linkedin {
- margin-top: -4px;
-}
-
-#quotes ul li.yahoo {
- margin-top: -4px;
+#quotes ul li:last-child {
padding-right: 0;
}
diff --git a/lib/fs.js b/lib/fs.js
index ca98e2aa65..fc1e1b830b 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -106,6 +106,7 @@ fs.readFile = function(path, encoding_) {
var readStream = fs.createReadStream(path);
var buffers = [];
var nread = 0;
+ var error;
readStream.on('data', function(chunk) {
buffers.push(chunk);
@@ -113,11 +114,18 @@ fs.readFile = function(path, encoding_) {
});
readStream.on('error', function(er) {
- callback(er);
+ error = er;
readStream.destroy();
+ if (!readStream.fd) {
+ readStream.emit('close');
+ }
});
- readStream.on('end', function() {
+ readStream.on('close', function() {
+ if (error) {
+ return callback(error);
+ }
+
// copy all the buffers into one
var buffer;
switch (buffers.length) {
diff --git a/lib/net.js b/lib/net.js
index 6c2e86e832..8d36c34e60 100644
--- a/lib/net.js
+++ b/lib/net.js
@@ -114,6 +114,7 @@ function initSocketHandle(self) {
self._flags = 0;
self._connectQueueSize = 0;
self.destroyed = false;
+ self.errorEmitted = false;
self.bytesRead = 0;
self.bytesWritten = 0;
@@ -278,7 +279,7 @@ Socket.prototype.end = function(data, encoding) {
var shutdownReq = this._handle.shutdown();
if (!shutdownReq) {
- this.destroy(errnoException(errno, 'shutdown'));
+ this._destroy(errnoException(errno, 'shutdown'));
return false;
}
@@ -301,7 +302,7 @@ function afterShutdown(status, handle, req) {
}
if (self._flags & FLAG_GOT_EOF || !self.readable) {
- self.destroy();
+ self._destroy();
} else {
}
}
@@ -312,7 +313,7 @@ Socket.prototype.destroySoon = function() {
this._flags |= FLAG_DESTROY_SOON;
if (this._pendingWriteReqs == 0) {
- this.destroy();
+ this._destroy();
}
};
@@ -324,11 +325,24 @@ Socket.prototype._connectQueueCleanUp = function(exception) {
};
-Socket.prototype.destroy = function(exception) {
- if (this.destroyed) return;
-
+Socket.prototype._destroy = function(exception, cb) {
var self = this;
+ function fireErrorCallbacks() {
+ if (cb) cb(exception);
+ if (exception && !self.errorEmitted) {
+ process.nextTick(function() {
+ self.emit('error', exception);
+ });
+ self.errorEmitted = true;
+ }
+ };
+
+ if (this.destroyed) {
+ fireErrorCallbacks();
+ return;
+ }
+
self._connectQueueCleanUp();
debug('destroy');
@@ -349,8 +363,9 @@ Socket.prototype.destroy = function(exception) {
this._handle = null;
}
+ fireErrorCallbacks();
+
process.nextTick(function() {
- if (exception) self.emit('error', exception);
self.emit('close', exception ? true : false);
});
@@ -358,6 +373,11 @@ Socket.prototype.destroy = function(exception) {
};
+Socket.prototype.destroy = function(exception) {
+ this._destroy(exception);
+}
+
+
function onread(buffer, offset, length) {
var handle = this;
var self = handle.socket;
@@ -396,7 +416,7 @@ function onread(buffer, offset, length) {
// We call destroy() before end(). 'close' not emitted until nextTick so
// the 'end' event will come first as required.
- if (!self.writable) self.destroy();
+ if (!self.writable) self._destroy();
if (!self.allowHalfOpen) self.end();
if (self._events && self._events['end']) self.emit('end');
@@ -404,9 +424,9 @@ function onread(buffer, offset, length) {
} else {
// Error
if (errno == 'ECONNRESET') {
- self.destroy();
+ self._destroy();
} else {
- self.destroy(errnoException(errno, 'read'));
+ self._destroy(errnoException(errno, 'read'));
}
}
}
@@ -484,13 +504,16 @@ Socket.prototype.write = function(data, arg1, arg2) {
Socket.prototype._write = function(data, encoding, cb) {
timers.active(this);
- if (!this._handle) throw new Error('This socket is closed.');
+ if (!this._handle) {
+ this._destroy(new Error('This socket is closed.'), cb);
+ return false;
+ }
// `encoding` is unused right now, `data` is always a buffer.
var writeReq = this._handle.write(data);
if (!writeReq) {
- this.destroy(errnoException(errno, 'write'));
+ this._destroy(errnoException(errno, 'write'), cb);
return false;
}
@@ -511,7 +534,7 @@ function afterWrite(status, handle, req, buffer) {
}
if (status) {
- self.destroy(errnoException(errno, 'write'));
+ self._destroy(errnoException(errno, 'write'), req.cb);
return;
}
@@ -526,7 +549,7 @@ function afterWrite(status, handle, req, buffer) {
if (req.cb) req.cb();
if (self._pendingWriteReqs == 0 && self._flags & FLAG_DESTROY_SOON) {
- self.destroy();
+ self._destroy();
}
}
@@ -563,7 +586,7 @@ function connect(self, address, port, addressType, localAddress) {
if (connectReq !== null) {
connectReq.oncomplete = afterConnect;
} else {
- self.destroy(errnoException(errno, 'connect'));
+ self._destroy(errnoException(errno, 'connect'));
}
}
@@ -617,7 +640,7 @@ Socket.prototype.connect = function(options, cb) {
// error event to the next tick.
process.nextTick(function() {
self.emit('error', err);
- self.destroy();
+ self._destroy();
});
} else {
timers.active(self);
@@ -662,8 +685,9 @@ function afterConnect(status, handle, req, readable, writable) {
if (self._connectQueue) {
debug('Drain the connect queue');
- for (var i = 0; i < self._connectQueue.length; i++) {
- self._write.apply(self, self._connectQueue[i]);
+ var connectQueue = self._connectQueue;
+ for (var i = 0; i < connectQueue.length; i++) {
+ self._write.apply(self, connectQueue[i]);
}
self._connectQueueCleanUp();
}
@@ -677,7 +701,7 @@ function afterConnect(status, handle, req, readable, writable) {
}
} else {
self._connectQueueCleanUp();
- self.destroy(errnoException(errno, 'connect'));
+ self._destroy(errnoException(errno, 'connect'));
}
}
diff --git a/src/node.h b/src/node.h
index f7417c829f..a2cf2eb9bb 100644
--- a/src/node.h
+++ b/src/node.h
@@ -75,6 +75,14 @@
#define NODE_STRINGIFY_HELPER(n) #n
#endif
+#ifndef STATIC_ASSERT
+#if defined(_MSC_VER)
+# define STATIC_ASSERT(expr) static_assert(expr, "")
+# else
+# define STATIC_ASSERT(expr) static_cast((sizeof(char[-1 + !!(expr)])))
+# endif
+#endif
+
namespace node {
int Start(int argc, char *argv[]);
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index c05e8e3361..b99d9b074b 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -972,7 +972,10 @@ Handle Connection::New(const Arguments& args) {
}
-void Connection::SSLInfoCallback(const SSL *ssl, int where, int ret) {
+void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
+ // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
+ // a non-const SSL* in OpenSSL <= 0.9.7e.
+ SSL* ssl = const_cast(ssl_);
if (where & SSL_CB_HANDSHAKE_START) {
HandleScope scope;
Connection* c = static_cast(SSL_get_app_data(ssl));
diff --git a/src/node_file.cc b/src/node_file.cc
index f4b53a1b2f..805dc532f5 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -39,7 +39,6 @@
# include
#endif
-
namespace node {
using namespace v8;
@@ -70,10 +69,41 @@ static Persistent buf_symbol;
static Persistent oncomplete_sym;
-#ifdef _LARGEFILE_SOURCE
-static inline int IsInt64(double x) {
- return x == static_cast(static_cast(x));
-}
+#ifndef _LARGEFILE_SOURCE
+ typedef off_t node_off_t;
+# define ASSERT_OFFSET(a) \
+ STATIC_ASSERT(sizeof(node_off_t) * CHAR_BIT >= 32); \
+ if (!(a)->IsUndefined() && !(a)->IsNull() && !(a)->IsInt32()) { \
+ return ThrowException(Exception::TypeError(String::New("Not an integer"))); \
+ }
+# define ASSERT_TRUNCATE_LENGTH(a) \
+ if (!(a)->IsUndefined() && !(a)->IsNull() && !(a)->IsUint32()) { \
+ return ThrowException(Exception::TypeError(String::New("Not an integer"))); \
+ }
+# define GET_OFFSET(a) ((a)->IsNumber() ? (a)->Int32Value() : -1)
+# define GET_TRUNCATE_LENGTH(a) ((a)->Uint32Value())
+#else
+# ifdef _WIN32
+# define NODE_USE_64BIT_UV_FS_API
+ typedef int64_t node_off_t;
+# else
+ typedef off_t node_off_t;
+# endif
+# define ASSERT_OFFSET(a) \
+ STATIC_ASSERT(sizeof(node_off_t) * CHAR_BIT >= 64); \
+ if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \
+ return ThrowException(Exception::TypeError(String::New("Not an integer"))); \
+ }
+# define ASSERT_TRUNCATE_LENGTH(a) \
+ if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \
+ return ThrowException(Exception::TypeError(String::New("Not an integer"))); \
+ }
+# define GET_OFFSET(a) ((a)->IsNumber() ? (a)->IntegerValue() : -1)
+# define GET_TRUNCATE_LENGTH(a) ((a)->IntegerValue())
+
+ static inline int IsInt64(double x) {
+ return x == static_cast(static_cast(x));
+ }
#endif
@@ -475,20 +505,6 @@ static Handle Rename(const Arguments& args) {
}
}
-#ifndef _LARGEFILE_SOURCE
-#define ASSERT_TRUNCATE_LENGTH(a) \
- if (!(a)->IsUndefined() && !(a)->IsNull() && !(a)->IsUint32()) { \
- return ThrowException(Exception::TypeError(String::New("Not an integer"))); \
- }
-#define GET_TRUNCATE_LENGTH(a) ((a)->Uint32Value())
-#else
-#define ASSERT_TRUNCATE_LENGTH(a) \
- if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \
- return ThrowException(Exception::TypeError(String::New("Not an integer"))); \
- }
-#define GET_TRUNCATE_LENGTH(a) ((a)->IntegerValue())
-#endif
-
static Handle Truncate(const Arguments& args) {
HandleScope scope;
@@ -499,12 +515,20 @@ static Handle Truncate(const Arguments& args) {
int fd = args[0]->Int32Value();
ASSERT_TRUNCATE_LENGTH(args[1]);
- off_t len = GET_TRUNCATE_LENGTH(args[1]);
+ node_off_t len = GET_TRUNCATE_LENGTH(args[1]);
if (args[2]->IsFunction()) {
+#ifdef NODE_USE_64BIT_UV_FS_API
+ ASYNC_CALL(ftruncate64, args[2], fd, len)
+#else
ASYNC_CALL(ftruncate, args[2], fd, len)
+#endif
} else {
+#ifdef NODE_USE_64BIT_UV_FS_API
+ SYNC_CALL(ftruncate64, 0, fd, len)
+#else
SYNC_CALL(ftruncate, 0, fd, len)
+#endif
return Undefined();
}
}
@@ -674,20 +698,6 @@ static Handle Open(const Arguments& args) {
}
}
-#ifndef _LARGEFILE_SOURCE
-#define ASSERT_OFFSET(a) \
- if (!(a)->IsUndefined() && !(a)->IsNull() && !(a)->IsInt32()) { \
- return ThrowException(Exception::TypeError(String::New("Not an integer"))); \
- }
-#define GET_OFFSET(a) ((a)->IsNumber() ? (a)->Int32Value() : -1)
-#else
-#define ASSERT_OFFSET(a) \
- if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \
- return ThrowException(Exception::TypeError(String::New("Not an integer"))); \
- }
-#define GET_OFFSET(a) ((a)->IsNumber() ? (a)->IntegerValue() : -1)
-#endif
-
// bytesWritten = write(fd, data, position, enc, callback)
// Wrapper for write(2).
//
@@ -728,15 +738,23 @@ static Handle Write(const Arguments& args) {
}
ASSERT_OFFSET(args[4]);
- off_t pos = GET_OFFSET(args[4]);
+ node_off_t pos = GET_OFFSET(args[4]);
char * buf = (char*)buffer_data + off;
Local cb = args[5];
if (cb->IsFunction()) {
+#ifdef NODE_USE_64BIT_UV_FS_API
+ ASYNC_CALL(write64, cb, fd, buf, len, pos)
+#else
ASYNC_CALL(write, cb, fd, buf, len, pos)
+#endif
} else {
+#ifdef NODE_USE_64BIT_UV_FS_API
+ SYNC_CALL(write64, 0, fd, buf, len, pos)
+#else
SYNC_CALL(write, 0, fd, buf, len, pos)
+#endif
return scope.Close(Integer::New(SYNC_RESULT));
}
}
@@ -765,7 +783,7 @@ static Handle Read(const Arguments& args) {
Local cb;
size_t len;
- off_t pos;
+ node_off_t pos;
char * buf = NULL;
@@ -797,9 +815,17 @@ static Handle Read(const Arguments& args) {
cb = args[5];
if (cb->IsFunction()) {
+#ifdef NODE_USE_64BIT_UV_FS_API
+ ASYNC_CALL(read64, cb, fd, buf, len, pos);
+#else
ASYNC_CALL(read, cb, fd, buf, len, pos);
+#endif
} else {
+#ifdef NODE_USE_64BIT_UV_FS_API
+ SYNC_CALL(read64, 0, fd, buf, len, pos)
+#else
SYNC_CALL(read, 0, fd, buf, len, pos)
+#endif
Local bytesRead = Integer::New(SYNC_RESULT);
return scope.Close(bytesRead);
}
diff --git a/src/v8_typed_array.cc b/src/v8_typed_array.cc
index 3cf2db00af..4a76f97059 100644
--- a/src/v8_typed_array.cc
+++ b/src/v8_typed_array.cc
@@ -471,6 +471,8 @@ class TypedArray {
case v8::kExternalPixelArray: return "Uint8ClampedArray";
}
abort();
+ // Please the compiler
+ return "";
}
};
@@ -567,7 +569,7 @@ int valueToCType(v8::Handle value) {
template <>
float valueToCType(v8::Handle value) {
- return value->NumberValue();
+ return static_cast(value->NumberValue());
}
template <>
diff --git a/test/disabled/test-fs-largefile.js b/test/simple/test-fs-largefile.js
similarity index 98%
rename from test/disabled/test-fs-largefile.js
rename to test/simple/test-fs-largefile.js
index 98238b00b8..ffd6261d87 100644
--- a/test/disabled/test-fs-largefile.js
+++ b/test/simple/test-fs-largefile.js
@@ -53,6 +53,6 @@ assert.ok(exceptionRaised);
fs.close(fd);
process.on('exit', function() {
- fs.unlink(filepath);
+ fs.unlinkSync(filepath);
});
diff --git a/test/simple/test-fs-readfile-unlink.js b/test/simple/test-fs-readfile-unlink.js
new file mode 100644
index 0000000000..0bb4a67f78
--- /dev/null
+++ b/test/simple/test-fs-readfile-unlink.js
@@ -0,0 +1,48 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var assert = require('assert'),
+ common = require('../common'),
+ fs = require('fs'),
+ path = require('path'),
+ dirName = path.resolve(common.fixturesDir, 'test-readfile-unlink'),
+ fileName = path.resolve(dirName, 'test.bin');
+
+var buf = new Buffer(512 * 1024);
+buf.fill(42);
+
+try {
+ fs.mkdirSync(dirName);
+} catch (e) {
+ // Ignore if the directory already exists.
+ if (e.code != 'EEXIST') throw e;
+}
+
+fs.writeFileSync(fileName, buf);
+
+fs.readFile(fileName, function(err, data) {
+ assert.ifError(err);
+ assert(data.length == buf.length);
+ assert.strictEqual(buf[0], 42);
+
+ fs.unlinkSync(fileName);
+ fs.rmdirSync(dirName);
+});
diff --git a/test/simple/test-http-no-content-length.js b/test/simple/test-http-no-content-length.js
new file mode 100644
index 0000000000..8c565aedc7
--- /dev/null
+++ b/test/simple/test-http-no-content-length.js
@@ -0,0 +1,46 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var common = require('../common');
+var assert = require('assert');
+var net = require('net');
+var http = require('http');
+
+var body = '';
+
+var server = net.createServer(function(socket) {
+ // Neither Content-Length nor Connection
+ socket.end('HTTP/1.1 200 ok\r\n\r\nHello');
+}).listen(common.PORT, function() {
+ var req = http.get({port: common.PORT}, function(res) {
+ res.setEncoding('utf8');
+ res.on('data', function(chunk) {
+ body += chunk;
+ });
+ res.on('end', function() {
+ server.close();
+ });
+ });
+});
+
+process.on('exit', function() {
+ assert.equal(body, 'Hello');
+});
diff --git a/test/simple/test-memory-usage-emfile.js b/test/simple/test-memory-usage-emfile.js
new file mode 100644
index 0000000000..aaed899530
--- /dev/null
+++ b/test/simple/test-memory-usage-emfile.js
@@ -0,0 +1,37 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+
+var common = require('../common');
+var assert = require('assert');
+
+var fs = require('fs');
+
+var files = [];
+
+while (files.length < 256)
+ files.push(fs.openSync(__filename, 'r'));
+
+var r = process.memoryUsage();
+console.log(common.inspect(r));
+assert.equal(true, r['rss'] > 0);
diff --git a/test/simple/test-net-write-after-close.js b/test/simple/test-net-write-after-close.js
index fd0d30d540..b77e9af724 100644
--- a/test/simple/test-net-write-after-close.js
+++ b/test/simple/test-net-write-after-close.js
@@ -24,18 +24,23 @@ var assert = require('assert');
var net = require('net');
var gotError = false;
+var gotWriteCB = false;
process.on('exit', function() {
assert(gotError);
+ assert(gotWriteCB);
});
var server = net.createServer(function(socket) {
- setTimeout(function() {
- assert.throws(function() {
- socket.write('test');
- }, /This socket is closed/);
+ socket.on('error', function(error) {
server.close();
gotError = true;
+ });
+
+ setTimeout(function() {
+ socket.write('test', function(e) {
+ gotWriteCB = true;
+ });
}, 250);
});