From e556a487e0a85fd0dd61732732103108ace09c81 Mon Sep 17 00:00:00 2001 From: Sergey Lyubka <valenok@gmail.com> Date: Sat, 7 Sep 2013 18:49:24 +0100 Subject: [PATCH] Fix for the SCRIPT_NAME in the presence of PATH_INFO, https://code.google.com/p/mongoose/issues/detail?id=403 --- mongoose.c | 46 +++++++++++++++++++++++++--------------------- test/test.pl | 4 ++-- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/mongoose.c b/mongoose.c index c61700382..952b4ce7b 100644 --- a/mongoose.c +++ b/mongoose.c @@ -1849,7 +1849,7 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf, } // Support PATH_INFO for CGI scripts. - for (p = buf + strlen(buf); p > buf + 1; p--) { + for (p = buf + strlen(root == NULL ? "" : root); *p != '\0'; p++) { if (*p == '/') { *p = '\0'; if (match_prefix(conn->ctx->config[CGI_EXTENSIONS], @@ -3276,6 +3276,7 @@ static char *addenv(struct cgi_env_block *block, const char *fmt, ...) { static void prepare_cgi_environment(struct mg_connection *conn, const char *prog, struct cgi_env_block *blk) { + const struct mg_request_info *ri = &conn->request_info; const char *s, *slash; struct vec var_vec; char *p, src_addr[IP_ADDR_STR_LEN]; @@ -3298,18 +3299,25 @@ static void prepare_cgi_environment(struct mg_connection *conn, // TODO(lsm): fix this for IPv6 case addenv(blk, "SERVER_PORT=%d", ntohs(conn->client.lsa.sin.sin_port)); - addenv(blk, "REQUEST_METHOD=%s", conn->request_info.request_method); + addenv(blk, "REQUEST_METHOD=%s", ri->request_method); addenv(blk, "REMOTE_ADDR=%s", src_addr); - addenv(blk, "REMOTE_PORT=%d", conn->request_info.remote_port); - addenv(blk, "REQUEST_URI=%s", conn->request_info.uri); + addenv(blk, "REMOTE_PORT=%d", ri->remote_port); + addenv(blk, "REQUEST_URI=%s%s%s", ri->uri, + ri->query_string == NULL ? "" : "?", + ri->query_string == NULL ? "" : ri->query_string); // SCRIPT_NAME - assert(conn->request_info.uri[0] == '/'); - slash = strrchr(conn->request_info.uri, '/'); - if ((s = strrchr(prog, '/')) == NULL) - s = prog; - addenv(blk, "SCRIPT_NAME=%.*s%s", (int) (slash - conn->request_info.uri), - conn->request_info.uri, s); + if (conn->path_info != NULL) { + addenv(blk, "SCRIPT_NAME=%.*s", + (int) (strlen(ri->uri) - strlen(conn->path_info)), ri->uri); + addenv(blk, "PATH_INFO=%s", conn->path_info); + } else { + s = strrchr(prog, '/'); + slash = strrchr(ri->uri, '/'); + addenv(blk, "SCRIPT_NAME=%.*s%s", + slash == NULL ? 0 : (int) (slash - ri->uri), ri->uri, + s == NULL ? prog : s); + } addenv(blk, "SCRIPT_FILENAME=%s", prog); addenv(blk, "PATH_TRANSLATED=%s", prog); @@ -3318,8 +3326,9 @@ static void prepare_cgi_environment(struct mg_connection *conn, if ((s = mg_get_header(conn, "Content-Type")) != NULL) addenv(blk, "CONTENT_TYPE=%s", s); - if (conn->request_info.query_string != NULL) - addenv(blk, "QUERY_STRING=%s", conn->request_info.query_string); + if (ri->query_string != NULL) { + addenv(blk, "QUERY_STRING=%s", ri->query_string); + } if ((s = mg_get_header(conn, "Content-Length")) != NULL) addenv(blk, "CONTENT_LENGTH=%s", s); @@ -3327,10 +3336,6 @@ static void prepare_cgi_environment(struct mg_connection *conn, if ((s = getenv("PATH")) != NULL) addenv(blk, "PATH=%s", s); - if (conn->path_info != NULL) { - addenv(blk, "PATH_INFO=%s", conn->path_info); - } - #if defined(_WIN32) if ((s = getenv("COMSPEC")) != NULL) { addenv(blk, "COMSPEC=%s", s); @@ -3355,16 +3360,15 @@ static void prepare_cgi_environment(struct mg_connection *conn, if ((s = getenv("PERLLIB")) != NULL) addenv(blk, "PERLLIB=%s", s); - if (conn->request_info.remote_user != NULL) { - addenv(blk, "REMOTE_USER=%s", conn->request_info.remote_user); + if (ri->remote_user != NULL) { + addenv(blk, "REMOTE_USER=%s", ri->remote_user); addenv(blk, "%s", "AUTH_TYPE=Digest"); } // Add all headers as HTTP_* variables - for (i = 0; i < conn->request_info.num_headers; i++) { + for (i = 0; i < ri->num_headers; i++) { p = addenv(blk, "HTTP_%s=%s", - conn->request_info.http_headers[i].name, - conn->request_info.http_headers[i].value); + ri->http_headers[i].name, ri->http_headers[i].value); // Convert variable name into uppercase, and change - to _ for (; *p != '=' && *p != '\0'; p++) { diff --git a/test/test.pl b/test/test.pl index dbe508bd1..32406fb88 100644 --- a/test/test.pl +++ b/test/test.pl @@ -375,8 +375,6 @@ unless (scalar(@ARGV) > 0 and $ARGV[0] eq "basic_tests") { 'HTTP_MY_HDR=abc', 'HTTP_* env'); o("GET /env.cgi HTTP/1.0\n\r\nSOME_TRAILING_DATA_HERE", 'HTTP/1.1 200 OK', 'GET CGI with trailing data'); -# o("GET /env.cgi/foo/bar?a=b HTTP/1.0\n\n", -# 'SCRIPT_NAME=/env.cgi\s', 'SCRIPT_NAME for CGI with PATH_INFO'); o("GET /env.cgi%20 HTTP/1.0\n\r\n", 'HTTP/1.1 404', 'CGI Win32 code disclosure (%20)'); @@ -392,6 +390,8 @@ unless (scalar(@ARGV) > 0 and $ARGV[0] eq "basic_tests") { o("GET /env.cgi HTTP/1.0\n\r\n", '\nCGI_BAZ=baz\n', '-cgi_env 3'); o("GET /env.cgi/a/b/98 HTTP/1.0\n\r\n", 'PATH_INFO=/a/b/98\n', 'PATH_INFO'); o("GET /env.cgi/a/b/9 HTTP/1.0\n\r\n", 'PATH_INFO=/a/b/9\n', 'PATH_INFO'); + o("GET /env.cgi/foo/bar?a=b HTTP/1.0\n\n", + 'SCRIPT_NAME=/env.cgi\s', 'SCRIPT_NAME for CGI with PATH_INFO'); # Check that CGI's current directory is set to script's directory my $copy_cmd = on_windows() ? 'copy' : 'cp'; -- GitLab