commit - a6e689d7450c532baa306b293314e42c0b64a300
commit + 27b2fa9ae5d7a3807eea150cef5163931929cc23
blob - 2fdfc7e8a09113d36dbbe9b35909384cdd5f4a53
blob + 6d339c15e42dacfb6546a9051225b136a6b561cf
--- gmid.h
+++ gmid.h
const char *meta;
int fd, pfd;
DIR *dir;
- char sbuf[1024]; /* static buffer */
- void *buf, *i; /* mmap buffer */
- ssize_t len, off; /* mmap/static buffer */
+ char sbuf[BUFSIZ];
+ ssize_t len, off;
struct sockaddr_storage addr;
struct vhost *host; /* host she's talking to */
};
blob - 892b0dbdff8dd355e62d4efa29742914a3b80cba
blob + b499057cd209235e8510d2ecc6436f8613aa7e15
--- server.c
+++ server.c
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/mman.h>
#include <sys/stat.h>
#include <netdb.h>
static int check_path(struct client*, const char*, int*);
static void open_file(struct client*);
-static void load_file(struct client*);
static void check_for_cgi(struct client*);
static void handle_handshake(int, short, void*);
static char *strip_path(char*, int);
static void start_reply(struct client*, int, const char*);
static void handle_start_reply(int, short, void*);
static void start_cgi(const char*, const char*, struct client*);
-static void send_file(int, short, void*);
static void open_dir(struct client*);
static void redirect_canonical_dir(struct client*);
static void enter_handle_dirlist(int, short, void*);
static int read_next_dir_entry(struct client*);
static void send_directory_listing(int, short, void*);
static void handle_cgi_reply(int, short, void*);
-static void handle_cgi(int, short, void*);
+static void handle_copy(int, short, void*);
static void close_conn(int, short, void*);
static void do_accept(int, short, void*);
static void handle_sighup(int, short, void*);
/* fallthrough */
case FILE_EXISTS:
- load_file(c);
+ c->next = handle_copy;
+ start_reply(c, SUCCESS, mime(c->host, c->iri.path));
return;
case FILE_DIRECTORY:
default:
/* unreachable */
abort();
- }
-}
-
-static void
-load_file(struct client *c)
-{
- if ((c->len = filesize(c->pfd)) == -1) {
- log_err(c, "failed to get file size for %s: %s",
- c->iri.path, strerror(errno));
- start_reply(c, TEMP_FAILURE, "internal server error");
- return;
- }
-
- if ((c->buf = mmap(NULL, c->len, PROT_READ, MAP_PRIVATE,
- c->pfd, 0)) == MAP_FAILED) {
- log_err(c, "mmap: %s: %s", c->iri.path, strerror(errno));
- start_reply(c, TEMP_FAILURE, "internal server error");
- return;
}
- c->i = c->buf;
- c->next = send_file;
- start_reply(c, SUCCESS, mime(c->host, c->iri.path));
}
/*
err:
/* fatal("cannot talk to the executor process: %s", strerror(errno)); */
fatal("cannot talk to the executor process");
-}
-
-static void
-send_file(int fd, short ev, void *d)
-{
- struct client *c = d;
- ssize_t ret, len;
-
- len = (c->buf + c->len) - c->i;
-
- while (len > 0) {
- switch (ret = tls_write(c->ctx, c->i, len)) {
- case -1:
- log_err(c, "tls_write: %s", tls_error(c->ctx));
- close_conn(fd, ev, c);
- return;
-
- case TLS_WANT_POLLIN:
- reschedule_read(fd, c, &send_file);
- return;
-
- case TLS_WANT_POLLOUT:
- reschedule_write(fd, c, &send_file);
- return;
-
- default:
- c->i += ret;
- len -= ret;
- break;
- }
- }
-
- close_conn(fd, ev, c);
}
static void
log_request(c, c->sbuf, c->len);
c->off = 0;
- handle_cgi(fd, ev, c);
+ handle_copy(fd, ev, c);
return;
}
}
static void
-handle_cgi(int fd, short ev, void *d)
+handle_copy(int fd, short ev, void *d)
{
struct client *c = d;
ssize_t r;
while (1) {
- if (c->len == 0) {
- switch (r = read(c->pfd, c->sbuf, sizeof(c->sbuf))) {
- case 0:
- goto end;
- case -1:
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- reschedule_read(c->pfd, c, &handle_cgi);
- return;
- }
- goto end;
- default:
- c->len = r;
- c->off = 0;
- }
- }
-
while (c->len > 0) {
switch (r = tls_write(c->ctx, c->sbuf + c->off, c->len)) {
case -1:
goto end;
case TLS_WANT_POLLOUT:
- reschedule_read(c->fd, c, &handle_cgi);
+ reschedule_write(c->fd, c, &handle_copy);
return;
case TLS_WANT_POLLIN:
- reschedule_write(c->fd, c, &handle_cgi);
+ reschedule_read(c->fd, c, &handle_copy);
return;
default:
break;
}
}
+
+ switch (r = read(c->pfd, c->sbuf, sizeof(c->sbuf))) {
+ case 0:
+ goto end;
+ case -1:
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ reschedule_read(c->pfd, c, &handle_copy);
+ return;
+ }
+ goto end;
+ default:
+ c->len = r;
+ c->off = 0;
+ }
}
end:
tls_free(c->ctx);
c->ctx = NULL;
- if (c->buf != MAP_FAILED)
- munmap(c->buf, c->len);
-
if (c->pfd != -1)
close(c->pfd);
c->fd = fd;
c->pfd = -1;
- c->buf = MAP_FAILED;
c->dir = NULL;
c->addr = addr;