From 189cd8c5f641369c29fd44d385490f0e43940a5d Mon Sep 17 00:00:00 2001 From: Deomid Ryabkov Date: Thu, 27 Apr 2017 14:35:40 +0100 Subject: [PATCH] Add mg_assemble_uri PUBLISHED_FROM=533e134a48e0fca55509c3eb16b0a6b64c1188e8 --- docs/c-api/uri.h/intro.md | 1 + docs/c-api/uri.h/mg_assemble_uri.md | 20 +++++++++ mongoose.c | 70 +++++++++++++++++++++++++++++ mongoose.h | 15 +++++++ 4 files changed, 106 insertions(+) create mode 100644 docs/c-api/uri.h/mg_assemble_uri.md diff --git a/docs/c-api/uri.h/intro.md b/docs/c-api/uri.h/intro.md index 154aea63..f266b27e 100644 --- a/docs/c-api/uri.h/intro.md +++ b/docs/c-api/uri.h/intro.md @@ -3,6 +3,7 @@ title: "URI" symbol_kind: "intro" decl_name: "uri.h" items: + - { name: mg_assemble_uri.md } - { name: mg_parse_uri.md } --- diff --git a/docs/c-api/uri.h/mg_assemble_uri.md b/docs/c-api/uri.h/mg_assemble_uri.md new file mode 100644 index 00000000..20065148 --- /dev/null +++ b/docs/c-api/uri.h/mg_assemble_uri.md @@ -0,0 +1,20 @@ +--- +title: "mg_assemble_uri()" +decl_name: "mg_assemble_uri" +symbol_kind: "func" +signature: | + int mg_assemble_uri(const struct mg_str *scheme, const struct mg_str *user_info, + const struct mg_str *host, unsigned int port, + const struct mg_str *path, const struct mg_str *query, + const struct mg_str *fragment, int normalize_path, + struct mg_str *uri); +--- + +Assemble URI from parts. Any of the inputs can be NULL or zero-length mg_str. + +If normalize_path is true, path is normalized by resolving relative refs. + +Result is a heap-allocated string (uri->p must be free()d after use). + +Returns 0 on success, -1 on error. + diff --git a/mongoose.c b/mongoose.c index 6aabb5c0..568da31c 100644 --- a/mongoose.c +++ b/mongoose.c @@ -5021,6 +5021,76 @@ int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out) { out->len = d - cp; return 1; } + +int mg_assemble_uri(const struct mg_str *scheme, const struct mg_str *user_info, + const struct mg_str *host, unsigned int port, + const struct mg_str *path, const struct mg_str *query, + const struct mg_str *fragment, int normalize_path, + struct mg_str *uri) { + int result = -1; + struct mbuf out; + mbuf_init(&out, 0); + + if (scheme != NULL && scheme->len > 0) { + mbuf_append(&out, scheme->p, scheme->len); + mbuf_append(&out, "://", 3); + } + + if (user_info != NULL && user_info->len > 0) { + mbuf_append(&out, user_info->p, user_info->len); + mbuf_append(&out, "@", 1); + } + + if (host != NULL && host->len > 0) { + mbuf_append(&out, host->p, host->len); + } + + if (port != 0) { + char port_str[20]; + int port_str_len = sprintf(port_str, ":%u", port); + mbuf_append(&out, port_str, port_str_len); + } + + if (path != NULL && path->len > 0) { + if (normalize_path) { + struct mg_str npath = mg_strdup(*path); + if (npath.len != path->len) goto out; + if (!mg_normalize_uri_path(path, &npath)) { + free((void *) npath.p); + goto out; + } + mbuf_append(&out, npath.p, npath.len); + free((void *) npath.p); + } else { + mbuf_append(&out, path->p, path->len); + } + } else if (normalize_path) { + mbuf_append(&out, "/", 1); + } + + if (query != NULL && query->len > 0) { + mbuf_append(&out, "?", 1); + mbuf_append(&out, query->p, query->len); + } + + if (fragment != NULL && fragment->len > 0) { + mbuf_append(&out, "#", 1); + mbuf_append(&out, fragment->p, fragment->len); + } + + result = 0; + +out: + if (result == 0) { + uri->p = out.buf; + uri->len = out.len; + } else { + mbuf_free(&out); + uri->p = NULL; + uri->len = 0; + } + return result; +} #ifdef MG_MODULE_LINES #line 1 "mongoose/src/http.c" #endif diff --git a/mongoose.h b/mongoose.h index 76911e1c..766fc1ff 100644 --- a/mongoose.h +++ b/mongoose.h @@ -3843,6 +3843,21 @@ int mg_parse_uri(const struct mg_str uri, struct mg_str *scheme, unsigned int *port, struct mg_str *path, struct mg_str *query, struct mg_str *fragment); +/* + * Assemble URI from parts. Any of the inputs can be NULL or zero-length mg_str. + * + * If normalize_path is true, path is normalized by resolving relative refs. + * + * Result is a heap-allocated string (uri->p must be free()d after use). + * + * Returns 0 on success, -1 on error. + */ +int mg_assemble_uri(const struct mg_str *scheme, const struct mg_str *user_info, + const struct mg_str *host, unsigned int port, + const struct mg_str *path, const struct mg_str *query, + const struct mg_str *fragment, int normalize_path, + struct mg_str *uri); + int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out); #ifdef __cplusplus