Support parse url

Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
main
Jianhui Zhao 2020-03-14 14:03:48 +08:00
parent 5f4f6e0d97
commit 040763a64a
4 changed files with 41 additions and 17 deletions

View File

@ -36,7 +36,8 @@ static void on_request(struct uh_connection *conn)
conn->send_head(conn, 200, -1, NULL); conn->send_head(conn, 200, -1, NULL);
conn->chunk_printf(conn, "I'm Libuhttpd: %s\n", UHTTPD_VERSION_STRING); conn->chunk_printf(conn, "I'm Libuhttpd: %s\n", UHTTPD_VERSION_STRING);
conn->chunk_printf(conn, "Url: %s\n", conn->get_url(conn)); conn->chunk_printf(conn, "Path: %s\n", conn->get_path(conn));
conn->chunk_printf(conn, "Query: %s\n", conn->get_query(conn));
conn->chunk_printf(conn, "User-Agent: %s\n", conn->get_header(conn, "User-Agent")); conn->chunk_printf(conn, "User-Agent: %s\n", conn->get_header(conn, "User-Agent"));
conn->chunk_printf(conn, "Body: %.*s\n", body_len, body); conn->chunk_printf(conn, "Body: %.*s\n", body_len, body);
conn->chunk_end(conn); conn->chunk_end(conn);

View File

@ -150,13 +150,28 @@ static void conn_redirect(struct uh_connection *conn, int code, const char *loca
/* data of the request field */ /* data of the request field */
#define O2D(c, o) ((const char *)c->rb.data + o) #define O2D(c, o) ((const char *)c->rb.data + o)
static const char *conn_get_url(struct uh_connection *conn) static const char *conn_get_path(struct uh_connection *conn)
{ {
struct http_parser_url *u = &conn->url_parser;
struct uh_request *req = &conn->req; struct uh_request *req = &conn->req;
if (!req->url) if (!req->url.path)
req->url = strndup(O2D(conn, req->url_info.offset), req->url_info.len); req->url.path = strndup(O2D(conn, u->field_data[UF_PATH].off) + req->url.offset, u->field_data[UF_PATH].len);
return req->url; return req->url.path;
}
static const char *conn_get_query(struct uh_connection *conn)
{
struct http_parser_url *u = &conn->url_parser;
struct uh_request *req = &conn->req;
if (!(u->field_set & (1 << UF_QUERY)))
return "";
if (!req->url.query)
req->url.query = strndup(O2D(conn, u->field_data[UF_QUERY].off) + req->url.offset, u->field_data[UF_QUERY].len);
return req->url.query;
} }
static const char *conn_get_header(struct uh_connection *conn, const char *name) static const char *conn_get_header(struct uh_connection *conn, const char *name)
@ -204,10 +219,11 @@ static int on_url_cb(struct http_parser *parser, const char *at, size_t length)
struct uh_connection *conn = (struct uh_connection *)parser->data; struct uh_connection *conn = (struct uh_connection *)parser->data;
struct uh_request *req = &conn->req; struct uh_request *req = &conn->req;
req->url_info.offset = ROF(conn, at); req->url.offset = ROF(conn, at);
req->url_info.len = length;
return 0; http_parser_url_init(&conn->url_parser);
return http_parser_parse_url(at, length, false, &conn->url_parser);
} }
static int on_header_field_cb(struct http_parser *parser, const char *at, size_t length) static int on_header_field_cb(struct http_parser *parser, const char *at, size_t length)
@ -257,7 +273,7 @@ static bool run_plugins(struct uh_connection *conn)
struct uh_plugin *p = conn->srv->plugins; struct uh_plugin *p = conn->srv->plugins;
while (p) { while (p) {
if (!strcmp(conn->get_url(conn), p->path)) { if (!strcmp(conn->get_path(conn), p->path)) {
p->handler(conn); p->handler(conn);
return true; return true;
} }
@ -281,8 +297,11 @@ static int on_message_complete_cb(struct http_parser *parser)
buffer_pull(&conn->rb, NULL, buffer_length(&conn->rb)); buffer_pull(&conn->rb, NULL, buffer_length(&conn->rb));
if (req->url) if (req->url.path)
free(req->url); free(req->url.path);
if (req->url.query)
free(req->url.query);
for (i = 0; i < UHTTPD_MAX_HEADER_NUM; i++) { for (i = 0; i < UHTTPD_MAX_HEADER_NUM; i++) {
if (req->headers[i].name) if (req->headers[i].name)
@ -513,7 +532,8 @@ struct uh_connection *uh_new_connection(struct uh_server *srv, int sock, struct
conn->chunk_vprintf = conn_chunk_vprintf; conn->chunk_vprintf = conn_chunk_vprintf;
conn->chunk_end = conn_chunk_end; conn->chunk_end = conn_chunk_end;
conn->get_url = conn_get_url; conn->get_path = conn_get_path;
conn->get_query = conn_get_query;
conn->get_header = conn_get_header; conn->get_header = conn_get_header;
conn->get_body = conn_get_body; conn->get_body = conn_get_body;

View File

@ -44,9 +44,10 @@ struct uh_server;
struct uh_request { struct uh_request {
struct { struct {
int offset; int offset;
int len; char *path;
} url_info; char *query;
char *url; } url;
struct { struct {
int name_offset; int name_offset;
int name_len; int name_len;
@ -80,6 +81,7 @@ struct uh_connection {
struct uh_server *srv; struct uh_server *srv;
struct sockaddr_in addr; struct sockaddr_in addr;
struct http_parser parser; struct http_parser parser;
struct http_parser_url url_parser;
struct uh_connection *prev; struct uh_connection *prev;
struct uh_connection *next; struct uh_connection *next;
void (*free)(struct uh_connection *conn); void (*free)(struct uh_connection *conn);
@ -94,7 +96,8 @@ struct uh_connection {
void (*chunk_printf)(struct uh_connection *conn, const char *format, ...); void (*chunk_printf)(struct uh_connection *conn, const char *format, ...);
void (*chunk_vprintf)(struct uh_connection *conn, const char *format, va_list arg); void (*chunk_vprintf)(struct uh_connection *conn, const char *format, va_list arg);
void (*chunk_end)(struct uh_connection *conn); void (*chunk_end)(struct uh_connection *conn);
const char *(*get_url)(struct uh_connection *conn); const char *(*get_path)(struct uh_connection *conn);
const char *(*get_query)(struct uh_connection *conn);
const char *(*get_header)(struct uh_connection *conn, const char *name); const char *(*get_header)(struct uh_connection *conn, const char *name);
const char *(*get_body)(struct uh_connection *conn, int *len); const char *(*get_body)(struct uh_connection *conn, int *len);
}; };

View File

@ -27,7 +27,7 @@
static void test_handler(struct uh_connection *conn) static void test_handler(struct uh_connection *conn)
{ {
conn->send_head(conn, 200, -1, NULL); conn->send_head(conn, 200, -1, NULL);
conn->chunk_printf(conn, "Url: %s\n", conn->get_url(conn)); conn->chunk_printf(conn, "Path: %s\n", conn->get_path(conn));
conn->chunk_end(conn); conn->chunk_end(conn);
} }