aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2015-06-09 19:33:57 +0000
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2015-06-09 19:33:57 +0000
commit09088de0dbfb52843d4a960041b1f560b4c0e1b1 (patch)
treec2ee8f6ff22eb9e8ed6f70c20ce841fbe83a4118
parentb218fd29ff2dbbad26eaecce1abe65ba3e791bdf (diff)
downloadlibmicrohttpd-09088de0dbfb52843d4a960041b1f560b4c0e1b1.tar.gz
libmicrohttpd-09088de0dbfb52843d4a960041b1f560b4c0e1b1.zip
Add MHD_create_response_from_fd64() and MHD_create_response_from_fd_at_offset64() functions,
check lseek() results when reading file, check whether desired file offset fits off_t
-rw-r--r--src/include/microhttpd.h51
-rw-r--r--src/microhttpd/internal.h2
-rw-r--r--src/microhttpd/response.c64
3 files changed, 107 insertions, 10 deletions
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 4e22ee39..cb0c8a28 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -2076,11 +2076,27 @@ MHD_create_response_from_buffer (size_t size,
2076 * @return NULL on error (i.e. invalid arguments, out of memory) 2076 * @return NULL on error (i.e. invalid arguments, out of memory)
2077 * @ingroup response 2077 * @ingroup response
2078 */ 2078 */
2079/* NOTE: this should be 'uint64_t' instead of 'size_t', but changing
2080 this would break API compatibility. */
2081_MHD_EXTERN struct MHD_Response * 2079_MHD_EXTERN struct MHD_Response *
2082MHD_create_response_from_fd (size_t size, 2080MHD_create_response_from_fd (size_t size,
2083 int fd); 2081 int fd);
2082
2083
2084/**
2085 * Create a response object. The response object can be extended with
2086 * header information and then be used any number of times.
2087 *
2088 * @param size size of the data portion of the response;
2089 * sizes larger than 2 GiB may be not supported by OS or
2090 * MHD build
2091 * @param fd file descriptor referring to a file on disk with the
2092 * data; will be closed when response is destroyed;
2093 * fd should be in 'blocking' mode
2094 * @return NULL on error (i.e. invalid arguments, out of memory)
2095 * @ingroup response
2096 */
2097_MHD_EXTERN struct MHD_Response *
2098MHD_create_response_from_fd64 (uint64_t size,
2099 int fd);
2084 2100
2085 2101
2086/** 2102/**
@@ -2099,12 +2115,33 @@ MHD_create_response_from_fd (size_t size,
2099 * @return NULL on error (i.e. invalid arguments, out of memory) 2115 * @return NULL on error (i.e. invalid arguments, out of memory)
2100 * @ingroup response 2116 * @ingroup response
2101 */ 2117 */
2102/* NOTE: this should be 'uint64_t' instead of 'size_t', but changing 2118_MHD_DEPR_FUNC("Function MHD_create_response_from_fd_at_offset() is deprecated, use MHD_create_response_from_fd_at_offset64()") \
2103 this would break API compatibility. */
2104_MHD_EXTERN struct MHD_Response * 2119_MHD_EXTERN struct MHD_Response *
2105MHD_create_response_from_fd_at_offset (size_t size, 2120MHD_create_response_from_fd_at_offset (size_t size,
2106 int fd, 2121 int fd,
2107 off_t offset); 2122 off_t offset);
2123
2124
2125/**
2126 * Create a response object. The response object can be extended with
2127 * header information and then be used any number of times.
2128 *
2129 * @param size size of the data portion of the response;
2130 * sizes larger than 2 GiB may be not supported by OS or
2131 * MHD build
2132 * @param fd file descriptor referring to a file on disk with the
2133 * data; will be closed when response is destroyed;
2134 * fd should be in 'blocking' mode
2135 * @param offset offset to start reading from in the file;
2136 * reading file beyond 2 GiB may be not supported by OS or
2137 * MHD build
2138 * @return NULL on error (i.e. invalid arguments, out of memory)
2139 * @ingroup response
2140 */
2141_MHD_EXTERN struct MHD_Response *
2142MHD_create_response_from_fd_at_offset64 (uint64_t size,
2143 int fd,
2144 uint64_t offset);
2108 2145
2109 2146
2110#if 0 2147#if 0
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 286aee68..777c3ad3 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -295,7 +295,7 @@ struct MHD_Response
295 /** 295 /**
296 * Offset to start reading from when using @e fd. 296 * Offset to start reading from when using @e fd.
297 */ 297 */
298 off_t fd_off; 298 uint64_t fd_off;
299 299
300 /** 300 /**
301 * Number of bytes ready in @e data (buffer may be larger 301 * Number of bytes ready in @e data (buffer may be larger
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index cdc01a94..4a6382f8 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -28,6 +28,7 @@
28 28
29#include "internal.h" 29#include "internal.h"
30#include "response.h" 30#include "response.h"
31#include <limits.h>
31 32
32#if defined(_WIN32) && defined(MHD_W32_MUTEX_) 33#if defined(_WIN32) && defined(MHD_W32_MUTEX_)
33#ifndef WIN32_LEAN_AND_MEAN 34#ifndef WIN32_LEAN_AND_MEAN
@@ -304,6 +305,10 @@ MHD_set_response_options (struct MHD_Response *response,
304} 305}
305 306
306 307
308#ifndef INT32_MAX
309#define INT32_MAX ((int32_t)0x7FFFFFFF)
310#endif /* !INT32_MAX */
311
307/** 312/**
308 * Given a file descriptor, read data from the file 313 * Given a file descriptor, read data from the file
309 * to generate the response. 314 * to generate the response.
@@ -319,8 +324,17 @@ file_reader (void *cls, uint64_t pos, char *buf, size_t max)
319{ 324{
320 struct MHD_Response *response = cls; 325 struct MHD_Response *response = cls;
321 ssize_t n; 326 ssize_t n;
327 const int64_t offset64 = (int64_t)(pos + response->fd_off);
328
329 if (offset64 < 0)
330 return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
331
332 if (sizeof(off_t) < sizeof(uint64_t) && offset64 > (uint64_t)INT32_MAX)
333 return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
334
335 if (lseek (response->fd, (off_t)offset64, SEEK_SET) != (off_t)offset64)
336 return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
322 337
323 (void) lseek (response->fd, pos + response->fd_off, SEEK_SET);
324 n = read (response->fd, buf, max); 338 n = read (response->fd, buf, max);
325 if (0 == n) 339 if (0 == n)
326 return MHD_CONTENT_READER_END_OF_STREAM; 340 return MHD_CONTENT_READER_END_OF_STREAM;
@@ -367,6 +381,31 @@ MHD_create_response_from_fd_at_offset (size_t size,
367 int fd, 381 int fd,
368 off_t offset) 382 off_t offset)
369{ 383{
384 return MHD_create_response_from_fd_at_offset64 (size, fd, offset);
385}
386
387
388/**
389 * Create a response object. The response object can be extended with
390 * header information and then be used any number of times.
391 *
392 * @param size size of the data portion of the response;
393 * sizes larger than 2 GiB may be not supported by OS or
394 * MHD build
395 * @param fd file descriptor referring to a file on disk with the
396 * data; will be closed when response is destroyed;
397 * fd should be in 'blocking' mode
398 * @param offset offset to start reading from in the file;
399 * reading file beyond 2 GiB may be not supported by OS or
400 * MHD build
401 * @return NULL on error (i.e. invalid arguments, out of memory)
402 * @ingroup response
403 */
404_MHD_EXTERN struct MHD_Response *
405MHD_create_response_from_fd_at_offset64 (uint64_t size,
406 int fd,
407 uint64_t offset)
408{
370 struct MHD_Response *response; 409 struct MHD_Response *response;
371 410
372 response = MHD_create_response_from_callback (size, 411 response = MHD_create_response_from_callback (size,
@@ -396,7 +435,28 @@ struct MHD_Response *
396MHD_create_response_from_fd (size_t size, 435MHD_create_response_from_fd (size_t size,
397 int fd) 436 int fd)
398{ 437{
399 return MHD_create_response_from_fd_at_offset (size, fd, 0); 438 return MHD_create_response_from_fd_at_offset64 (size, fd, 0);
439}
440
441
442/**
443 * Create a response object. The response object can be extended with
444 * header information and then be used any number of times.
445 *
446 * @param size size of the data portion of the response;
447 * sizes larger than 2 GiB may be not supported by OS or
448 * MHD build
449 * @param fd file descriptor referring to a file on disk with the
450 * data; will be closed when response is destroyed;
451 * fd should be in 'blocking' mode
452 * @return NULL on error (i.e. invalid arguments, out of memory)
453 * @ingroup response
454 */
455_MHD_EXTERN struct MHD_Response *
456MHD_create_response_from_fd64(uint64_t size,
457 int fd)
458{
459 return MHD_create_response_from_fd_at_offset64 (size, fd, 0);
400} 460}
401 461
402 462