Fix liRequestUri struct

personal/stbuehler/wip
Stefan Bühler 14 years ago
parent a8a761946c
commit 77f2a832e7

@ -6,14 +6,15 @@
#endif
struct liRequestUri {
GString *raw;
GString *raw; /* may include scheme and authority before path_raw */
GString *raw_path, *raw_orig_path; /* not decoded path with querystring */
GString *scheme;
GString *authority;
GString *path, *orig_path;
GString *authority; /* authority: may include auth and ports and hostname trailing dots */
GString *path;
GString *query;
GString *host; /* without userinfo and port */
GString *host; /* without userinfo and port and trailing dots */
};
struct liPhysical {

@ -8,10 +8,11 @@ void li_request_init(liRequest *req) {
req->http_version = LI_HTTP_VERSION_UNSET;
req->uri.raw = g_string_sized_new(0);
req->uri.raw_path = g_string_sized_new(0);
req->uri.raw_orig_path = g_string_sized_new(0);
req->uri.scheme = g_string_sized_new(0);
req->uri.authority = g_string_sized_new(0);
req->uri.path = g_string_sized_new(0);
req->uri.orig_path = g_string_sized_new(0);
req->uri.query = g_string_sized_new(0);
req->uri.host = g_string_sized_new(0);
@ -26,10 +27,11 @@ void li_request_reset(liRequest *req) {
req->http_version = LI_HTTP_VERSION_UNSET;
g_string_truncate(req->uri.raw, 0);
g_string_truncate(req->uri.raw_path, 0);
g_string_truncate(req->uri.raw_orig_path, 0);
g_string_truncate(req->uri.scheme, 0);
g_string_truncate(req->uri.authority, 0);
g_string_truncate(req->uri.path, 0);
g_string_truncate(req->uri.orig_path, 0);
g_string_truncate(req->uri.query, 0);
g_string_truncate(req->uri.host, 0);
@ -44,10 +46,11 @@ void li_request_clear(liRequest *req) {
req->http_version = LI_HTTP_VERSION_UNSET;
g_string_free(req->uri.raw, TRUE);
g_string_free(req->uri.raw_path, TRUE);
g_string_free(req->uri.raw_orig_path, TRUE);
g_string_free(req->uri.scheme, TRUE);
g_string_free(req->uri.authority, TRUE);
g_string_free(req->uri.path, TRUE);
g_string_free(req->uri.orig_path, TRUE);
g_string_free(req->uri.query, TRUE);
g_string_free(req->uri.host, TRUE);
@ -79,8 +82,8 @@ static gboolean request_parse_url(liVRequest *vr) {
li_url_decode(req->uri.path);
li_path_simplify(req->uri.path);
if (0 == req->uri.orig_path->len) {
g_string_append_len(req->uri.orig_path, GSTR_LEN(req->uri.raw)); /* save orig raw uri */
if (0 == req->uri.raw_orig_path->len) {
g_string_append_len(req->uri.raw_orig_path, GSTR_LEN(req->uri.raw_path)); /* save orig raw uri */
}
return TRUE;
@ -91,6 +94,12 @@ gboolean li_request_validate_header(liConnection *con) {
liHttpHeader *hh;
GList *l;
if (con->is_ssl) {
g_string_append_len(req->uri.scheme, CONST_STR_LEN("https"));
} else {
g_string_append_len(req->uri.scheme, CONST_STR_LEN("http"));
}
switch (req->http_version) {
case LI_HTTP_VERSION_1_0:
if (!li_http_header_is(req->headers, CONST_STR_LEN("connection"), CONST_STR_LEN("keep-alive")))
@ -121,14 +130,11 @@ gboolean li_request_validate_header(liConnection *con) {
hh = (liHttpHeader*) l->data;
g_string_append_len(req->uri.authority, HEADER_VALUE_LEN(hh));
if (!li_parse_hostname(&req->uri)) {
bad_request(con, 400); /* bad request */
return FALSE;
}
/* check header after we parsed the url, as it may override uri.authority */
}
/* Need hostname in HTTP/1.1 */
if (req->uri.host->len == 0 && req->http_version == LI_HTTP_VERSION_1_1) {
if (req->uri.authority->len == 0 && req->http_version == LI_HTTP_VERSION_1_1) {
bad_request(con, 400); /* bad request */
return FALSE;
}
@ -139,6 +145,20 @@ gboolean li_request_validate_header(liConnection *con) {
return FALSE;
}
if (req->uri.host->len == 0 && req->uri.authority->len != 0) {
if (!li_parse_hostname(&req->uri)) {
bad_request(con, 400); /* bad request */
return FALSE;
}
}
/* remove trailing dots from hostname */
{
guint i = req->uri.host->len;
while (i > 0 && req->uri.host->str[i-1] == '.') i--;
g_string_truncate(req->uri.host, i);
}
/* content-length */
hh = li_http_header_lookup(req->headers, CONST_STR_LEN("content-length"));
if (hh) {

@ -9,12 +9,16 @@
action mark { mark = fpc; }
action mark_host { host_mark = fpc; }
action mark_url { url_mark = fpc; }
action save_host {
g_string_truncate(uri->host, 0);
g_string_append_len(uri->host, host_mark, fpc - host_mark);
g_string_ascii_down(uri->host);
}
action save_url {
g_string_append_len(uri->raw_path, url_mark, fpc - url_mark);
}
action save_authority {
g_string_truncate(uri->authority, 0);
g_string_append_len(uri->authority, mark, fpc - mark);
@ -26,6 +30,9 @@
action save_query {
g_string_append_len(uri->query, mark, fpc - mark);
}
action save_scheme {
g_string_append_len(uri->scheme, mark, fpc - mark);
}
pct_encoded = "%" xdigit xdigit;
@ -67,9 +74,9 @@
query = ( pchar | "/" | "?" )* >mark %save_query;
fragment = ( pchar | "/" | "?" )*;
URI_path = path ( "?" query )? ( "#" fragment )?;
URI_path = (path >mark_url ( "?" query )?) %save_url ( "#" fragment )?;
URI = scheme "://" (authority >mark %save_authority) URI_path;
URI = (scheme >mark %save_scheme) "://" (authority >mark %save_authority) URI_path;
parse_URI := URI | ("*" >mark %save_path) | URI_path;
parse_Hostname := (host >mark_host %save_host) ( ":" port )?;
@ -79,7 +86,7 @@
gboolean li_parse_raw_url(liRequestUri *uri) {
const char *p, *pe, *eof;
const char *mark = NULL, *host_mark = NULL;
const char *mark = NULL, *host_mark = NULL, *url_mark = NULL;
int cs;
p = uri->raw->str;
@ -95,7 +102,7 @@ gboolean li_parse_raw_url(liRequestUri *uri) {
gboolean li_parse_hostname(liRequestUri *uri) {
const char *p, *pe, *eof;
const char *mark = NULL, *host_mark = NULL;
const char *mark = NULL, *host_mark = NULL, *url_mark = NULL;
int cs;
g_string_ascii_down(uri->authority);

@ -290,7 +290,7 @@ static GString *al_format_log(liConnection *con, al_data *ald, GArray *format) {
case AL_FORMAT_FIRST_LINE:
g_string_append_len(str, GSTR_LEN(req->http_method_str));
g_string_append_c(str, ' ');
al_append_escaped(str, req->uri.orig_path);
al_append_escaped(str, req->uri.raw_orig_path);
if (req->uri.query->len) {
g_string_append_c(str, '?');
al_append_escaped(str, req->uri.query);

@ -212,7 +212,7 @@ static liHandlerResult dirlist(liVRequest *vr, gpointer param, gpointer *context
host = vr->request.uri.authority->len ? vr->request.uri.authority : vr->con->local_addr_str;
uri = g_string_sized_new(
8 /* https:// */ + host->len +
vr->request.uri.orig_path->len + 2 /* /? */ + vr->request.uri.query->len
vr->request.uri.raw_orig_path->len + 2 /* /? */ + vr->request.uri.query->len
);
if (vr->con->is_ssl)
@ -220,7 +220,7 @@ static liHandlerResult dirlist(liVRequest *vr, gpointer param, gpointer *context
else
g_string_append_len(uri, CONST_STR_LEN("http://"));
g_string_append_len(uri, GSTR_LEN(host));
g_string_append_len(uri, GSTR_LEN(vr->request.uri.orig_path));
g_string_append_len(uri, GSTR_LEN(vr->request.uri.raw_orig_path));
g_string_append_c(uri, '/');
if (vr->request.uri.query->len) {
g_string_append_c(uri, '?');

@ -380,9 +380,9 @@ static void fastcgi_env_create(liVRequest *vr, liEnvironmentDup *envdup, GByteAr
fastcgi_env_add(buf, envdup, CONST_STR_LEN("SCRIPT_FILENAME"), GSTR_LEN(vr->physical.path));
fastcgi_env_add(buf, envdup, CONST_STR_LEN("DOCUMENT_ROOT"), GSTR_LEN(vr->physical.doc_root));
fastcgi_env_add(buf, envdup, CONST_STR_LEN("REQUEST_URI"), GSTR_LEN(vr->request.uri.orig_path));
if (!g_string_equal(vr->request.uri.orig_path, vr->request.uri.raw)) {
fastcgi_env_add(buf, envdup, CONST_STR_LEN("REDIRECT_URI"), GSTR_LEN(vr->request.uri.raw));
fastcgi_env_add(buf, envdup, CONST_STR_LEN("REQUEST_URI"), GSTR_LEN(vr->request.uri.raw_orig_path));
if (!g_string_equal(vr->request.uri.raw_orig_path, vr->request.uri.raw_path)) {
fastcgi_env_add(buf, envdup, CONST_STR_LEN("REDIRECT_URI"), GSTR_LEN(vr->request.uri.raw_path));
}
fastcgi_env_add(buf, envdup, CONST_STR_LEN("QUERY_STRING"), GSTR_LEN(vr->request.uri.query));

@ -224,7 +224,7 @@ static gboolean redirect_internal(liVRequest *vr, GString *dest, redirect_rule *
GMatchInfo *match_info = NULL;
if (raw)
path = vr->request.uri.raw->str;
path = vr->request.uri.raw_path->str;
else
path = vr->request.uri.path->str;

@ -234,7 +234,7 @@ static gboolean rewrite_internal(liVRequest *vr, GString *dest_path, GString *de
GMatchInfo *match_info = NULL;
if (raw)
path = vr->request.uri.raw->str;
path = vr->request.uri.raw_path->str;
else
path = vr->request.uri.path->str;

Loading…
Cancel
Save