mirror of
https://github.com/cesanta/mongoose.git
synced 2025-08-06 13:37:34 +08:00
Added MG_OPEN_FILE message
This commit is contained in:
parent
2539a473fe
commit
557d1f4c49
6
main.c
6
main.c
@ -224,6 +224,12 @@ static void *mongoose_callback(enum mg_event ev, struct mg_connection *conn) {
|
||||
printf("%s\n", (const char *) mg_get_request_info(conn)->ev_data);
|
||||
}
|
||||
|
||||
if (ev == MG_OPEN_FILE &&
|
||||
!memcmp(mg_get_request_info(conn)->ev_data, "./x", 3)) {
|
||||
mg_get_request_info(conn)->ev_data = (void *) (int) 5;
|
||||
return "hello";
|
||||
}
|
||||
|
||||
// Returning NULL marks request as not handled, signalling mongoose to
|
||||
// proceed with handling it.
|
||||
return NULL;
|
||||
|
587
mongoose.c
587
mongoose.c
File diff suppressed because it is too large
Load Diff
15
mongoose.h
15
mongoose.h
@ -82,6 +82,21 @@ enum mg_event {
|
||||
// SSL_CTX *ssl_context = request_info->ev_data;
|
||||
MG_INIT_SSL,
|
||||
|
||||
// Mongoose tries to open file.
|
||||
// If callback returns non-NULL, Mongoose will not try to open it, but
|
||||
// will use the returned value as a pointer to the file data. This allows
|
||||
// for example to serve files from memory.
|
||||
// ev_data contains file path, including document root path.
|
||||
// Upon return, ev_data should return file size, which should be an int.
|
||||
//
|
||||
// const char *file_name = request_info->ev_data;
|
||||
// if (strcmp(file_name, "foo.txt") == 0) {
|
||||
// request_info->ev_data = (void *) (int) 4;
|
||||
// return "data";
|
||||
// }
|
||||
// return NULL;
|
||||
MG_OPEN_FILE,
|
||||
|
||||
// Sent on HTTP connect, before websocket handshake.
|
||||
// If user callback returns NULL, then mongoose proceeds
|
||||
// with handshake, otherwise it closes the connection.
|
||||
|
@ -7,6 +7,8 @@
|
||||
} while (0)
|
||||
#define ASSERT(expr) do { if (!(expr)) FATAL(#expr, __LINE__); } while (0)
|
||||
|
||||
#define UNUSED_PORT "33796"
|
||||
|
||||
static void test_parse_http_request() {
|
||||
struct mg_request_info ri;
|
||||
char req1[] = "GET / HTTP/1.1\r\n\r\n";
|
||||
@ -126,15 +128,24 @@ static void test_remove_double_dots() {
|
||||
}
|
||||
|
||||
static const char *fetch_data = "hello world!\n";
|
||||
static void *event_handler(enum mg_event event,
|
||||
struct mg_connection *conn) {
|
||||
static const char *inmemory_file_data = "hi there";
|
||||
static void *event_handler(enum mg_event event, struct mg_connection *conn) {
|
||||
const struct mg_request_info *request_info = mg_get_request_info(conn);
|
||||
|
||||
if (event == MG_NEW_REQUEST && !strcmp(request_info->uri, "/data")) {
|
||||
mg_printf(conn, "HTTP/1.1 200 OK\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"Content-Type: text/plain\r\n\r\n"
|
||||
"%s", (int) strlen(fetch_data), fetch_data);
|
||||
return "";
|
||||
} else if (event == MG_OPEN_FILE) {
|
||||
const char *path = request_info->ev_data;
|
||||
printf("%s: [%s]\n", __func__, path);
|
||||
if (strcmp(path, "./blah") == 0) {
|
||||
mg_get_request_info(conn)->ev_data =
|
||||
(void *) (int) strlen(inmemory_file_data);
|
||||
return (void *) inmemory_file_data;
|
||||
}
|
||||
} else if (event == MG_EVENT_LOG) {
|
||||
printf("%s\n", (const char *) mg_get_request_info(conn)->ev_data);
|
||||
}
|
||||
@ -145,33 +156,33 @@ static void *event_handler(enum mg_event event,
|
||||
static void test_mg_fetch(void) {
|
||||
static const char *options[] = {
|
||||
"document_root", ".",
|
||||
"listening_ports", "33796",
|
||||
"listening_ports", UNUSED_PORT,
|
||||
NULL,
|
||||
};
|
||||
char buf[2000], buf2[2000];
|
||||
int length;
|
||||
int n, length;
|
||||
struct mg_context *ctx;
|
||||
struct mg_request_info ri;
|
||||
const char *tmp_file = "temporary_file_name_for_unit_test.txt";
|
||||
struct mgstat st;
|
||||
struct file file;
|
||||
FILE *fp;
|
||||
|
||||
ASSERT((ctx = mg_start(event_handler, NULL, options)) != NULL);
|
||||
|
||||
// Failed fetch, pass invalid URL
|
||||
ASSERT(mg_fetch(ctx, "localhost", tmp_file, buf, sizeof(buf), &ri) == NULL);
|
||||
ASSERT(mg_fetch(ctx, "localhost:33796", tmp_file,
|
||||
ASSERT(mg_fetch(ctx, "localhost:" UNUSED_PORT, tmp_file,
|
||||
buf, sizeof(buf), &ri) == NULL);
|
||||
ASSERT(mg_fetch(ctx, "http://$$$.$$$", tmp_file,
|
||||
buf, sizeof(buf), &ri) == NULL);
|
||||
|
||||
// Failed fetch, pass invalid file name
|
||||
ASSERT(mg_fetch(ctx, "http://localhost:33796/data",
|
||||
ASSERT(mg_fetch(ctx, "http://localhost:" UNUSED_PORT "/data",
|
||||
"/this/file/must/not/exist/ever",
|
||||
buf, sizeof(buf), &ri) == NULL);
|
||||
|
||||
// Successful fetch
|
||||
ASSERT((fp = mg_fetch(ctx, "http://localhost:33796/data",
|
||||
ASSERT((fp = mg_fetch(ctx, "http://localhost:" UNUSED_PORT "/data",
|
||||
tmp_file, buf, sizeof(buf), &ri)) != NULL);
|
||||
ASSERT(ri.num_headers == 2);
|
||||
ASSERT(!strcmp(ri.request_method, "HTTP/1.1"));
|
||||
@ -184,12 +195,31 @@ static void test_mg_fetch(void) {
|
||||
fclose(fp);
|
||||
|
||||
// Fetch big file, mongoose.c
|
||||
ASSERT((fp = mg_fetch(ctx, "http://localhost:33796/mongoose.c",
|
||||
ASSERT((fp = mg_fetch(ctx, "http://localhost:" UNUSED_PORT "/mongoose.c",
|
||||
tmp_file, buf, sizeof(buf), &ri)) != NULL);
|
||||
ASSERT(mg_stat("mongoose.c", &st) == 0);
|
||||
ASSERT(st.size == ftell(fp));
|
||||
ASSERT(mg_stat(fc(ctx), "mongoose.c", &file));
|
||||
ASSERT(file.size == ftell(fp));
|
||||
ASSERT(!strcmp(ri.request_method, "HTTP/1.1"));
|
||||
|
||||
// Fetch nonexistent file, /blah
|
||||
ASSERT((fp = mg_fetch(ctx, "http://localhost:" UNUSED_PORT "/boo",
|
||||
tmp_file, buf, sizeof(buf), &ri)) != NULL);
|
||||
ASSERT(!mg_strcasecmp(ri.uri, "404"));
|
||||
fclose(fp);
|
||||
|
||||
// Fetch existing inmemory file
|
||||
ASSERT((fp = mg_fetch(ctx, "http://localhost:" UNUSED_PORT "/blah",
|
||||
tmp_file, buf, sizeof(buf), &ri)) != NULL);
|
||||
ASSERT(!mg_strcasecmp(ri.uri, "200"));
|
||||
n = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
printf("%s %d %d [%.*s]\n", __func__, n, (int) feof(fp), n, buf2);
|
||||
n = fread(buf2, 1, n, fp);
|
||||
printf("%s %d %d [%.*s]\n", __func__, n, (int) feof(fp), n, buf2);
|
||||
ASSERT((size_t) ftell(fp) == (size_t) strlen(inmemory_file_data));
|
||||
ASSERT(!memcmp(inmemory_file_data, buf2, ftell(fp)));
|
||||
fclose(fp);
|
||||
|
||||
remove(tmp_file);
|
||||
mg_stop(ctx);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user