Commit a61c3a26 authored by Sergey Lyubka's avatar Sergey Lyubka

Added handle_delete_request(). Refactored convert_uri_to_file_name()

parent 9fd43505
...@@ -1812,7 +1812,8 @@ int mg_get_cookie(const char *cookie_header, const char *var_name, ...@@ -1812,7 +1812,8 @@ int mg_get_cookie(const char *cookie_header, const char *var_name,
return len; return len;
} }
static void convert_uri_to_file_name(struct mg_connection *conn, char *buf, // Return 1 if real file has been found, 0 otherwise
static int convert_uri_to_file_name(struct mg_connection *conn, char *buf,
size_t buf_len, struct file *filep) { size_t buf_len, struct file *filep) {
struct vec a, b; struct vec a, b;
const char *rewrite, *uri = conn->request_info.uri, const char *rewrite, *uri = conn->request_info.uri,
...@@ -1822,12 +1823,15 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf, ...@@ -1822,12 +1823,15 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf,
char gz_path[PATH_MAX]; char gz_path[PATH_MAX];
char const* accept_encoding; char const* accept_encoding;
// No filesystem access
if (root == NULL) {
return 0;
}
// Using buf_len - 1 because memmove() for PATH_INFO may shift part // Using buf_len - 1 because memmove() for PATH_INFO may shift part
// of the path one byte on the right. // of the path one byte on the right.
// If document_root is NULL, leave the file empty. // If document_root is NULL, leave the file empty.
mg_snprintf(conn, buf, buf_len - 1, "%s%s", mg_snprintf(conn, buf, buf_len - 1, "%s%s", root, uri);
root == NULL ? "" : root,
root == NULL ? "" : uri);
rewrite = conn->ctx->config[REWRITE]; rewrite = conn->ctx->config[REWRITE];
while ((rewrite = next_option(rewrite, &a, &b)) != NULL) { while ((rewrite = next_option(rewrite, &a, &b)) != NULL) {
...@@ -1838,7 +1842,7 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf, ...@@ -1838,7 +1842,7 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf,
} }
} }
if (mg_stat(conn, buf, filep)) return; if (mg_stat(conn, buf, filep)) return 1;
// if we can't find the actual file, look for the file // if we can't find the actual file, look for the file
// with the same name but a .gz extension. If we find it, // with the same name but a .gz extension. If we find it,
...@@ -1851,7 +1855,7 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf, ...@@ -1851,7 +1855,7 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf,
snprintf(gz_path, sizeof(gz_path), "%s.gz", buf); snprintf(gz_path, sizeof(gz_path), "%s.gz", buf);
if (mg_stat(conn, gz_path, filep)) { if (mg_stat(conn, gz_path, filep)) {
filep->gzipped = 1; filep->gzipped = 1;
return; return 1;
} }
} }
} }
...@@ -1871,12 +1875,14 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf, ...@@ -1871,12 +1875,14 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf,
conn->path_info = p + 1; conn->path_info = p + 1;
memmove(p + 2, p + 1, strlen(p + 1) + 1); // +1 is for trailing \0 memmove(p + 2, p + 1, strlen(p + 1) + 1); // +1 is for trailing \0
p[1] = '/'; p[1] = '/';
break; return 1;
} else { } else {
*p = '/'; *p = '/';
} }
} }
} }
return 0;
} }
// Check whether full request is buffered. Return: // Check whether full request is buffered. Return:
...@@ -3822,6 +3828,7 @@ static void send_options(struct mg_connection *conn) { ...@@ -3822,6 +3828,7 @@ static void send_options(struct mg_connection *conn) {
conn->status_code = 200; conn->status_code = 200;
mg_printf(conn, "%s", "HTTP/1.1 200 OK\r\n" mg_printf(conn, "%s", "HTTP/1.1 200 OK\r\n"
"Content-Length: 0\r\n"
"Allow: GET, POST, HEAD, CONNECT, PUT, DELETE, " "Allow: GET, POST, HEAD, CONNECT, PUT, DELETE, "
"OPTIONS, PROPFIND, MKCOL\r\n" "OPTIONS, PROPFIND, MKCOL\r\n"
"DAV: 1\r\n\r\n"); "DAV: 1\r\n\r\n");
...@@ -4437,6 +4444,26 @@ static void redirect_to_https_port(struct mg_connection *conn, int ssl_index) { ...@@ -4437,6 +4444,26 @@ static void redirect_to_https_port(struct mg_connection *conn, int ssl_index) {
lsa.sin.sin_port), conn->request_info.uri); lsa.sin.sin_port), conn->request_info.uri);
} }
static void handle_delete_request(struct mg_connection *conn,
const char *path) {
struct file file = STRUCT_FILE_INITIALIZER;
if (!mg_stat(conn, path, &file)) {
send_http_error(conn, 404, "Not Found", "%s", "File not found");
} else if (!file.modification_time) {
send_http_error(conn, 500, http_500_error, "remove(%s): %s", path,
strerror(ERRNO));
} else if (file.is_directory) {
remove_directory(conn, path);
send_http_error(conn, 204, "No Content", "%s", "");
} else if (mg_remove(path) == 0) {
send_http_error(conn, 204, "No Content", "%s", "");
} else {
send_http_error(conn, 423, "Locked", "remove(%s): %s", path,
strerror(ERRNO));
}
}
// This is the heart of the Mongoose's logic. // This is the heart of the Mongoose's logic.
// This function is called when the request is read, parsed and validated, // This function is called when the request is read, parsed and validated,
// and Mongoose must decide what action to take: serve a file, or // and Mongoose must decide what action to take: serve a file, or
...@@ -4453,9 +4480,10 @@ static void handle_request(struct mg_connection *conn) { ...@@ -4453,9 +4480,10 @@ static void handle_request(struct mg_connection *conn) {
uri_len = (int) strlen(ri->uri); uri_len = (int) strlen(ri->uri);
mg_url_decode(ri->uri, uri_len, (char *) ri->uri, uri_len + 1, 0); mg_url_decode(ri->uri, uri_len, (char *) ri->uri, uri_len + 1, 0);
remove_double_dots_and_double_slashes((char *) ri->uri); remove_double_dots_and_double_slashes((char *) ri->uri);
convert_uri_to_file_name(conn, path, sizeof(path), &file);
conn->throttle = set_throttle(conn->ctx->config[THROTTLE], conn->throttle = set_throttle(conn->ctx->config[THROTTLE],
get_remote_ip(conn), ri->uri); get_remote_ip(conn), ri->uri);
path[0] = '\0';
convert_uri_to_file_name(conn, path, sizeof(path), &file);
DEBUG_TRACE(("%s", ri->uri)); DEBUG_TRACE(("%s", ri->uri));
// Perform redirect and auth checks before calling begin_request() handler. // Perform redirect and auth checks before calling begin_request() handler.
...@@ -4485,27 +4513,7 @@ static void handle_request(struct mg_connection *conn) { ...@@ -4485,27 +4513,7 @@ static void handle_request(struct mg_connection *conn) {
} else if (!strcmp(ri->request_method, "MKCOL")) { } else if (!strcmp(ri->request_method, "MKCOL")) {
mkcol(conn, path); mkcol(conn, path);
} else if (!strcmp(ri->request_method, "DELETE")) { } else if (!strcmp(ri->request_method, "DELETE")) {
struct de de; handle_delete_request(conn, path);
memset(&de.file, 0, sizeof(de.file));
if(!mg_stat(conn, path, &de.file)) {
send_http_error(conn, 404, "Not Found", "%s", "File not found");
} else {
if(de.file.modification_time) {
if(de.file.is_directory) {
remove_directory(conn, path);
send_http_error(conn, 204, "No Content", "%s", "");
} else if (mg_remove(path) == 0) {
send_http_error(conn, 204, "No Content", "%s", "");
} else {
send_http_error(conn, 423, "Locked", "remove(%s): %s", path,
strerror(ERRNO));
}
}
else {
send_http_error(conn, 500, http_500_error, "remove(%s): %s", path,
strerror(ERRNO));
}
}
} else if ((file.membuf == NULL && file.modification_time == (time_t) 0) || } else if ((file.membuf == NULL && file.modification_time == (time_t) 0) ||
must_hide_file(conn, path)) { must_hide_file(conn, path)) {
send_http_error(conn, 404, "Not Found", "%s", "File not found"); send_http_error(conn, 404, "Not Found", "%s", "File not found");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment