Fix liRequestUri struct
This commit is contained in:
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…
Reference in New Issue