parent
43b7160cd9
commit
0eaa539315
|
@ -26,7 +26,9 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <sys/sendfile.h>
|
||||
|
||||
#include "connection.h"
|
||||
#include "uhttpd.h"
|
||||
|
@ -34,13 +36,25 @@
|
|||
#include "ssl.h"
|
||||
|
||||
|
||||
|
||||
static void conn_send(struct uh_connection *conn, const void *data, ssize_t len)
|
||||
{
|
||||
buffer_put_data(&conn->wb, data, len);
|
||||
ev_io_start(conn->srv->loop, &conn->iow);
|
||||
}
|
||||
|
||||
static void conn_send_file(struct uh_connection *conn, const char *path)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
conn->file.fd = open(path, O_RDONLY);
|
||||
|
||||
fstat(conn->file.fd, &st);
|
||||
|
||||
conn->file.size = st.st_size;
|
||||
|
||||
ev_io_start(conn->srv->loop, &conn->iow);
|
||||
}
|
||||
|
||||
static void conn_printf(struct uh_connection *conn, const char *format, ...)
|
||||
{
|
||||
struct buffer *wb = &conn->wb;
|
||||
|
@ -335,6 +349,9 @@ static void conn_free(struct uh_connection *conn)
|
|||
buffer_free(&conn->rb);
|
||||
buffer_free(&conn->wb);
|
||||
|
||||
if (conn->file.fd > 0)
|
||||
close(conn->file.fd);
|
||||
|
||||
if (conn->prev)
|
||||
conn->prev->next = conn->next;
|
||||
else
|
||||
|
@ -388,6 +405,25 @@ static void conn_write_cb(struct ev_loop *loop, struct ev_io *w, int revents)
|
|||
}
|
||||
|
||||
if (buffer_length(&conn->wb) == 0) {
|
||||
if (conn->file.fd > 0) {
|
||||
ssize_t ret = sendfile(w->fd, conn->file.fd, NULL, conn->file.size);
|
||||
if (ret < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
uh_log_err("write error: %s\n", strerror(errno));
|
||||
conn_free(conn);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret < conn->file.size) {
|
||||
conn->file.size -= ret;
|
||||
return;
|
||||
}
|
||||
|
||||
close(conn->file.fd);
|
||||
conn->file.fd = -1;
|
||||
}
|
||||
|
||||
if (conn->flags & CONN_F_SEND_AND_CLOSE)
|
||||
conn_free(conn);
|
||||
else
|
||||
|
@ -520,6 +556,7 @@ struct uh_connection *uh_new_connection(struct uh_server *srv, int sock, struct
|
|||
|
||||
conn->free = conn_free;
|
||||
conn->send = conn_send;
|
||||
conn->send_file = conn_send_file;
|
||||
conn->printf = conn_printf;
|
||||
conn->vprintf = conn_vprintf;
|
||||
conn->send_status_line = conn_send_status_line;
|
||||
|
|
|
@ -71,6 +71,10 @@ struct uh_connection {
|
|||
void *ssl;
|
||||
#endif
|
||||
uint8_t flags;
|
||||
struct {
|
||||
int fd;
|
||||
int size;
|
||||
} file;
|
||||
struct ev_io ior;
|
||||
struct ev_io iow;
|
||||
struct buffer rb;
|
||||
|
@ -86,6 +90,7 @@ struct uh_connection {
|
|||
struct uh_connection *next;
|
||||
void (*free)(struct uh_connection *conn);
|
||||
void (*send)(struct uh_connection *conn, const void *data, ssize_t len);
|
||||
void (*send_file)(struct uh_connection *conn, const char *path);
|
||||
void (*printf)(struct uh_connection *conn, const char *format, ...);
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue