parent
32f478f370
commit
9702ab5851
|
@ -17,7 +17,7 @@ void route_test(struct uh_connection *con)
|
||||||
struct uh_value *header_ua = uh_get_header(con, "User-Agent");
|
struct uh_value *header_ua = uh_get_header(con, "User-Agent");
|
||||||
char unescaped_name[128];
|
char unescaped_name[128];
|
||||||
|
|
||||||
uh_send_head(con, UH_STATUS_OK, -1, NULL);
|
uh_send_head(con, HTTP_STATUS_OK, -1, NULL);
|
||||||
uh_printf_chunk(con, "<h1>Hello World</h1>");
|
uh_printf_chunk(con, "<h1>Hello World</h1>");
|
||||||
uh_printf_chunk(con, "<h1>Libuhttp v%s</h1>", uh_version());
|
uh_printf_chunk(con, "<h1>Libuhttp v%s</h1>", uh_version());
|
||||||
uh_printf_chunk(con, "<h1>Url: %.*s</h1>", (int)url->len, url->at);
|
uh_printf_chunk(con, "<h1>Url: %.*s</h1>", (int)url->len, url->at);
|
||||||
|
|
|
@ -5,74 +5,7 @@
|
||||||
#include "uhttp/config.h"
|
#include "uhttp/config.h"
|
||||||
#include "uhttp/log.h"
|
#include "uhttp/log.h"
|
||||||
#include "uhttp/buf.h"
|
#include "uhttp/buf.h"
|
||||||
|
#include "uhttp/http_parser.h"
|
||||||
/* HTTP Status Codes */
|
|
||||||
#define UH_STATUS_MAP(XX) \
|
|
||||||
XX(100, CONTINUE, Continue) \
|
|
||||||
XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
|
|
||||||
XX(102, PROCESSING, Processing) \
|
|
||||||
XX(200, OK, OK) \
|
|
||||||
XX(201, CREATED, Created) \
|
|
||||||
XX(202, ACCEPTED, Accepted) \
|
|
||||||
XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \
|
|
||||||
XX(204, NO_CONTENT, No Content) \
|
|
||||||
XX(205, RESET_CONTENT, Reset Content) \
|
|
||||||
XX(206, PARTIAL_CONTENT, Partial Content) \
|
|
||||||
XX(207, MULTI_STATUS, Multi-Status) \
|
|
||||||
XX(208, ALREADY_REPORTED, Already Reported) \
|
|
||||||
XX(226, IM_USED, IM Used) \
|
|
||||||
XX(300, MULTIPLE_CHOICES, Multiple Choices) \
|
|
||||||
XX(301, MOVED_PERMANENTLY, Moved Permanently) \
|
|
||||||
XX(302, FOUND, Found) \
|
|
||||||
XX(303, SEE_OTHER, See Other) \
|
|
||||||
XX(304, NOT_MODIFIED, Not Modified) \
|
|
||||||
XX(305, USE_PROXY, Use Proxy) \
|
|
||||||
XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \
|
|
||||||
XX(308, PERMANENT_REDIRECT, Permanent Redirect) \
|
|
||||||
XX(400, BAD_REQUEST, Bad Request) \
|
|
||||||
XX(401, UNAUTHORIZED, Unauthorized) \
|
|
||||||
XX(402, PAYMENT_REQUIRED, Payment Required) \
|
|
||||||
XX(403, FORBIDDEN, Forbidden) \
|
|
||||||
XX(404, NOT_FOUND, Not Found) \
|
|
||||||
XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \
|
|
||||||
XX(406, NOT_ACCEPTABLE, Not Acceptable) \
|
|
||||||
XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \
|
|
||||||
XX(408, REQUEST_TIMEOUT, Request Timeout) \
|
|
||||||
XX(409, CONFLICT, Conflict) \
|
|
||||||
XX(410, GONE, Gone) \
|
|
||||||
XX(411, LENGTH_REQUIRED, Length Required) \
|
|
||||||
XX(412, PRECONDITION_FAILED, Precondition Failed) \
|
|
||||||
XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \
|
|
||||||
XX(414, URI_TOO_LONG, URI Too Long) \
|
|
||||||
XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \
|
|
||||||
XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \
|
|
||||||
XX(417, EXPECTATION_FAILED, Expectation Failed) \
|
|
||||||
XX(421, MISDIRECTED_REQUEST, Misdirected Request) \
|
|
||||||
XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \
|
|
||||||
XX(423, LOCKED, Locked) \
|
|
||||||
XX(424, FAILED_DEPENDENCY, Failed Dependency) \
|
|
||||||
XX(426, UPGRADE_REQUIRED, Upgrade Required) \
|
|
||||||
XX(428, PRECONDITION_REQUIRED, Precondition Required) \
|
|
||||||
XX(429, TOO_MANY_REQUESTS, Too Many Requests) \
|
|
||||||
XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \
|
|
||||||
XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \
|
|
||||||
XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \
|
|
||||||
XX(501, NOT_IMPLEMENTED, Not Implemented) \
|
|
||||||
XX(502, BAD_GATEWAY, Bad Gateway) \
|
|
||||||
XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \
|
|
||||||
XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \
|
|
||||||
XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \
|
|
||||||
XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \
|
|
||||||
XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
|
|
||||||
XX(508, LOOP_DETECTED, Loop Detected) \
|
|
||||||
XX(510, NOT_EXTENDED, Not Extended) \
|
|
||||||
XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \
|
|
||||||
|
|
||||||
enum uh_status {
|
|
||||||
#define XX(num, name, string) UH_STATUS_##name = num,
|
|
||||||
UH_STATUS_MAP(XX)
|
|
||||||
#undef XX
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uh_server;
|
struct uh_server;
|
||||||
struct uh_connection;
|
struct uh_connection;
|
||||||
|
|
26
src/uhttp.c
26
src/uhttp.c
|
@ -14,11 +14,11 @@ const char *uh_version()
|
||||||
return UHTTP_VERSION_STRING;
|
return UHTTP_VERSION_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *uh_status_str(enum uh_status s)
|
static const char *http_status_str(enum http_status s)
|
||||||
{
|
{
|
||||||
switch (s) {
|
switch (s) {
|
||||||
#define XX(num, name, string) case num : return #string;
|
#define XX(num, name, string) case num : return #string;
|
||||||
UH_STATUS_MAP(XX)
|
HTTP_STATUS_MAP(XX)
|
||||||
#undef XX
|
#undef XX
|
||||||
}
|
}
|
||||||
return "<unknown>";
|
return "<unknown>";
|
||||||
|
@ -50,7 +50,7 @@ static void connection_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents
|
||||||
{
|
{
|
||||||
struct uh_connection *con = container_of(w, struct uh_connection, timer_watcher);
|
struct uh_connection *con = container_of(w, struct uh_connection, timer_watcher);
|
||||||
uh_log_debug("connection(%p) timeout", con);
|
uh_log_debug("connection(%p) timeout", con);
|
||||||
uh_send_error(con, UH_STATUS_REQUEST_TIMEOUT, NULL);
|
uh_send_error(con, HTTP_STATUS_REQUEST_TIMEOUT, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uh_con_reuse(struct uh_connection *con)
|
static int uh_con_reuse(struct uh_connection *con)
|
||||||
|
@ -77,13 +77,13 @@ static int on_url(http_parser *parser, const char *at, size_t len)
|
||||||
con->req.url.len = len;
|
con->req.url.len = len;
|
||||||
|
|
||||||
if (len > UH_URI_SIZE_LIMIT) {
|
if (len > UH_URI_SIZE_LIMIT) {
|
||||||
uh_send_error(con, UH_STATUS_URI_TOO_LONG, NULL);
|
uh_send_error(con, HTTP_STATUS_URI_TOO_LONG, NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (http_parser_parse_url(at, len, 0, &url)) {
|
if (http_parser_parse_url(at, len, 0, &url)) {
|
||||||
uh_log_err("http_parser_parse_url() failed");
|
uh_log_err("http_parser_parse_url() failed");
|
||||||
uh_send_error(con, UH_STATUS_BAD_REQUEST, NULL);
|
uh_send_error(con, HTTP_STATUS_BAD_REQUEST, NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ static int on_headers_complete(http_parser *parser)
|
||||||
struct uh_connection *con = container_of(parser, struct uh_connection, parser);
|
struct uh_connection *con = container_of(parser, struct uh_connection, parser);
|
||||||
|
|
||||||
if (parser->method != HTTP_GET && parser->method != HTTP_POST) {
|
if (parser->method != HTTP_GET && parser->method != HTTP_POST) {
|
||||||
uh_send_error(con, UH_STATUS_NOT_IMPLEMENTED, NULL);
|
uh_send_error(con, HTTP_STATUS_NOT_IMPLEMENTED, NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ static int on_body(http_parser *parser, const char *at, size_t len)
|
||||||
con->req.body.len += len;
|
con->req.body.len += len;
|
||||||
|
|
||||||
if (con->req.body.len > UH_BODY_SIZE_LIMIT) {
|
if (con->req.body.len > UH_BODY_SIZE_LIMIT) {
|
||||||
uh_send_error(con, UH_STATUS_PAYLOAD_TOO_LARGE, NULL);
|
uh_send_error(con, HTTP_STATUS_PAYLOAD_TOO_LARGE, NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ static int on_message_complete(http_parser *parser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uh_send_error(con, UH_STATUS_NOT_FOUND, NULL);
|
uh_send_error(con, HTTP_STATUS_NOT_FOUND, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,7 @@ handshake_done:
|
||||||
if (!memmem(buf->base, buf->len, "\r\n\r\n", 4)) {
|
if (!memmem(buf->base, buf->len, "\r\n\r\n", 4)) {
|
||||||
if (buf->len > UH_HEAD_SIZE_LIMIT) {
|
if (buf->len > UH_HEAD_SIZE_LIMIT) {
|
||||||
uh_log_err("HTTP head size too big");
|
uh_log_err("HTTP head size too big");
|
||||||
uh_send_error(con, UH_STATUS_BAD_REQUEST, NULL);
|
uh_send_error(con, HTTP_STATUS_BAD_REQUEST, NULL);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ handshake_done:
|
||||||
|
|
||||||
if (unlikely(parsered != len)) {
|
if (unlikely(parsered != len)) {
|
||||||
uh_log_err("http_parser_execute() failed:%s", http_errno_description(HTTP_PARSER_ERRNO(&con->parser)));
|
uh_log_err("http_parser_execute() failed:%s", http_errno_description(HTTP_PARSER_ERRNO(&con->parser)));
|
||||||
uh_send_error(con, UH_STATUS_BAD_REQUEST, NULL);
|
uh_send_error(con, HTTP_STATUS_BAD_REQUEST, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,7 +448,7 @@ int uh_printf(struct uh_connection *con, const char *fmt, ...)
|
||||||
|
|
||||||
static void send_status_line(struct uh_connection *con, int code)
|
static void send_status_line(struct uh_connection *con, int code)
|
||||||
{
|
{
|
||||||
const char *reason = uh_status_str(code);
|
const char *reason = http_status_str(code);
|
||||||
uh_printf(con, "HTTP/1.1 %d %s\r\nServer: Libuhttp %s\r\n",
|
uh_printf(con, "HTTP/1.1 %d %s\r\nServer: Libuhttp %s\r\n",
|
||||||
code, reason, UHTTP_VERSION_STRING);
|
code, reason, UHTTP_VERSION_STRING);
|
||||||
}
|
}
|
||||||
|
@ -473,9 +473,9 @@ void uh_send_error(struct uh_connection *con, int code, const char *reason)
|
||||||
http_parser *parser = &con->parser;
|
http_parser *parser = &con->parser;
|
||||||
|
|
||||||
if (!reason)
|
if (!reason)
|
||||||
reason = uh_status_str(code);
|
reason = http_status_str(code);
|
||||||
|
|
||||||
if (http_should_keep_alive(parser) && code < UH_STATUS_BAD_REQUEST) {
|
if (http_should_keep_alive(parser) && code < HTTP_STATUS_BAD_REQUEST) {
|
||||||
uh_send_head(con, code, strlen(reason), "Content-Type: text/plain\r\nConnection: keep-alive\r\n");
|
uh_send_head(con, code, strlen(reason), "Content-Type: text/plain\r\nConnection: keep-alive\r\n");
|
||||||
} else {
|
} else {
|
||||||
uh_send_head(con, code, strlen(reason), "Content-Type: text/plain\r\nConnection: close\r\n");
|
uh_send_head(con, code, strlen(reason), "Content-Type: text/plain\r\nConnection: close\r\n");
|
||||||
|
|
Loading…
Reference in New Issue