file: support handle large file
Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>main^2
parent
f2c55aff77
commit
81db1fa371
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
add_definitions(-O -Wall -Werror --std=gnu99 -D_GNU_SOURCE)
|
add_definitions(-O -Wall -Werror --std=gnu99 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64)
|
||||||
|
|
||||||
# The version number.
|
# The version number.
|
||||||
set(UHTTPD_VERSION_MAJOR 3)
|
set(UHTTPD_VERSION_MAJOR 3)
|
||||||
|
|
|
@ -62,7 +62,7 @@ static void conn_send(struct uh_connection *conn, const void *data, ssize_t len)
|
||||||
ev_io_start(conni->srv->loop, &conni->iow);
|
ev_io_start(conni->srv->loop, &conni->iow);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void conn_send_file(struct uh_connection *conn, const char *path, size_t offset, ssize_t len)
|
static void conn_send_file(struct uh_connection *conn, const char *path, off_t offset, int64_t len)
|
||||||
{
|
{
|
||||||
struct uh_connection_internal *conni = (struct uh_connection_internal *)conn;
|
struct uh_connection_internal *conni = (struct uh_connection_internal *)conn;
|
||||||
size_t min = 8192;
|
size_t min = 8192;
|
||||||
|
|
|
@ -74,7 +74,7 @@ struct uh_connection_internal {
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
struct {
|
struct {
|
||||||
int fd;
|
int fd;
|
||||||
size_t size;
|
uint64_t size;
|
||||||
} file;
|
} file;
|
||||||
struct ev_io ior;
|
struct ev_io ior;
|
||||||
struct ev_io iow;
|
struct ev_io iow;
|
||||||
|
|
14
src/file.c
14
src/file.c
|
@ -154,7 +154,7 @@ static void file_if_gzip(struct uh_connection *conn, const char *path, const cha
|
||||||
conn->printf(conn, "Content-Encoding: gzip\r\n");
|
conn->printf(conn, "Content-Encoding: gzip\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool file_range(struct uh_connection *conn, size_t size, size_t *start, size_t *end, bool *ranged)
|
static bool file_range(struct uh_connection *conn, uint64_t size, uint64_t *start, uint64_t *end, bool *ranged)
|
||||||
{
|
{
|
||||||
struct uh_connection_internal *conni = (struct uh_connection_internal *)conn;
|
struct uh_connection_internal *conni = (struct uh_connection_internal *)conn;
|
||||||
const struct uh_str hdr = conn->get_header(conn, "Range");
|
const struct uh_str hdr = conn->get_header(conn, "Range");
|
||||||
|
@ -202,7 +202,7 @@ static bool file_range(struct uh_connection *conn, size_t size, size_t *start, s
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
*start = strtoul(buf, NULL, 0);
|
*start = strtoull(buf, NULL, 0);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ static bool file_range(struct uh_connection *conn, size_t size, size_t *start, s
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
*end = strtoul(buf, NULL, 0);
|
*end = strtoull(buf, NULL, 0);
|
||||||
|
|
||||||
if (*start >= size)
|
if (*start >= size)
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -237,7 +237,7 @@ err:
|
||||||
|
|
||||||
conn->send_status_line(conn, HTTP_STATUS_RANGE_NOT_SATISFIABLE, "Content-Type: text/plain\r\nConnection: close\r\n");
|
conn->send_status_line(conn, HTTP_STATUS_RANGE_NOT_SATISFIABLE, "Content-Type: text/plain\r\nConnection: close\r\n");
|
||||||
conn->printf(conn, "Content-Length: %d\r\n", content_length);
|
conn->printf(conn, "Content-Length: %d\r\n", content_length);
|
||||||
conn->printf(conn, "Content-Range: bytes */%zu\r\n", size);
|
conn->printf(conn, "Content-Range: bytes */%" PRIu64 "\r\n", size);
|
||||||
|
|
||||||
conn->send(conn, "\r\n", 2);
|
conn->send(conn, "\r\n", 2);
|
||||||
|
|
||||||
|
@ -258,8 +258,8 @@ void serve_file(struct uh_connection *conn)
|
||||||
const char *docroot = srv->docroot;
|
const char *docroot = srv->docroot;
|
||||||
const char *index_page = srv->index_page;
|
const char *index_page = srv->index_page;
|
||||||
static char fullpath[PATH_MAX];
|
static char fullpath[PATH_MAX];
|
||||||
|
uint64_t start, end;
|
||||||
int docroot_len;
|
int docroot_len;
|
||||||
size_t start, end;
|
|
||||||
const char *mime;
|
const char *mime;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
bool ranged;
|
bool ranged;
|
||||||
|
@ -334,10 +334,10 @@ void serve_file(struct uh_connection *conn)
|
||||||
mime = file_mime_lookup(fullpath);
|
mime = file_mime_lookup(fullpath);
|
||||||
|
|
||||||
conn->printf(conn, "Content-Type: %s\r\n", mime);
|
conn->printf(conn, "Content-Type: %s\r\n", mime);
|
||||||
conn->printf(conn, "Content-Length: %zu\r\n", end - start + 1);
|
conn->printf(conn, "Content-Length: %" PRIu64 "\r\n", end - start + 1);
|
||||||
|
|
||||||
if (ranged)
|
if (ranged)
|
||||||
conn->printf(conn, "Content-Range: bytes %zu-%zu/%" PRIu64 "\r\n", start, end, (uint64_t)st.st_size);
|
conn->printf(conn, "Content-Range: bytes %" PRIu64 "-%" PRIu64 "/%" PRIu64 "\r\n", start, end, (uint64_t)st.st_size);
|
||||||
else
|
else
|
||||||
file_if_gzip(conn, fullpath, mime);
|
file_if_gzip(conn, fullpath, mime);
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ struct uh_connection {
|
||||||
*/
|
*/
|
||||||
void (*done)(struct uh_connection *conn);
|
void (*done)(struct uh_connection *conn);
|
||||||
void (*send)(struct uh_connection *conn, const void *data, ssize_t len);
|
void (*send)(struct uh_connection *conn, const void *data, ssize_t len);
|
||||||
void (*send_file)(struct uh_connection *conn, const char *path, size_t offset, ssize_t len);
|
void (*send_file)(struct uh_connection *conn, const char *path, off_t offset, int64_t len);
|
||||||
void (*printf)(struct uh_connection *conn, const char *format, ...) __attribute__((format(printf, 2, 3)));
|
void (*printf)(struct uh_connection *conn, const char *format, ...) __attribute__((format(printf, 2, 3)));
|
||||||
void (*vprintf)(struct uh_connection *conn, const char *format, va_list arg);
|
void (*vprintf)(struct uh_connection *conn, const char *format, va_list arg);
|
||||||
void (*send_status_line)(struct uh_connection *conn, int code, const char *extra_headers);
|
void (*send_status_line)(struct uh_connection *conn, int code, const char *extra_headers);
|
||||||
|
|
Loading…
Reference in New Issue