commit - 3b486b32233bf7e55e12e568e2c799990abf9e37
commit + c83e450a02fd06d73c5cbc444a1ccd6fc0bf0fa6
blob - 4122004350c48f4836092646efbd80ac564d455d
blob + 62fe18352621f0158077483ff1740b4cf7c4ab32
--- web/http.c
+++ web/http.c
if (*t != '\0')
*t++ = '\0';
req->path = xstrdup(s);
- if (strcmp("HTTP/1.0", t) != 0 &&
- strcmp("HTTP/1.1", t) != 0) {
+ if (!strcmp("HTTP/1.0", t))
+ req->version = HTTP_1_0;
+ else if (!strcmp("HTTP/1.1", t))
+ req->version = HTTP_1_1;
+ else {
log_warnx("unknown http version: %s",
t);
return -1;
}
void
-http_response_init(struct reswriter *res, int fd)
+http_response_init(struct reswriter *res, struct request *req, int fd)
{
memset(res, 0, sizeof(*res));
res->fd = fd;
+ res->chunked = req->version == HTTP_1_1;
}
int
int r;
res->len = 0; /* discard any leftover from reading */
- res->chunked = ctype != NULL;
log_debug("> %d %s", code, reason);
if (code >= 300 && code < 400) {
location = ctype;
- ctype = NULL;
+ ctype = "text/html;charset=UTF-8";
}
r = snprintf(res->buf, sizeof(res->buf), "HTTP/1.1 %d %s\r\n"
location == NULL ? "" : "Location: ",
location == NULL ? "" : location,
location == NULL ? "" : "\r\n",
- ctype == NULL ? "" : "Transfer-Encoding: chunked\r\n");
+ res->chunked ? "Transfer-Encoding: chunked\r\n" : "");
if (r < 0 || (size_t)r >= sizeof(res->buf))
return -1;
- return writeall(res, res->buf, r);
+ if (writeall(res, res->buf, r) == -1)
+ return -1;
+
+ if (location) {
+ if (http_writes(res, "<a href='") == -1 ||
+ http_htmlescape(res, location) == -1 ||
+ http_writes(res, "'>") == -1 ||
+ http_htmlescape(res, reason) == -1 ||
+ http_writes(res, "</a>") == -1)
+ return -1;
+ }
+
+ return 0;
}
int
if (res->len == 0)
return 0;
+ if (!res->chunked) {
+ if (writeall(res, res->buf, res->len) == -1)
+ return -1;
+ res->len = 0;
+ return 0;
+ }
+
r = snprintf(buf, sizeof(buf), "%zx\r\n", res->len);
if (r < 0 || (size_t)r >= sizeof(buf)) {
log_warn("snprintf failed");
blob - c457f7765fa8d07caa8b0cb7f255800debb1787f
blob + 51cbdb77bac5f32482d1db3184660b2a6e2cac12
--- web/http.h
+++ web/http.h
METHOD_POST,
};
+enum http_version {
+ HTTP_1_0,
+ HTTP_1_1,
+};
+
struct request {
char buf[BUFSIZ];
size_t len;
char *path;
int method;
+ int version;
char *ctype;
size_t clen;
};
int http_parse(struct request *, int);
int http_read(struct request *, int);
-void http_response_init(struct reswriter *, int);
+void http_response_init(struct reswriter *, struct request *, int);
int http_reply(struct reswriter *, int, const char *, const char *);
int http_flush(struct reswriter *);
int http_write(struct reswriter *, const char *, size_t);
blob - 3904a24bfcba03acd812a6e6f3be7564415b3978
blob + 9e64528d62a13660ef647ef40120c6a03dc0efa6
--- web/web.c
+++ web/web.c
close(sock);
return;
}
- http_response_init(&res, sock);
+ http_response_init(&res, &req, sock);
route_dispatch(&res, &req);
http_flush(&res);
http_close(&res);