|
@@ -2330,6 +2330,7 @@ struct mg_connection {
|
|
|
char *path_info; /* PATH_INFO part of the URL */
|
|
|
|
|
|
int must_close; /* 1 if connection must be closed */
|
|
|
+ int accept_gzip; /* 1 if gzip encoding is accepted */
|
|
|
int in_error_handler; /* 1 if in handler for user defined error
|
|
|
* pages */
|
|
|
int handled_requests; /* Number of requests handled by this connection
|
|
@@ -6487,9 +6488,9 @@ substitute_index_file(struct mg_connection *conn,
|
|
|
|
|
|
|
|
|
static void
|
|
|
-interpret_uri(struct mg_connection *conn, /* in: request (must be valid) */
|
|
|
- char *filename, /* out: filename */
|
|
|
- size_t filename_buf_len, /* in: size of filename buffer */
|
|
|
+interpret_uri(struct mg_connection *conn, /* in/out: request (must be valid) */
|
|
|
+ char *filename, /* out: filename */
|
|
|
+ size_t filename_buf_len, /* in: size of filename buffer */
|
|
|
struct mg_file_stat *filestat, /* out: file status structure */
|
|
|
int *is_found, /* out: file found (directly) */
|
|
|
int *is_script_resource, /* out: handled by a script? */
|
|
@@ -6536,8 +6537,16 @@ interpret_uri(struct mg_connection *conn, /* in: request (must be valid) */
|
|
|
*is_websocket_request = 0;
|
|
|
#endif /* USE_WEBSOCKET */
|
|
|
|
|
|
+ /* Step 4: Check if gzip encoded response is allowed */
|
|
|
+ conn->accept_gzip = 0;
|
|
|
+ if ((accept_encoding = mg_get_header(conn, "Accept-Encoding")) != NULL) {
|
|
|
+ if (strstr(accept_encoding, "gzip") != NULL) {
|
|
|
+ conn->accept_gzip = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
#if !defined(NO_FILES)
|
|
|
- /* Step 4: If there is no root directory, don't look for files. */
|
|
|
+ /* Step 5: If there is no root directory, don't look for files. */
|
|
|
/* Note that root == NULL is a regular use case here. This occurs,
|
|
|
* if all requests are handled by callbacks, so the WEBSOCKET_ROOT
|
|
|
* config is not required. */
|
|
@@ -6547,7 +6556,7 @@ interpret_uri(struct mg_connection *conn, /* in: request (must be valid) */
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- /* Step 5: Determine the local file path from the root path and the
|
|
|
+ /* Step 6: Determine the local file path from the root path and the
|
|
|
* request uri. */
|
|
|
/* Using filename_buf_len - 1 because memmove() for PATH_INFO may shift
|
|
|
* part of the path one byte on the right. */
|
|
@@ -6558,7 +6567,7 @@ interpret_uri(struct mg_connection *conn, /* in: request (must be valid) */
|
|
|
goto interpret_cleanup;
|
|
|
}
|
|
|
|
|
|
- /* Step 6: URI rewriting */
|
|
|
+ /* Step 7: URI rewriting */
|
|
|
rewrite = conn->ctx->config[URL_REWRITE_PATTERN];
|
|
|
while ((rewrite = next_option(rewrite, &a, &b)) != NULL) {
|
|
|
if ((match_len = match_prefix(a.ptr, a.len, uri)) > 0) {
|
|
@@ -6578,14 +6587,14 @@ interpret_uri(struct mg_connection *conn, /* in: request (must be valid) */
|
|
|
goto interpret_cleanup;
|
|
|
}
|
|
|
|
|
|
- /* Step 7: Check if the file exists at the server */
|
|
|
+ /* Step 8: Check if the file exists at the server */
|
|
|
/* Local file path and name, corresponding to requested URI
|
|
|
* is now stored in "filename" variable. */
|
|
|
if (mg_stat(conn, filename, filestat)) {
|
|
|
- /* 7.1: File exists. */
|
|
|
+ /* 8.1: File exists. */
|
|
|
*is_found = 1;
|
|
|
|
|
|
- /* 7.2: Check if it is a script type. */
|
|
|
+ /* 8.2: Check if it is a script type. */
|
|
|
if (extention_matches_script(conn, filename)) {
|
|
|
/* The request addresses a CGI resource, Lua script or
|
|
|
* server-side javascript.
|
|
@@ -6601,7 +6610,7 @@ interpret_uri(struct mg_connection *conn, /* in: request (must be valid) */
|
|
|
*is_script_resource = (!*is_put_or_delete_request);
|
|
|
}
|
|
|
|
|
|
- /* 7.3: If the request target is a directory, there could be
|
|
|
+ /* 8.3: If the request target is a directory, there could be
|
|
|
* a substitute file (index.html, index.cgi, ...). */
|
|
|
if (filestat->is_directory) {
|
|
|
/* Use a local copy here, since substitute_index_file will
|
|
@@ -6631,35 +6640,33 @@ interpret_uri(struct mg_connection *conn, /* in: request (must be valid) */
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- /* Step 8: Check for zipped files: */
|
|
|
+ /* Step 9: Check for zipped files: */
|
|
|
/* If we can't find the actual file, look for the file
|
|
|
* with the same name but a .gz extension. If we find it,
|
|
|
* use that and set the gzipped flag in the file struct
|
|
|
* to indicate that the response need to have the content-
|
|
|
* encoding: gzip header.
|
|
|
* We can only do this if the browser declares support. */
|
|
|
- if ((accept_encoding = mg_get_header(conn, "Accept-Encoding")) != NULL) {
|
|
|
- if (strstr(accept_encoding, "gzip") != NULL) {
|
|
|
- mg_snprintf(
|
|
|
- conn, &truncated, gz_path, sizeof(gz_path), "%s.gz", filename);
|
|
|
+ if (conn->accept_gzip) {
|
|
|
+ mg_snprintf(
|
|
|
+ conn, &truncated, gz_path, sizeof(gz_path), "%s.gz", filename);
|
|
|
|
|
|
- if (truncated) {
|
|
|
- goto interpret_cleanup;
|
|
|
- }
|
|
|
+ if (truncated) {
|
|
|
+ goto interpret_cleanup;
|
|
|
+ }
|
|
|
|
|
|
- if (mg_stat(conn, gz_path, filestat)) {
|
|
|
- if (filestat) {
|
|
|
- filestat->is_gzipped = 1;
|
|
|
- *is_found = 1;
|
|
|
- }
|
|
|
- /* Currently gz files can not be scripts. */
|
|
|
- return;
|
|
|
+ if (mg_stat(conn, gz_path, filestat)) {
|
|
|
+ if (filestat) {
|
|
|
+ filestat->is_gzipped = 1;
|
|
|
+ *is_found = 1;
|
|
|
}
|
|
|
+ /* Currently gz files can not be scripts. */
|
|
|
+ return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#if !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE)
|
|
|
- /* Step 9: Script resources may handle sub-resources */
|
|
|
+ /* Step 10: Script resources may handle sub-resources */
|
|
|
/* Support PATH_INFO for CGI scripts. */
|
|
|
tmp_str_len = strlen(filename);
|
|
|
tmp_str = mg_malloc_ctx(tmp_str_len + PATH_MAX + 1, conn->ctx);
|
|
@@ -14067,6 +14074,7 @@ reset_per_request_attributes(struct mg_connection *conn)
|
|
|
conn->throttle = 0;
|
|
|
conn->data_len = 0;
|
|
|
conn->chunk_remainder = 0;
|
|
|
+ conn->accept_gzip = 0;
|
|
|
|
|
|
conn->response_info.content_length = conn->request_info.content_length = -1;
|
|
|
conn->response_info.http_version = conn->request_info.http_version = NULL;
|