diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2015-06-09 19:33:57 +0000 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2015-06-09 19:33:57 +0000 |
commit | 09088de0dbfb52843d4a960041b1f560b4c0e1b1 (patch) | |
tree | c2ee8f6ff22eb9e8ed6f70c20ce841fbe83a4118 | |
parent | b218fd29ff2dbbad26eaecce1abe65ba3e791bdf (diff) | |
download | libmicrohttpd-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.h | 51 | ||||
-rw-r--r-- | src/microhttpd/internal.h | 2 | ||||
-rw-r--r-- | src/microhttpd/response.c | 64 |
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 * |
2082 | MHD_create_response_from_fd (size_t size, | 2080 | MHD_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 * | ||
2098 | MHD_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 * |
2105 | MHD_create_response_from_fd_at_offset (size_t size, | 2120 | MHD_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 * | ||
2142 | MHD_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 * | ||
405 | MHD_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 * | |||
396 | MHD_create_response_from_fd (size_t size, | 435 | MHD_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 * | ||
456 | MHD_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 | ||