view Resources/Patches/mongoose-3.8-patch.diff @ 3119:8f2bda0719f4

Fix issue #125 (Mongoose: /instances/{id} returns 500 on invalid HTTP Method)
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 14 Jan 2019 13:11:43 +0100
parents a119f9ae3640
children 4a8e8a96b233
line wrap: on
line source

--- mongoose.c.orig	2019-01-14 13:06:27.147098524 +0100
+++ mongoose.c	2019-01-14 12:44:35.331361929 +0100
@@ -50,6 +50,14 @@
 #define PATH_MAX FILENAME_MAX
 #endif // __SYMBIAN32__
 
+#if __gnu_hurd__ == 1
+/**
+ * There is no limit on the length on a path under GNU Hurd, so we set
+ * it to an arbitrary constant.
+ **/
+#define PATH_MAX 4096
+#endif
+
 #ifndef _WIN32_WCE // Some ANSI #includes are not available on Windows CE
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -108,8 +116,9 @@
 #define strtoll(x, y, z) _atoi64(x)
 #else
 #define __func__  __FUNCTION__
-#define strtoull(x, y, z) _strtoui64(x, y, z)
-#define strtoll(x, y, z) _strtoi64(x, y, z)
+#include <stdlib.h>
+//#define strtoull(x, y, z) _strtoui64(x, y, z)
+//#define strtoll(x, y, z) _strtoi64(x, y, z)
 #endif // _MSC_VER
 
 #define ERRNO   GetLastError()
@@ -2997,19 +3006,19 @@
   }
 }
 
-static int is_valid_http_method(const char *method) {
-  return !strcmp(method, "GET") || !strcmp(method, "POST") ||
+static int is_valid_http_method(const char *method, int *isValidHttpMethod) {
+  *isValidHttpMethod = !strcmp(method, "GET") || !strcmp(method, "POST") ||
     !strcmp(method, "HEAD") || !strcmp(method, "CONNECT") ||
     !strcmp(method, "PUT") || !strcmp(method, "DELETE") ||
     !strcmp(method, "OPTIONS") || !strcmp(method, "PROPFIND")
-    || !strcmp(method, "MKCOL")
-          ;
+    || !strcmp(method, "MKCOL");
+  return *isValidHttpMethod;
 }
 
 // Parse HTTP request, fill in mg_request_info structure.
 // This function modifies the buffer by NUL-terminating
 // HTTP request components, header names and header values.
-static int parse_http_message(char *buf, int len, struct mg_request_info *ri) {
+static int parse_http_message(char *buf, int len, struct mg_request_info *ri, int *isValidHttpMethod) {
   int is_request, request_length = get_request_len(buf, len);
   if (request_length > 0) {
     // Reset attributes. DO NOT TOUCH is_ssl, remote_ip, remote_port
@@ -3025,7 +3034,7 @@
     ri->request_method = skip(&buf, " ");
     ri->uri = skip(&buf, " ");
     ri->http_version = skip(&buf, "\r\n");
-    if (((is_request = is_valid_http_method(ri->request_method)) &&
+    if (((is_request = is_valid_http_method(ri->request_method, isValidHttpMethod)) &&
          memcmp(ri->http_version, "HTTP/", 5) != 0) ||
         (!is_request && memcmp(ri->request_method, "HTTP/", 5)) != 0) {
       request_length = -1;
@@ -4930,7 +4939,7 @@
   return uri[0] == '/' || (uri[0] == '*' && uri[1] == '\0');
 }
 
-static int getreq(struct mg_connection *conn, char *ebuf, size_t ebuf_len) {
+static int getreq(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *isValidHttpMethod) {
   const char *cl;
 
   ebuf[0] = '\0';
@@ -4944,7 +4953,7 @@
   } else if (conn->request_len <= 0) {
     snprintf(ebuf, ebuf_len, "%s", "Client closed connection");
   } else if (parse_http_message(conn->buf, conn->buf_size,
-                                &conn->request_info) <= 0) {
+                                &conn->request_info, isValidHttpMethod) <= 0) {
     snprintf(ebuf, ebuf_len, "Bad request: [%.*s]", conn->data_len, conn->buf);
   } else {
     // Request is valid
@@ -4973,7 +4982,8 @@
   } else if (mg_vprintf(conn, fmt, ap) <= 0) {
     snprintf(ebuf, ebuf_len, "%s", "Error sending request");
   } else {
-    getreq(conn, ebuf, ebuf_len);
+    int isValidHttpMethod = 1; /* unused in this case */
+    getreq(conn, ebuf, ebuf_len, &isValidHttpMethod);
   }
   if (ebuf[0] != '\0' && conn != NULL) {
     mg_close_connection(conn);
@@ -4995,8 +5005,13 @@
   // to crule42.
   conn->data_len = 0;
   do {
-    if (!getreq(conn, ebuf, sizeof(ebuf))) {
+    int isValidHttpMethod = 1;
+    if (!getreq(conn, ebuf, sizeof(ebuf), &isValidHttpMethod)) {
+      if (isValidHttpMethod) {
       send_http_error(conn, 500, "Server Error", "%s", ebuf);
+      } else {
+        send_http_error(conn, 400, "Bad Request", "%s", ebuf);
+      }
       conn->must_close = 1;
     } else if (!is_valid_uri(conn->request_info.uri)) {
       snprintf(ebuf, sizeof(ebuf), "Invalid URI: [%s]", ri->uri);