mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-27 06:51:04 +08:00
Add extra param to http_reply()
This commit is contained in:
parent
29d31ba919
commit
82a378e519
@ -648,11 +648,18 @@ Serve static file.
|
||||
### mg\_http\_reply()
|
||||
|
||||
```c
|
||||
void mg_http_reply(struct mg_connection *c, int code, const char *fmt, ...);
|
||||
void mg_http_reply(struct mg_connection *c, int status_code, const char *headers,
|
||||
const char *body_fmt, ...);
|
||||
```
|
||||
|
||||
Send simple HTTP response using `printf()` semantic.
|
||||
`code` is HTTP response code, `fmt` is format for the HTTP body.
|
||||
Send simple HTTP response using `printf()` semantic. This function formats
|
||||
response body according to a `body_fmt`, and automatically appends a correct
|
||||
`Content-Length` header. Extra headers could be passed via `headers`
|
||||
parameter.
|
||||
|
||||
- `status_code` - an HTTP response code
|
||||
- `headers` - extra headers, default NULL. If not NULL, must end with `\r\n`
|
||||
- `fmt` - a format string for the HTTP body, in a printf semantics
|
||||
|
||||
|
||||
### mg\_http\_header()
|
||||
|
@ -10,7 +10,7 @@
|
||||
// Event handler for an accepted connection
|
||||
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
if (ev == MG_EV_HTTP_MSG) {
|
||||
mg_http_reply(c, 200, "Hello from ESP32!");
|
||||
mg_http_reply(c, 200, "", "Hello from ESP32!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,9 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
if (ev == MG_EV_HTTP_MSG) {
|
||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||
if (mg_http_match_uri(hm, "/api/f1")) {
|
||||
mg_http_reply(c, 200, "{\"result\": %d}\n", 123); // Serve REST response
|
||||
mg_http_reply(c, 200, "", "{\"result\": %d}\n", 123); // Serve REST
|
||||
} else if (mg_http_match_uri(hm, "/api/f2/*")) {
|
||||
mg_http_reply(c, 200, "{\"result\": \"%.*s\"}\n", (int) hm->uri.len,
|
||||
mg_http_reply(c, 200, "", "{\"result\": \"%.*s\"}\n", (int) hm->uri.len,
|
||||
hm->uri.ptr);
|
||||
} else {
|
||||
mg_http_serve_dir(c, ev_data, s_web_directory); // Serve static files
|
||||
|
@ -24,7 +24,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
mg_ws_upgrade(c, hm);
|
||||
} else if (mg_http_match_uri(hm, "/rest")) {
|
||||
// Serve REST response
|
||||
mg_http_reply(c, 200, "{\"result\": %d}\n", 123);
|
||||
mg_http_reply(c, 200, "", "{\"result\": %d}\n", 123);
|
||||
} else {
|
||||
// Serve static files
|
||||
mg_http_serve_dir(c, ev_data, s_web_directory);
|
||||
|
25
mongoose.c
25
mongoose.c
@ -586,17 +586,16 @@ void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len) {
|
||||
mg_send(c, "\r\n", 2);
|
||||
}
|
||||
|
||||
void mg_http_reply(struct mg_connection *c, int code, const char *fmt, ...) {
|
||||
void mg_http_reply(struct mg_connection *c, int code, const char *headers,
|
||||
const char *fmt, ...) {
|
||||
char mem[100], *buf = mem;
|
||||
va_list ap;
|
||||
int len;
|
||||
va_start(ap, fmt);
|
||||
len = mg_vasprintf(&buf, sizeof(mem), fmt, ap);
|
||||
va_end(ap);
|
||||
mg_printf(c,
|
||||
"HTTP/1.1 %d OK\r\nContent-Type: text/plain\r\n"
|
||||
"Content-Length: %d\r\n\r\n",
|
||||
code, len);
|
||||
mg_printf(c, "HTTP/1.1 %d OK\r\n%sContent-Length: %d\r\n\r\n", code,
|
||||
headers == NULL ? "" : headers, len);
|
||||
mg_send(c, buf, len);
|
||||
if (buf != mem) free(buf);
|
||||
}
|
||||
@ -623,7 +622,7 @@ int mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
|
||||
mg_http_get_var(&hm->query, "offset", offset, sizeof(offset));
|
||||
mg_http_get_var(&hm->query, "name", name, sizeof(name));
|
||||
if (name[0] == '\0') {
|
||||
mg_http_reply(c, 400, "%s", "name required");
|
||||
mg_http_reply(c, 400, "", "%s", "name required");
|
||||
return -1;
|
||||
} else {
|
||||
FILE *fp;
|
||||
@ -632,12 +631,12 @@ int mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
|
||||
LOG(LL_DEBUG,
|
||||
("%p %d bytes @ %d [%s]", c->fd, (int) hm->body.len, (int) oft, name));
|
||||
if ((fp = fopen(path, oft == 0 ? "wb" : "a")) == NULL) {
|
||||
mg_http_reply(c, 400, "fopen(%s): %d", name, errno);
|
||||
mg_http_reply(c, 400, "", "fopen(%s): %d", name, errno);
|
||||
return -2;
|
||||
} else {
|
||||
fwrite(hm->body.ptr, 1, hm->body.len, fp);
|
||||
fclose(fp);
|
||||
mg_http_reply(c, 200, "");
|
||||
mg_http_reply(c, 200, "", "");
|
||||
return hm->body.len;
|
||||
}
|
||||
}
|
||||
@ -730,7 +729,7 @@ void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
|
||||
char etag[64];
|
||||
if (fp == NULL || stat(path, &st) != 0 ||
|
||||
mg_http_etag(etag, sizeof(etag), &st) != etag) {
|
||||
mg_http_reply(c, 404, "%s", "Not found\n");
|
||||
mg_http_reply(c, 404, "", "%s", "Not found\n");
|
||||
} else if (inm != NULL && mg_vcasecmp(inm, etag) == 0) {
|
||||
mg_printf(c, "HTTP/1.1 304 Not Modified\r\nContent-Length: 0\r\n\r\n");
|
||||
} else {
|
||||
@ -950,7 +949,7 @@ static void listdir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
MG_VERSION);
|
||||
mg_http_write_chunk(c, "", 0);
|
||||
} else {
|
||||
mg_http_reply(c, 400, "Cannot open dir");
|
||||
mg_http_reply(c, 400, "", "Cannot open dir");
|
||||
LOG(LL_DEBUG, ("%p opendir(%s) -> %d", c->fd, dir, errno));
|
||||
}
|
||||
}
|
||||
@ -963,7 +962,7 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
if (realpath(dir, root) == NULL)
|
||||
LOG(LL_DEBUG, ("realpath(%s): %d", dir, errno));
|
||||
if (!mg_is_dir(root)) {
|
||||
mg_http_reply(c, 400, "Bad web root [%s]\n", root);
|
||||
mg_http_reply(c, 400, "", "Bad web root [%s]\n", root);
|
||||
} else {
|
||||
// NOTE(lsm): Xilinx snprintf does not 0-terminate the detination for
|
||||
// the %.*s specifier, if the length is zero. Make sure hm->uri.len > 0
|
||||
@ -979,7 +978,7 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
is_index = true;
|
||||
}
|
||||
if (strlen(real) < strlen(root) || memcmp(real, root, strlen(root)) != 0) {
|
||||
mg_http_reply(c, 404, "Not found %.*s\n", hm->uri.len, hm->uri.ptr);
|
||||
mg_http_reply(c, 404, "", "Not found %.*s\n", hm->uri.len, hm->uri.ptr);
|
||||
} else {
|
||||
FILE *fp = fopen(real, "r");
|
||||
#if MG_ENABLE_HTTP_DEBUG_ENDPOINT
|
||||
@ -989,7 +988,7 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
#if MG_ENABLE_DIRECTORY_LISTING
|
||||
listdir(c, hm, real);
|
||||
#else
|
||||
mg_http_reply(c, 403, "%s", "Directory listing not supported");
|
||||
mg_http_reply(c, 403, "", "%s", "Directory listing not supported");
|
||||
#endif
|
||||
} else {
|
||||
mg_http_serve_file(c, hm, real, guess_content_type(real));
|
||||
|
@ -676,7 +676,8 @@ void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
|
||||
const char *path);
|
||||
void mg_http_serve_file(struct mg_connection *, struct mg_http_message *,
|
||||
const char *, const char *mime);
|
||||
void mg_http_reply(struct mg_connection *c, int code, const char *fmt, ...);
|
||||
void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
|
||||
const char *body_fmt, ...);
|
||||
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
|
||||
void mg_http_event_handler(struct mg_connection *c, int ev);
|
||||
int mg_http_get_var(const struct mg_str *, const char *name, char *, int);
|
||||
|
25
src/http.c
25
src/http.c
@ -219,17 +219,16 @@ void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len) {
|
||||
mg_send(c, "\r\n", 2);
|
||||
}
|
||||
|
||||
void mg_http_reply(struct mg_connection *c, int code, const char *fmt, ...) {
|
||||
void mg_http_reply(struct mg_connection *c, int code, const char *headers,
|
||||
const char *fmt, ...) {
|
||||
char mem[100], *buf = mem;
|
||||
va_list ap;
|
||||
int len;
|
||||
va_start(ap, fmt);
|
||||
len = mg_vasprintf(&buf, sizeof(mem), fmt, ap);
|
||||
va_end(ap);
|
||||
mg_printf(c,
|
||||
"HTTP/1.1 %d OK\r\nContent-Type: text/plain\r\n"
|
||||
"Content-Length: %d\r\n\r\n",
|
||||
code, len);
|
||||
mg_printf(c, "HTTP/1.1 %d OK\r\n%sContent-Length: %d\r\n\r\n", code,
|
||||
headers == NULL ? "" : headers, len);
|
||||
mg_send(c, buf, len);
|
||||
if (buf != mem) free(buf);
|
||||
}
|
||||
@ -256,7 +255,7 @@ int mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
|
||||
mg_http_get_var(&hm->query, "offset", offset, sizeof(offset));
|
||||
mg_http_get_var(&hm->query, "name", name, sizeof(name));
|
||||
if (name[0] == '\0') {
|
||||
mg_http_reply(c, 400, "%s", "name required");
|
||||
mg_http_reply(c, 400, "", "%s", "name required");
|
||||
return -1;
|
||||
} else {
|
||||
FILE *fp;
|
||||
@ -265,12 +264,12 @@ int mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
|
||||
LOG(LL_DEBUG,
|
||||
("%p %d bytes @ %d [%s]", c->fd, (int) hm->body.len, (int) oft, name));
|
||||
if ((fp = fopen(path, oft == 0 ? "wb" : "a")) == NULL) {
|
||||
mg_http_reply(c, 400, "fopen(%s): %d", name, errno);
|
||||
mg_http_reply(c, 400, "", "fopen(%s): %d", name, errno);
|
||||
return -2;
|
||||
} else {
|
||||
fwrite(hm->body.ptr, 1, hm->body.len, fp);
|
||||
fclose(fp);
|
||||
mg_http_reply(c, 200, "");
|
||||
mg_http_reply(c, 200, "", "");
|
||||
return hm->body.len;
|
||||
}
|
||||
}
|
||||
@ -363,7 +362,7 @@ void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
|
||||
char etag[64];
|
||||
if (fp == NULL || stat(path, &st) != 0 ||
|
||||
mg_http_etag(etag, sizeof(etag), &st) != etag) {
|
||||
mg_http_reply(c, 404, "%s", "Not found\n");
|
||||
mg_http_reply(c, 404, "", "%s", "Not found\n");
|
||||
} else if (inm != NULL && mg_vcasecmp(inm, etag) == 0) {
|
||||
mg_printf(c, "HTTP/1.1 304 Not Modified\r\nContent-Length: 0\r\n\r\n");
|
||||
} else {
|
||||
@ -583,7 +582,7 @@ static void listdir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
MG_VERSION);
|
||||
mg_http_write_chunk(c, "", 0);
|
||||
} else {
|
||||
mg_http_reply(c, 400, "Cannot open dir");
|
||||
mg_http_reply(c, 400, "", "Cannot open dir");
|
||||
LOG(LL_DEBUG, ("%p opendir(%s) -> %d", c->fd, dir, errno));
|
||||
}
|
||||
}
|
||||
@ -596,7 +595,7 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
if (realpath(dir, root) == NULL)
|
||||
LOG(LL_DEBUG, ("realpath(%s): %d", dir, errno));
|
||||
if (!mg_is_dir(root)) {
|
||||
mg_http_reply(c, 400, "Bad web root [%s]\n", root);
|
||||
mg_http_reply(c, 400, "", "Bad web root [%s]\n", root);
|
||||
} else {
|
||||
// NOTE(lsm): Xilinx snprintf does not 0-terminate the detination for
|
||||
// the %.*s specifier, if the length is zero. Make sure hm->uri.len > 0
|
||||
@ -612,7 +611,7 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
is_index = true;
|
||||
}
|
||||
if (strlen(real) < strlen(root) || memcmp(real, root, strlen(root)) != 0) {
|
||||
mg_http_reply(c, 404, "Not found %.*s\n", hm->uri.len, hm->uri.ptr);
|
||||
mg_http_reply(c, 404, "", "Not found %.*s\n", hm->uri.len, hm->uri.ptr);
|
||||
} else {
|
||||
FILE *fp = fopen(real, "r");
|
||||
#if MG_ENABLE_HTTP_DEBUG_ENDPOINT
|
||||
@ -622,7 +621,7 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
#if MG_ENABLE_DIRECTORY_LISTING
|
||||
listdir(c, hm, real);
|
||||
#else
|
||||
mg_http_reply(c, 403, "%s", "Directory listing not supported");
|
||||
mg_http_reply(c, 403, "", "%s", "Directory listing not supported");
|
||||
#endif
|
||||
} else {
|
||||
mg_http_serve_file(c, hm, real, guess_content_type(real));
|
||||
|
@ -32,7 +32,8 @@ void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
|
||||
const char *path);
|
||||
void mg_http_serve_file(struct mg_connection *, struct mg_http_message *,
|
||||
const char *, const char *mime);
|
||||
void mg_http_reply(struct mg_connection *c, int code, const char *fmt, ...);
|
||||
void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
|
||||
const char *body_fmt, ...);
|
||||
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
|
||||
void mg_http_event_handler(struct mg_connection *c, int ev);
|
||||
int mg_http_get_var(const struct mg_str *, const char *name, char *, int);
|
||||
|
@ -323,19 +323,19 @@ static void eh1(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
("[%.*s %.*s] message len %d", (int) hm->method.len, hm->method.ptr,
|
||||
(int) hm->uri.len, hm->uri.ptr, (int) hm->message.len));
|
||||
if (mg_http_match_uri(hm, "/foo/*")) {
|
||||
mg_http_reply(c, 200, "uri: %.*s", hm->uri.len - 5, hm->uri.ptr + 5);
|
||||
mg_http_reply(c, 200, "", "uri: %.*s", hm->uri.len - 5, hm->uri.ptr + 5);
|
||||
} else if (mg_http_match_uri(hm, "/ws")) {
|
||||
mg_ws_upgrade(c, hm);
|
||||
} else if (mg_http_match_uri(hm, "/body")) {
|
||||
mg_http_reply(c, 200, "%.*s", (int) hm->body.len, hm->body.ptr);
|
||||
mg_http_reply(c, 200, "", "%.*s", (int) hm->body.len, hm->body.ptr);
|
||||
} else if (mg_http_match_uri(hm, "/bar")) {
|
||||
mg_http_reply(c, 404, "not found");
|
||||
mg_http_reply(c, 404, "", "not found");
|
||||
} else if (mg_http_match_uri(hm, "/badroot")) {
|
||||
mg_http_serve_dir(c, hm, "/BAAADDD!");
|
||||
} else if (mg_http_match_uri(hm, "/creds")) {
|
||||
char user[100], pass[100];
|
||||
mg_http_creds(hm, user, sizeof(user), pass, sizeof(pass));
|
||||
mg_http_reply(c, 200, "[%s]:[%s]", user, pass);
|
||||
mg_http_reply(c, 200, "", "[%s]:[%s]", user, pass);
|
||||
} else if (mg_http_match_uri(hm, "/upload")) {
|
||||
mg_http_upload(c, hm, ".");
|
||||
} else if (mg_http_match_uri(hm, "/test/")) {
|
||||
@ -470,10 +470,10 @@ static void test_http_server(void) {
|
||||
ASSERT(cmpbody(buf, "kuku") == 0);
|
||||
|
||||
ASSERT(fetch(&mgr, buf, url, "GET /badroot HTTP/1.0\r\n\n") == 400);
|
||||
// LOG(LL_INFO, ("--> [%s]", buf));
|
||||
#if MG_ARCH == MG_ARCH_WIN32
|
||||
ASSERT(cmpbody(buf, "Bad web root [Z:\\BAAADDD!]\n") == 0);
|
||||
#else
|
||||
LOG(LL_INFO, ("--> [%s]", buf));
|
||||
ASSERT(cmpbody(buf, "Bad web root [/BAAADDD!]\n") == 0);
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user