New member function for struct uh_client

cl->get_url(cl);
cl->get_var(cl, "name");

Signed-off-by: Jianhui Zhao <jianhuizhao329@gmail.com>
main
Jianhui Zhao 2018-01-01 11:44:46 +08:00
parent 89851e3f33
commit cbe7173205
6 changed files with 69 additions and 21 deletions

View File

@ -73,8 +73,10 @@ static void hello_action(struct uh_client *cl)
cl->chunk_printf(cl, "<h1>Hello Libuhttpd %s</h1>", UHTTPD_VERSION_STRING);
cl->chunk_printf(cl, "<h1>REMOTE_ADDR: %s</h1>", cl->get_peer_addr(cl));
cl->chunk_printf(cl, "<h1>URL: %s</h1>", cl->get_url(cl));
cl->chunk_printf(cl, "<h1>PATH: %s</h1>", cl->get_path(cl));
cl->chunk_printf(cl, "<h1>QUERY: %s</h1>", cl->get_query(cl));
cl->chunk_printf(cl, "<h1>VAR name: %s</h1>", cl->get_var(cl, "name"));
cl->chunk_printf(cl, "<h1>BODY:%s</h1>", cl->get_body(cl, &body_len));
cl->request_done(cl);
}

View File

@ -74,8 +74,10 @@ static void hello_action(struct uh_client *cl)
cl->chunk_printf(cl, "<h1>Hello Libuhttpd %s</h1>", UHTTPD_VERSION_STRING);
cl->chunk_printf(cl, "<h1>REMOTE_ADDR: %s</h1>", cl->get_peer_addr(cl));
cl->chunk_printf(cl, "<h1>URL: %s</h1>", cl->get_url(cl));
cl->chunk_printf(cl, "<h1>PATH: %s</h1>", cl->get_path(cl));
cl->chunk_printf(cl, "<h1>QUERY: %s</h1>", cl->get_query(cl));
cl->chunk_printf(cl, "<h1>VAR name: %s</h1>", cl->get_var(cl, "name"));
cl->chunk_printf(cl, "<h1>BODY:%s</h1>", cl->get_body(cl, &body_len));
cl->request_done(cl);
}

View File

@ -29,8 +29,10 @@ static void hello_action(struct uh_client *cl)
cl->chunk_printf(cl, "<h1>Hello Libuhttpd %s</h1>", UHTTPD_VERSION_STRING);
cl->chunk_printf(cl, "<h1>REMOTE_ADDR: %s</h1>", cl->get_peer_addr(cl));
cl->chunk_printf(cl, "<h1>URL: %s</h1>", cl->get_url(cl));
cl->chunk_printf(cl, "<h1>PATH: %s</h1>", cl->get_path(cl));
cl->chunk_printf(cl, "<h1>QUERY: %s</h1>", cl->get_query(cl));
cl->chunk_printf(cl, "<h1>VAR name: %s</h1>", cl->get_var(cl, "name"));
cl->chunk_printf(cl, "<h1>BODY:%s</h1>", cl->get_body(cl, &body_len));
cl->request_done(cl);
}

View File

@ -102,19 +102,29 @@ static inline const char *client_get_peer_addr(struct uh_client *cl)
return inet_ntoa(cl->peer_addr.sin_addr);
}
static inline const char *client_get_url(struct uh_client *cl)
{
return kvlist_get(&cl->request.url, "url");
}
static inline const char *client_get_path(struct uh_client *cl)
{
return kvlist_get(&cl->request.hdr, "path");
return kvlist_get(&cl->request.url, "path");
}
static inline const char *client_get_query(struct uh_client *cl)
{
return kvlist_get(&cl->request.hdr, "query");
return kvlist_get(&cl->request.url, "query");
}
const char *client_get_var(struct uh_client *cl, const char *name)
{
return kvlist_get(&cl->request.var, name);
}
static inline const char *client_get_header(struct uh_client *cl, const char *name)
{
return kvlist_get(&cl->request.hdr, name);
return kvlist_get(&cl->request.header, name);
}
static inline const char *client_get_body(struct uh_client *cl, int *len)
@ -125,13 +135,7 @@ static inline const char *client_get_body(struct uh_client *cl, int *len)
static void uh_handle_request(struct uh_client *cl)
{
char *path = kvlist_get(&cl->request.hdr, "path");
#if (UHTTPD_DEBUG)
const char *name, *value;
kvlist_for_each(&cl->request.hdr, name, value) {
uh_log_debug("%s: %s", name, value);
}
#endif
char *path = kvlist_get(&cl->request.url, "path");
if (handle_action_request(cl, path))
return;
@ -188,7 +192,9 @@ static void client_request_done(struct uh_client *cl)
memset(&cl->request, 0, sizeof(cl->request));
memset(&cl->dispatch, 0, sizeof(cl->dispatch));
kvlist_init(&cl->request.hdr, hdr_get_len);
kvlist_init(&cl->request.url, hdr_get_len);
kvlist_init(&cl->request.var, hdr_get_len);
kvlist_init(&cl->request.header, hdr_get_len);
uloop_timeout_set(&cl->timeout, UHTTPD_CONNECTION_TIMEOUT * 1000);
}
@ -203,7 +209,9 @@ static void client_free(struct uh_client *cl)
shutdown(cl->sfd.fd.fd, SHUT_RDWR);
close(cl->sfd.fd.fd);
list_del(&cl->list);
kvlist_free(&cl->request.hdr);
kvlist_free(&cl->request.url);
kvlist_free(&cl->request.var);
kvlist_free(&cl->request.header);
cl->srv->nclients--;
uh_log_debug("client_free: %s:%d", inet_ntoa(cl->peer_addr.sin_addr), cl->peer_addr.sin_port);
@ -211,6 +219,26 @@ static void client_free(struct uh_client *cl)
}
}
static void parse_var(struct uh_client *cl, char *query)
{
struct kvlist *kv = &cl->request.var;
char *k, *v;
while (query && *query) {
k = query;
query = strchr(query, '&');
if (query)
*query++ = 0;
v = strchr(k, '=');
if (v)
*v++ = 0;
if (*k && v)
kvlist_set(kv, k, v);
}
}
static int client_parse_request(struct uh_client *cl, char *data)
{
struct http_request *req = &cl->request;
@ -231,23 +259,29 @@ static int client_parse_request(struct uh_client *cl, char *data)
return CLIENT_STATE_DONE;
}
kvlist_set(&req->url, "url", url);
p = strchr(url, '?');
if (p) {
*p = 0;
if (p[1])
kvlist_set(&cl->request.hdr, "query", p + 1);
if (p[1]) {
kvlist_set(&req->url, "query", p + 1);
parse_var(cl, p + 1);
}
}
if (uh_urldecode(path, sizeof(path) - 1, url, strlen(url)) < 0)
return CLIENT_STATE_DONE;
kvlist_set(&cl->request.hdr, "path", path);
kvlist_set(&req->url, "path", path);
req->method = h_method;
req->version = h_version;
if (req->version < UH_HTTP_VER_1_1)
cl->connection_close = true;
uh_log_debug("http path: %s", kvlist_get(&req->url, "path"));
uh_log_debug("http query: %s", kvlist_get(&req->url, "query"));
uh_log_debug("http method: %s", http_methods[h_method]);
uh_log_debug("http version: %s", http_versions[h_version]);
@ -324,7 +358,7 @@ static inline bool client_data_cb(struct uh_client *cl, char *buf, int len)
static void client_parse_header(struct uh_client *cl, char *data)
{
struct http_request *r = &cl->request;
struct http_request *req = &cl->request;
char *err;
char *name;
char *val;
@ -347,7 +381,7 @@ static void client_parse_header(struct uh_client *cl, char *data)
*name = tolower(*name);
if (!strcmp(data, "content-length")) {
r->content_length = strtoul(val, &err, 0);
req->content_length = strtoul(val, &err, 0);
if (err && *err) {
cl->send_error(cl, 400, "Bad Request", "Invalid Content-Length");
return;
@ -359,7 +393,7 @@ static void client_parse_header(struct uh_client *cl, char *data)
cl->connection_close = true;
}
kvlist_set(&cl->request.hdr, data, val);
kvlist_set(&req->header, data, val);
cl->state = CLIENT_STATE_HEADER;
}
@ -486,7 +520,9 @@ void uh_accept_client(struct uh_server *srv, bool ssl)
uloop_timeout_set(&cl->timeout, UHTTPD_CONNECTION_TIMEOUT * 1000);
list_add(&cl->list, &srv->clients);
kvlist_init(&cl->request.hdr, hdr_get_len);
kvlist_init(&cl->request.url, hdr_get_len);
kvlist_init(&cl->request.var, hdr_get_len);
kvlist_init(&cl->request.header, hdr_get_len);
cl->srv = srv;
cl->srv->nclients++;
@ -507,8 +543,10 @@ void uh_accept_client(struct uh_server *srv, bool ssl)
cl->chunk_vprintf = uh_chunk_vprintf;
cl->get_peer_addr = client_get_peer_addr;
cl->get_url = client_get_url;
cl->get_path = client_get_path;
cl->get_query = client_get_query;
cl->get_var = client_get_var;
cl->get_header = client_get_header;
cl->get_body = client_get_body;

View File

@ -50,7 +50,9 @@ struct http_request {
enum http_method method;
enum http_version version;
int content_length;
struct kvlist hdr;
struct kvlist url;
struct kvlist var;
struct kvlist header;
};
struct uh_client;
@ -106,8 +108,10 @@ struct uh_client {
void (*chunk_vprintf)(struct uh_client *cl, const char *format, va_list arg);
const char *(*get_peer_addr)(struct uh_client *cl);
const char *(*get_url)(struct uh_client *cl);
const char *(*get_path)(struct uh_client *cl);
const char *(*get_query)(struct uh_client *cl);
const char *(*get_var)(struct uh_client *cl, const char *name);
const char *(*get_header)(struct uh_client *cl, const char *name);
const char *(*get_body)(struct uh_client *cl, int *len);
};

View File

@ -296,7 +296,7 @@ static void uh_file_response_200(struct uh_client *cl, struct stat *s)
static int uh_file_if_modified_since(struct uh_client *cl, struct stat *s)
{
const char *date = kvlist_get(&cl->request.hdr, "if-modified-since");
const char *date = kvlist_get(&cl->request.header, "if-modified-since");
struct tm t;
if (!date)