|
@@ -24,11 +24,18 @@
|
|
#define USE_LUA
|
|
#define USE_LUA
|
|
#include "mongoose.c"
|
|
#include "mongoose.c"
|
|
|
|
|
|
-#define FATAL(str, line) do { \
|
|
|
|
|
|
+static int s_total_tests = 0;
|
|
|
|
+static int s_failed_tests = 0;
|
|
|
|
+
|
|
|
|
+#define FAIL(str, line) do { \
|
|
printf("Fail on line %d: [%s]\n", line, str); \
|
|
printf("Fail on line %d: [%s]\n", line, str); \
|
|
- abort(); \
|
|
|
|
|
|
+ s_failed_tests++; \
|
|
|
|
+} while (0)
|
|
|
|
+
|
|
|
|
+#define ASSERT(expr) do { \
|
|
|
|
+ s_total_tests++; \
|
|
|
|
+ if (!(expr)) FAIL(#expr, __LINE__); \
|
|
} while (0)
|
|
} while (0)
|
|
-#define ASSERT(expr) do { if (!(expr)) FATAL(#expr, __LINE__); } while (0)
|
|
|
|
|
|
|
|
#define HTTP_PORT "56789"
|
|
#define HTTP_PORT "56789"
|
|
#define HTTPS_PORT "56790"
|
|
#define HTTPS_PORT "56790"
|
|
@@ -187,6 +194,7 @@ static char *read_file(const char *path, int *size) {
|
|
static const char *fetch_data = "hello world!\n";
|
|
static const char *fetch_data = "hello world!\n";
|
|
static const char *inmemory_file_data = "hi there";
|
|
static const char *inmemory_file_data = "hi there";
|
|
static const char *upload_filename = "upload_test.txt";
|
|
static const char *upload_filename = "upload_test.txt";
|
|
|
|
+static const char *upload_filename2 = "upload_test2.txt";
|
|
static const char *upload_ok_message = "upload successful";
|
|
static const char *upload_ok_message = "upload successful";
|
|
|
|
|
|
static const char *open_file_cb(const struct mg_connection *conn,
|
|
static const char *open_file_cb(const struct mg_connection *conn,
|
|
@@ -200,16 +208,39 @@ static const char *open_file_cb(const struct mg_connection *conn,
|
|
}
|
|
}
|
|
|
|
|
|
static void upload_cb(struct mg_connection *conn, const char *path) {
|
|
static void upload_cb(struct mg_connection *conn, const char *path) {
|
|
|
|
+ const struct mg_request_info *ri = mg_get_request_info(conn);
|
|
char *p1, *p2;
|
|
char *p1, *p2;
|
|
int len1, len2;
|
|
int len1, len2;
|
|
|
|
|
|
- ASSERT(!strcmp(path, "./upload_test.txt"));
|
|
|
|
- ASSERT((p1 = read_file("mongoose.c", &len1)) != NULL);
|
|
|
|
- ASSERT((p2 = read_file(path, &len2)) != NULL);
|
|
|
|
- ASSERT(len1 == len2);
|
|
|
|
- ASSERT(memcmp(p1, p2, len1) == 0);
|
|
|
|
- free(p1), free(p2);
|
|
|
|
- remove(upload_filename);
|
|
|
|
|
|
+ if (atoi(ri->query_string) == 1) {
|
|
|
|
+ ASSERT(!strcmp(path, "./upload_test.txt"));
|
|
|
|
+ ASSERT((p1 = read_file("mongoose.c", &len1)) != NULL);
|
|
|
|
+ ASSERT((p2 = read_file(path, &len2)) != NULL);
|
|
|
|
+ ASSERT(len1 == len2);
|
|
|
|
+ ASSERT(memcmp(p1, p2, len1) == 0);
|
|
|
|
+ free(p1), free(p2);
|
|
|
|
+ remove(upload_filename);
|
|
|
|
+ } else if (atoi(ri->query_string) == 2) {
|
|
|
|
+ if (!strcmp(path, "./upload_test.txt")) {
|
|
|
|
+ ASSERT((p1 = read_file("mongoose.h", &len1)) != NULL);
|
|
|
|
+ ASSERT((p2 = read_file(path, &len2)) != NULL);
|
|
|
|
+ ASSERT(len1 == len2);
|
|
|
|
+ ASSERT(memcmp(p1, p2, len1) == 0);
|
|
|
|
+ free(p1), free(p2);
|
|
|
|
+ remove(upload_filename);
|
|
|
|
+ } else if (!strcmp(path, "./upload_test2.txt")) {
|
|
|
|
+ ASSERT((p1 = read_file("README.md", &len1)) != NULL);
|
|
|
|
+ ASSERT((p2 = read_file(path, &len2)) != NULL);
|
|
|
|
+ ASSERT(len1 == len2);
|
|
|
|
+ ASSERT(memcmp(p1, p2, len1) == 0);
|
|
|
|
+ free(p1), free(p2);
|
|
|
|
+ remove(upload_filename);
|
|
|
|
+ } else {
|
|
|
|
+ ASSERT(0);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ ASSERT(0);
|
|
|
|
+ }
|
|
|
|
|
|
mg_printf(conn, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\n\r\n%s",
|
|
mg_printf(conn, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\n\r\n%s",
|
|
(int) strlen(upload_ok_message), upload_ok_message);
|
|
(int) strlen(upload_ok_message), upload_ok_message);
|
|
@@ -227,7 +258,8 @@ static int begin_request_handler_cb(struct mg_connection *conn) {
|
|
}
|
|
}
|
|
|
|
|
|
if (!strcmp(ri->uri, "/upload")) {
|
|
if (!strcmp(ri->uri, "/upload")) {
|
|
- ASSERT(mg_upload(conn, ".") == 1);
|
|
|
|
|
|
+ ASSERT(ri->query_string != NULL);
|
|
|
|
+ ASSERT(mg_upload(conn, ".") == atoi(ri->query_string));
|
|
}
|
|
}
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -348,24 +380,27 @@ static void test_mg_upload(void) {
|
|
static const char *boundary = "OOO___MY_BOUNDARY___OOO";
|
|
static const char *boundary = "OOO___MY_BOUNDARY___OOO";
|
|
struct mg_context *ctx;
|
|
struct mg_context *ctx;
|
|
struct mg_connection *conn;
|
|
struct mg_connection *conn;
|
|
- char ebuf[100], buf[20], *file_data, *post_data = NULL;
|
|
|
|
- int file_len, post_data_len;
|
|
|
|
|
|
+ char ebuf[100], buf[20], *file_data, *file2_data, *post_data;
|
|
|
|
+ int file_len, file2_len, post_data_len;
|
|
|
|
|
|
ASSERT((ctx = mg_start(&CALLBACKS, NULL, OPTIONS)) != NULL);
|
|
ASSERT((ctx = mg_start(&CALLBACKS, NULL, OPTIONS)) != NULL);
|
|
|
|
+
|
|
|
|
+ // Upload one file
|
|
ASSERT((file_data = read_file("mongoose.c", &file_len)) != NULL);
|
|
ASSERT((file_data = read_file("mongoose.c", &file_len)) != NULL);
|
|
|
|
+ post_data = NULL;
|
|
post_data_len = alloc_printf(&post_data, 0,
|
|
post_data_len = alloc_printf(&post_data, 0,
|
|
"--%s\r\n"
|
|
"--%s\r\n"
|
|
"Content-Disposition: form-data; "
|
|
"Content-Disposition: form-data; "
|
|
"name=\"file\"; "
|
|
"name=\"file\"; "
|
|
"filename=\"%s\"\r\n\r\n"
|
|
"filename=\"%s\"\r\n\r\n"
|
|
"%.*s\r\n"
|
|
"%.*s\r\n"
|
|
- "--%s\r\n",
|
|
|
|
|
|
+ "--%s--\r\n",
|
|
boundary, upload_filename,
|
|
boundary, upload_filename,
|
|
file_len, file_data, boundary);
|
|
file_len, file_data, boundary);
|
|
ASSERT(post_data_len > 0);
|
|
ASSERT(post_data_len > 0);
|
|
ASSERT((conn = mg_download("localhost", atoi(HTTPS_PORT), 1,
|
|
ASSERT((conn = mg_download("localhost", atoi(HTTPS_PORT), 1,
|
|
ebuf, sizeof(ebuf),
|
|
ebuf, sizeof(ebuf),
|
|
- "POST /upload HTTP/1.1\r\n"
|
|
|
|
|
|
+ "POST /upload?1 HTTP/1.1\r\n"
|
|
"Content-Length: %d\r\n"
|
|
"Content-Length: %d\r\n"
|
|
"Content-Type: multipart/form-data; "
|
|
"Content-Type: multipart/form-data; "
|
|
"boundary=%s\r\n\r\n"
|
|
"boundary=%s\r\n\r\n"
|
|
@@ -375,6 +410,47 @@ static void test_mg_upload(void) {
|
|
ASSERT(mg_read(conn, buf, sizeof(buf)) == (int) strlen(upload_ok_message));
|
|
ASSERT(mg_read(conn, buf, sizeof(buf)) == (int) strlen(upload_ok_message));
|
|
ASSERT(memcmp(buf, upload_ok_message, strlen(upload_ok_message)) == 0);
|
|
ASSERT(memcmp(buf, upload_ok_message, strlen(upload_ok_message)) == 0);
|
|
mg_close_connection(conn);
|
|
mg_close_connection(conn);
|
|
|
|
+
|
|
|
|
+ // Upload two files
|
|
|
|
+ ASSERT((file_data = read_file("mongoose.h", &file_len)) != NULL);
|
|
|
|
+ ASSERT((file2_data = read_file("README.md", &file2_len)) != NULL);
|
|
|
|
+ post_data = NULL;
|
|
|
|
+ post_data_len = alloc_printf(&post_data, 0,
|
|
|
|
+ // First file
|
|
|
|
+ "--%s\r\n"
|
|
|
|
+ "Content-Disposition: form-data; "
|
|
|
|
+ "name=\"file\"; "
|
|
|
|
+ "filename=\"%s\"\r\n\r\n"
|
|
|
|
+ "%.*s\r\n"
|
|
|
|
+
|
|
|
|
+ // Second file
|
|
|
|
+ "--%s\r\n"
|
|
|
|
+ "Content-Disposition: form-data; "
|
|
|
|
+ "name=\"file\"; "
|
|
|
|
+ "filename=\"%s\"\r\n\r\n"
|
|
|
|
+ "%.*s\r\n"
|
|
|
|
+
|
|
|
|
+ // Final boundary
|
|
|
|
+ "--%s--\r\n",
|
|
|
|
+ boundary, upload_filename,
|
|
|
|
+ file_len, file_data,
|
|
|
|
+ boundary, upload_filename2,
|
|
|
|
+ file2_len, file2_data,
|
|
|
|
+ boundary);
|
|
|
|
+ ASSERT(post_data_len > 0);
|
|
|
|
+ ASSERT((conn = mg_download("localhost", atoi(HTTPS_PORT), 1,
|
|
|
|
+ ebuf, sizeof(ebuf),
|
|
|
|
+ "POST /upload?2 HTTP/1.1\r\n"
|
|
|
|
+ "Content-Length: %d\r\n"
|
|
|
|
+ "Content-Type: multipart/form-data; "
|
|
|
|
+ "boundary=%s\r\n\r\n"
|
|
|
|
+ "%.*s", post_data_len, boundary,
|
|
|
|
+ post_data_len, post_data)) != NULL);
|
|
|
|
+ free(file_data), free(file2_data), free(post_data);
|
|
|
|
+ ASSERT(mg_read(conn, buf, sizeof(buf)) == (int) strlen(upload_ok_message));
|
|
|
|
+ ASSERT(memcmp(buf, upload_ok_message, strlen(upload_ok_message)) == 0);
|
|
|
|
+ mg_close_connection(conn);
|
|
|
|
+
|
|
mg_stop(ctx);
|
|
mg_stop(ctx);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -666,6 +742,7 @@ int __cdecl main(void) {
|
|
test_lua();
|
|
test_lua();
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- printf("%s\n", "PASSED");
|
|
|
|
- return 0;
|
|
|
|
|
|
+ printf("TOTAL TESTS: %d, FAILED: %d\n", s_total_tests, s_failed_tests);
|
|
|
|
+
|
|
|
|
+ return s_failed_tests == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
}
|
|
}
|