diff options
author | joe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845> | 2010-09-22 19:33:36 +0000 |
---|---|---|
committer | joe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845> | 2010-09-22 19:33:36 +0000 |
commit | 2e1d714cd8106eb397a4aa48866cbb34353b78f3 (patch) | |
tree | f3eb4464ce5a7114982ec5767950b158f4c832a1 | |
parent | da757cba8a2a74ea0d0f7ac325fa6bc75f01706e (diff) | |
download | neon-2e1d714cd8106eb397a4aa48866cbb34353b78f3.tar.gz |
Merge r1801 from trunk:
* src/ne_request.c (body_fd_send): Handle read() errors; thanks to Lou
Montulli.
* test/request.c (serve_mirror, send_length): Add test case.
* test/Makefile.in (foobar.txt): Create test file.
git-svn-id: http://svn.webdav.org/repos/projects/neon/branches/0.29.x@1807 61a7d7f5-40b7-0310-9c16-bb0ea8cb1845
-rw-r--r-- | src/ne_request.c | 25 | ||||
-rw-r--r-- | test/Makefile.in | 5 | ||||
-rw-r--r-- | test/request.c | 63 |
3 files changed, 89 insertions, 4 deletions
diff --git a/src/ne_request.c b/src/ne_request.c index 8cab832..ea43f3a 100644 --- a/src/ne_request.c +++ b/src/ne_request.c @@ -1,6 +1,6 @@ /* HTTP request/response handling - Copyright (C) 1999-2009, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2010, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -284,6 +284,8 @@ static ssize_t body_fd_send(void *userdata, char *buffer, size_t count) ne_request *req = userdata; if (count) { + ssize_t ret; + if (req->body.file.remain == 0) return 0; @@ -292,7 +294,26 @@ static ssize_t body_fd_send(void *userdata, char *buffer, size_t count) * and 64-bit off64_t: */ if ((ne_off_t)count > req->body.file.remain) count = (size_t)req->body.file.remain; - return read(req->body.file.fd, buffer, count); + + ret = read(req->body.file.fd, buffer, count); + if (ret > 0) { + req->body.file.remain -= ret; + return ret; + } + else if (ret == 0) { + ne_set_error(req->session, + _("Premature EOF in request body file")); + } + else if (ret < 0) { + char err[200]; + int errnum = errno; + + ne_set_error(req->session, + _("Failed reading request body file: %s"), + ne_strerror(errnum, err, sizeof err)); + } + + return -1; } else { ne_off_t newoff; diff --git a/test/Makefile.in b/test/Makefile.in index 8617a3e..d94a02d 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -18,7 +18,7 @@ LIBS = $(LIBTEST) CC = @CC@ OPENSSL = @OPENSSL@ -HELPERS = @HELPERS@ +HELPERS = @HELPERS@ foobar.txt BASIC_TESTS = uri-tests util-tests string-tests socket \ session request auth basic stubs redirect ZLIB_TESTS = compress @@ -125,6 +125,9 @@ empty.gz: random.txt: $(NEWS) cat $(NEWS) > $@ +foobar.txt: + echo foobar > $@ + # Dummy target to create the CA keys etc. makekeys stderr is redirected # since it changes for every invocation; not helpful for regression # testing. diff --git a/test/request.c b/test/request.c index 55f9c8d..0cb4c8b 100644 --- a/test/request.c +++ b/test/request.c @@ -1,6 +1,6 @@ /* HTTP request handling tests - Copyright (C) 2001-2009, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2001-2010, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,6 +31,7 @@ #include <unistd.h> #endif #include <fcntl.h> +#include <errno.h> #include "ne_request.h" #include "ne_socket.h" @@ -2236,6 +2237,65 @@ static int socks_v4_proxy(void) return await_server(); } +/* Server function which serves the request body back as the response + * body. */ +static int serve_mirror(ne_socket *sock, void *userdata) +{ + char response[1024]; + + CALL(discard_request(sock)); + + ONV(clength == 0 || (size_t)clength > sizeof buffer, + ("C-L out of bounds: %d", clength)); + + ONV(ne_sock_fullread(sock, buffer, clength), + ("read failed: %s", ne_sock_error(sock))); + + ne_snprintf(response, sizeof response, + "HTTP/1.0 200 OK\r\n" + "Content-Length: %d\r\n" + "\r\n", clength); + + ONN("send response header failed", + server_send(sock, response, strlen(response))); + + ONN("send response body failed", + server_send(sock, buffer, clength)); + + ONV(ne_sock_read(sock, buffer, 1) != NE_SOCK_CLOSED, + ("client sent data after request: %c", buffer[0])); + + return OK; +} + +/* Test for ne_set_request_body_fd() bug in <= 0.29.3. */ +static int send_length(void) +{ + ne_session *sess; + ne_request *req; + int fd; + ne_buffer *buf = ne_buffer_create(); + + fd = open("foobar.txt", O_RDONLY); + ONV(fd < 0, ("open random.txt failed: %s", strerror(errno))); + + CALL(make_session(&sess, serve_mirror, NULL)); + + req = ne_request_create(sess, "GET", "/foo"); + + ne_set_request_body_fd(req, fd, 0, 3); + ne_add_response_body_reader(req, ne_accept_2xx, collector, buf); + + ONREQ(ne_request_dispatch(req)); + + ONCMP("foo", buf->data, "response body", "match"); + + ne_request_destroy(req); + ne_session_destroy(sess); + close(fd); + return await_server(); +} + /* TODO: test that ne_set_notifier(, NULL, NULL) DTRT too. */ ne_test tests[] = { @@ -2327,5 +2387,6 @@ ne_test tests[] = { T(addrlist), T(socks_proxy), T(socks_v4_proxy), + T(send_length), T(NULL) }; |