diff options
Diffstat (limited to 'src/microhttpd/response.c')
-rw-r--r-- | src/microhttpd/response.c | 64 |
1 files changed, 62 insertions, 2 deletions
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 | ||