From 7c4cda622f8f11039480cfadffd63226ca9a8a85 Mon Sep 17 00:00:00 2001 From: Sergey Lyubka Date: Thu, 26 Nov 2015 21:37:20 +0000 Subject: [PATCH] Implement port based redirect PUBLISHED_FROM=798a8bc38cb385027d3caae9b954002c1a10d39c --- examples/restful_server/restful_server.c | 2 +- mongoose.c | 38 ++++++++++++++++++++++++ mongoose.h | 7 +++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/examples/restful_server/restful_server.c b/examples/restful_server/restful_server.c index 85e52e93..27ada98b 100644 --- a/examples/restful_server/restful_server.c +++ b/examples/restful_server/restful_server.c @@ -74,7 +74,7 @@ int main(int argc, char *argv[]) { #endif } else if (strcmp(argv[i], "-P") == 0 && i + 1 < argc) { s_http_server_opts.global_auth_file = argv[++i]; - } else if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) { + } else if (strcmp(argv[i], "-A") == 0 && i + 1 < argc) { s_http_server_opts.per_directory_auth_file = argv[++i]; } else if (strcmp(argv[i], "-r") == 0 && i + 1 < argc) { s_http_server_opts.url_rewrites = argv[++i]; diff --git a/mongoose.c b/mongoose.c index 73a1f179..c24e740e 100644 --- a/mongoose.c +++ b/mongoose.c @@ -4488,6 +4488,12 @@ void mg_send_response_line(struct mg_connection *nc, int status_code, case 206: status_message = "Partial Content"; break; + case 301: + status_message = "Moved"; + break; + case 302: + status_message = "Found"; + break; case 416: status_message = "Requested range not satisfiable"; break; @@ -5502,6 +5508,34 @@ MG_INTERNAL int find_index_file(char *path, size_t path_len, const char *list, return found; } +static int send_port_based_redirect(struct mg_connection *c, + struct http_message *hm, + const struct mg_serve_http_opts *opts) { + const char *rewrites = opts->url_rewrites; + struct mg_str a, b; + char local_port[20] = {'%'}; + +#ifndef MG_ESP8266 + mg_sock_to_str(c->sock, local_port + 1, sizeof(local_port) - 1, + MG_SOCK_STRINGIFY_PORT); +#else + /* TODO(lsm): remove when mg_sock_to_str() is implemented in LWIP codepath */ + snprintf(local_port, sizeof(local_port), "%s", "%0"); +#endif + + while ((rewrites = mg_next_comma_list_entry(rewrites, &a, &b)) != NULL) { + if (mg_vcmp(&a, local_port) == 0) { + mg_send_response_line(c, 301, NULL); + mg_printf(c, "Content-Length: 0\r\nLocation: %.*s%.*s\r\n\r\n", + (int) b.len, b.p, (int) (hm->proto.p - hm->uri.p - 1), + hm->uri.p); + return 1; + } + } + + return 0; +} + static void uri_to_path(struct http_message *hm, char *buf, size_t buf_len, const struct mg_serve_http_opts *opts) { char uri[MG_MAX_PATH]; @@ -6132,6 +6166,10 @@ void mg_serve_http(struct mg_connection *nc, struct http_message *hm, char path[MG_MAX_PATH]; struct mg_str *hdr; + if (send_port_based_redirect(nc, hm, &opts)) { + return; + } + if (opts.document_root == NULL) { opts.document_root = "."; } diff --git a/mongoose.h b/mongoose.h index f8dd00fc..a1674203 100644 --- a/mongoose.h +++ b/mongoose.h @@ -1772,6 +1772,13 @@ struct mg_serve_http_opts { * If uri_pattern starts with `@` symbol, then Mongoose compares it with the * HOST header of the request. If they are equal, Mongoose sets document root * to `file_or_directory_path`, implementing virtual hosts support. + * Example: `@foo.com=/document/root/for/foo.com` + * + * If `uri_pattern` starts with `%` symbol, then Mongoose compares it with + * the listening port. If they match, then Mongoose issues a 301 redirect. + * For example, to redirect all HTTP requests to the + * HTTPS port, do `%80=https://my.site.com`. Note that the request URI is + * automatically appended to the redirect location. */ const char *url_rewrites;