diff --git a/docs/c-api/http.h/intro.md b/docs/c-api/http.h/intro.md index f070b4b5a1e837dc2b58703b15724e1a75695e4f..df5df05fb4574862db45f06eeb73bbdb058235e7 100644 --- a/docs/c-api/http.h/intro.md +++ b/docs/c-api/http.h/intro.md @@ -15,6 +15,7 @@ items: - { name: struct_http_message.md } - { name: struct_websocket_message.md } - { name: struct_mg_http_multipart_part.md } + - { name: struct_mg_ssi_call_ctx.md } --- diff --git a/docs/c-api/http.h/struct_mg_ssi_call_ctx.md b/docs/c-api/http.h/struct_mg_ssi_call_ctx.md new file mode 100644 index 0000000000000000000000000000000000000000..2b430fd11968430dbe815ef52d2bdc601d18a609 --- /dev/null +++ b/docs/c-api/http.h/struct_mg_ssi_call_ctx.md @@ -0,0 +1,14 @@ +--- +title: "struct mg_ssi_call_ctx" +decl_name: "struct mg_ssi_call_ctx" +symbol_kind: "struct" +signature: | + struct mg_ssi_call_ctx { + struct http_message *req; /* The request being processed. */ + struct mg_str file; /* Filesystem path of the file being processed. */ + struct mg_str arg; /* The argument passed to the tag: <!-- call arg -->. */ + }; +--- + +SSI call context + diff --git a/mongoose.c b/mongoose.c index 111930bfd2101d4828c90dd28865ae46f55c10d9..24ba9916b86542d7a7ccdeda456f73f5adef569c 100644 --- a/mongoose.c +++ b/mongoose.c @@ -5385,8 +5385,9 @@ static void mg_http_send_error(struct mg_connection *nc, int code, nc->flags |= MG_F_SEND_AND_CLOSE; } #ifndef MG_DISABLE_SSI -static void mg_send_ssi_file(struct mg_connection *, const char *, FILE *, int, - const struct mg_serve_http_opts *); +static void mg_send_ssi_file(struct mg_connection *nc, struct http_message *hm, + const char *path, FILE *fp, int include_level, + const struct mg_serve_http_opts *opts); static void mg_send_file_data(struct mg_connection *nc, FILE *fp) { char buf[BUFSIZ]; @@ -5396,8 +5397,8 @@ static void mg_send_file_data(struct mg_connection *nc, FILE *fp) { } } -static void mg_do_ssi_include(struct mg_connection *nc, const char *ssi, - char *tag, int include_level, +static void mg_do_ssi_include(struct mg_connection *nc, struct http_message *hm, + const char *ssi, char *tag, int include_level, const struct mg_serve_http_opts *opts) { char file_name[BUFSIZ], path[MAX_PATH_SIZE], *p; FILE *fp; @@ -5434,7 +5435,7 @@ static void mg_do_ssi_include(struct mg_connection *nc, const char *ssi, mg_set_close_on_exec(fileno(fp)); if (mg_match_prefix(opts->ssi_pattern, strlen(opts->ssi_pattern), path) > 0) { - mg_send_ssi_file(nc, path, fp, include_level + 1, opts); + mg_send_ssi_file(nc, hm, path, fp, include_level + 1, opts); } else { mg_send_file_data(nc, fp); } @@ -5458,16 +5459,12 @@ static void do_ssi_exec(struct mg_connection *nc, char *tag) { } #endif /* !MG_DISABLE_POPEN */ -static void mg_do_ssi_call(struct mg_connection *nc, char *tag) { - mg_call(nc, NULL, MG_EV_SSI_CALL, tag); -} - /* * SSI directive has the following format: * <!--#directive parameter=value parameter=value --> */ -static void mg_send_ssi_file(struct mg_connection *nc, const char *path, - FILE *fp, int include_level, +static void mg_send_ssi_file(struct mg_connection *nc, struct http_message *hm, + const char *path, FILE *fp, int include_level, const struct mg_serve_http_opts *opts) { static const struct mg_str btag = MG_MK_STR("<!--#"); static const struct mg_str d_include = MG_MK_STR("include"); @@ -5497,9 +5494,17 @@ static void mg_send_ssi_file(struct mg_connection *nc, const char *path, /* Handle known SSI directives */ if (memcmp(p, d_include.p, d_include.len) == 0) { - mg_do_ssi_include(nc, path, p + d_include.len + 1, include_level, opts); + mg_do_ssi_include(nc, hm, path, p + d_include.len + 1, include_level, + opts); } else if (memcmp(p, d_call.p, d_call.len) == 0) { - mg_do_ssi_call(nc, p + d_call.len + 1); + struct mg_ssi_call_ctx cctx; + memset(&cctx, 0, sizeof(cctx)); + cctx.req = hm; + cctx.file = mg_mk_str(path); + cctx.arg = mg_mk_str(p + d_call.len + 1); + mg_call(nc, NULL, MG_EV_SSI_CALL, + (void *) cctx.arg.p); /* NUL added above */ + mg_call(nc, NULL, MG_EV_SSI_CALL_CTX, &cctx); #ifndef MG_DISABLE_POPEN } else if (memcmp(p, d_exec.p, d_exec.len) == 0) { do_ssi_exec(nc, p + d_exec.len + 1); @@ -5539,7 +5544,8 @@ static void mg_send_ssi_file(struct mg_connection *nc, const char *path, } } -static void mg_handle_ssi_request(struct mg_connection *nc, const char *path, +static void mg_handle_ssi_request(struct mg_connection *nc, + struct http_message *hm, const char *path, const struct mg_serve_http_opts *opts) { FILE *fp; struct mg_str mime_type; @@ -5556,15 +5562,17 @@ static void mg_handle_ssi_request(struct mg_connection *nc, const char *path, "Content-Type: %.*s\r\n" "Connection: close\r\n\r\n", (int) mime_type.len, mime_type.p); - mg_send_ssi_file(nc, path, fp, 0, opts); + mg_send_ssi_file(nc, hm, path, fp, 0, opts); fclose(fp); nc->flags |= MG_F_SEND_AND_CLOSE; } } #else -static void mg_handle_ssi_request(struct mg_connection *nc, const char *path, +static void mg_handle_ssi_request(struct mg_connection *nc, + struct http_message *hm, const char *path, const struct mg_serve_http_opts *opts) { (void) path; + (void) hm; (void) opts; mg_http_send_error(nc, 500, "SSI disabled"); } @@ -5696,7 +5704,7 @@ static void mg_http_serve_file2(struct mg_connection *nc, const char *path, struct http_message *hm, struct mg_serve_http_opts *opts) { if (mg_match_prefix(opts->ssi_pattern, strlen(opts->ssi_pattern), path) > 0) { - mg_handle_ssi_request(nc, path, opts); + mg_handle_ssi_request(nc, hm, path, opts); return; } mg_http_serve_file(nc, hm, path, mg_get_mime_type(path, "text/plain", opts), diff --git a/mongoose.h b/mongoose.h index c4a8ce7593106744db48b2e13fa29991b615584d..f24aa6ecddbdb414f0828f703b96ab90b722dbb8 100644 --- a/mongoose.h +++ b/mongoose.h @@ -2170,11 +2170,19 @@ struct mg_http_multipart_part { void *user_data; }; +/* SSI call context */ +struct mg_ssi_call_ctx { + struct http_message *req; /* The request being processed. */ + struct mg_str file; /* Filesystem path of the file being processed. */ + struct mg_str arg; /* The argument passed to the tag: <!-- call arg -->. */ +}; + /* HTTP and websocket events. void *ev_data is described in a comment. */ #define MG_EV_HTTP_REQUEST 100 /* struct http_message * */ #define MG_EV_HTTP_REPLY 101 /* struct http_message * */ #define MG_EV_HTTP_CHUNK 102 /* struct http_message * */ #define MG_EV_SSI_CALL 105 /* char * */ +#define MG_EV_SSI_CALL_CTX 106 /* struct mg_ssi_call_ctx * */ #ifndef MG_DISABLE_HTTP_WEBSOCKET #define MG_EV_WEBSOCKET_HANDSHAKE_REQUEST 111 /* NULL */