mirror of
https://github.com/cesanta/mongoose.git
synced 2025-06-07 17:42:30 +08:00
Add mg_url_encode_opt()
CL: Add `mg_url_encode_opt()` - a parametrized version of `mg_url_encode()` PUBLISHED_FROM=17fa57a7a5325b51b6e3aef3855eac4e82c35782
This commit is contained in:
parent
c2fbff6d0e
commit
e89be2e944
@ -6,8 +6,5 @@ signature: |
|
||||
struct mg_str mg_url_encode(const struct mg_str src);
|
||||
---
|
||||
|
||||
URL-escape the specified string.
|
||||
All non-printable characters are escaped, plus `._-$,;~()/`.
|
||||
Input need not be NUL-terminated, but the returned string is.
|
||||
Returned string is heap-allocated and must be free()'d.
|
||||
Same as `mg_url_encode_opt(src, "._-$,;~()/", 0)`.
|
||||
|
||||
|
16
mongoose.c
16
mongoose.c
@ -10444,17 +10444,21 @@ void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass,
|
||||
mbuf_append(buf, header_suffix, strlen(header_suffix));
|
||||
}
|
||||
|
||||
struct mg_str mg_url_encode(const struct mg_str src) {
|
||||
static const char *dont_escape = "._-$,;~()/";
|
||||
static const char *hex = "0123456789abcdef";
|
||||
struct mg_str mg_url_encode_opt(const struct mg_str src,
|
||||
const struct mg_str safe, unsigned int flags) {
|
||||
const char *hex =
|
||||
(flags & MG_URL_ENCODE_F_UPPERCASE_HEX ? "0123456789ABCDEF"
|
||||
: "0123456789abcdef");
|
||||
size_t i = 0;
|
||||
struct mbuf mb;
|
||||
mbuf_init(&mb, src.len);
|
||||
|
||||
for (i = 0; i < src.len; i++) {
|
||||
const unsigned char c = *((const unsigned char *) src.p + i);
|
||||
if (isalnum(c) || strchr(dont_escape, c) != NULL) {
|
||||
if (isalnum(c) || mg_strchr(safe, c) != NULL) {
|
||||
mbuf_append(&mb, &c, 1);
|
||||
} else if (c == ' ' && (flags & MG_URL_ENCODE_F_SPACE_AS_PLUS)) {
|
||||
mbuf_append(&mb, "+", 1);
|
||||
} else {
|
||||
mbuf_append(&mb, "%", 1);
|
||||
mbuf_append(&mb, &hex[c >> 4], 1);
|
||||
@ -10465,6 +10469,10 @@ struct mg_str mg_url_encode(const struct mg_str src) {
|
||||
mbuf_trim(&mb);
|
||||
return mg_mk_str_n(mb.buf, mb.len - 1);
|
||||
}
|
||||
|
||||
struct mg_str mg_url_encode(const struct mg_str src) {
|
||||
return mg_url_encode_opt(src, mg_mk_str("._-$,;~()/"), 0);
|
||||
}
|
||||
#ifdef MG_MODULE_LINES
|
||||
#line 1 "mongoose/src/mg_mqtt.c"
|
||||
#endif
|
||||
|
17
mongoose.h
17
mongoose.h
@ -2314,6 +2314,14 @@ void cs_base64_finish(struct cs_base64_ctx *ctx);
|
||||
|
||||
void cs_base64_encode(const unsigned char *src, int src_len, char *dst);
|
||||
void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len);
|
||||
|
||||
/*
|
||||
* Decodes a base64 string `s` length `len` into `dst`.
|
||||
* `dst` must have enough space to hold the result.
|
||||
* `*dec_len` will contain the resulting length of the string in `dst`
|
||||
* while return value will return number of processed bytes in `src`.
|
||||
* Return value == len indicates successful processing of all the data.
|
||||
*/
|
||||
int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -4501,10 +4509,17 @@ void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass,
|
||||
|
||||
/*
|
||||
* URL-escape the specified string.
|
||||
* All non-printable characters are escaped, plus `._-$,;~()/`.
|
||||
* All characters acept letters, numbers and characters listed in
|
||||
* `safe` are escaped. If `hex_upper`is true, `A-F` are used for hex digits.
|
||||
* Input need not be NUL-terminated, but the returned string is.
|
||||
* Returned string is heap-allocated and must be free()'d.
|
||||
*/
|
||||
#define MG_URL_ENCODE_F_SPACE_AS_PLUS (1 << 0)
|
||||
#define MG_URL_ENCODE_F_UPPERCASE_HEX (1 << 1)
|
||||
struct mg_str mg_url_encode_opt(const struct mg_str src,
|
||||
const struct mg_str safe, unsigned int flags);
|
||||
|
||||
/* Same as `mg_url_encode_opt(src, "._-$,;~()/", 0)`. */
|
||||
struct mg_str mg_url_encode(const struct mg_str src);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -313,17 +313,21 @@ void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass,
|
||||
mbuf_append(buf, header_suffix, strlen(header_suffix));
|
||||
}
|
||||
|
||||
struct mg_str mg_url_encode(const struct mg_str src) {
|
||||
static const char *dont_escape = "._-$,;~()/";
|
||||
static const char *hex = "0123456789abcdef";
|
||||
struct mg_str mg_url_encode_opt(const struct mg_str src,
|
||||
const struct mg_str safe, unsigned int flags) {
|
||||
const char *hex =
|
||||
(flags & MG_URL_ENCODE_F_UPPERCASE_HEX ? "0123456789ABCDEF"
|
||||
: "0123456789abcdef");
|
||||
size_t i = 0;
|
||||
struct mbuf mb;
|
||||
mbuf_init(&mb, src.len);
|
||||
|
||||
for (i = 0; i < src.len; i++) {
|
||||
const unsigned char c = *((const unsigned char *) src.p + i);
|
||||
if (isalnum(c) || strchr(dont_escape, c) != NULL) {
|
||||
if (isalnum(c) || mg_strchr(safe, c) != NULL) {
|
||||
mbuf_append(&mb, &c, 1);
|
||||
} else if (c == ' ' && (flags & MG_URL_ENCODE_F_SPACE_AS_PLUS)) {
|
||||
mbuf_append(&mb, "+", 1);
|
||||
} else {
|
||||
mbuf_append(&mb, "%", 1);
|
||||
mbuf_append(&mb, &hex[c >> 4], 1);
|
||||
@ -334,3 +338,7 @@ struct mg_str mg_url_encode(const struct mg_str src) {
|
||||
mbuf_trim(&mb);
|
||||
return mg_mk_str_n(mb.buf, mb.len - 1);
|
||||
}
|
||||
|
||||
struct mg_str mg_url_encode(const struct mg_str src) {
|
||||
return mg_url_encode_opt(src, mg_mk_str("._-$,;~()/"), 0);
|
||||
}
|
||||
|
@ -196,10 +196,17 @@ void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass,
|
||||
|
||||
/*
|
||||
* URL-escape the specified string.
|
||||
* All non-printable characters are escaped, plus `._-$,;~()/`.
|
||||
* All characters acept letters, numbers and characters listed in
|
||||
* `safe` are escaped. If `hex_upper`is true, `A-F` are used for hex digits.
|
||||
* Input need not be NUL-terminated, but the returned string is.
|
||||
* Returned string is heap-allocated and must be free()'d.
|
||||
*/
|
||||
#define MG_URL_ENCODE_F_SPACE_AS_PLUS (1 << 0)
|
||||
#define MG_URL_ENCODE_F_UPPERCASE_HEX (1 << 1)
|
||||
struct mg_str mg_url_encode_opt(const struct mg_str src,
|
||||
const struct mg_str safe, unsigned int flags);
|
||||
|
||||
/* Same as `mg_url_encode_opt(src, "._-$,;~()/", 0)`. */
|
||||
struct mg_str mg_url_encode(const struct mg_str src);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -928,10 +928,38 @@ static const char *test_mg_uri_to_local_path(void) {
|
||||
static const char *test_mg_url_encode(void) {
|
||||
const struct mg_str encode_me =
|
||||
MG_MK_STR("I'm a.little_tea-pot,here's$my;spout~oink(oink)oink/!");
|
||||
struct mg_str encoded = mg_url_encode(encode_me);
|
||||
ASSERT_MG_STREQ(
|
||||
encoded, "I%27m%20a.little_tea-pot,here%27s$my;spout~oink(oink)oink/%21");
|
||||
free((void *) encoded.p);
|
||||
{
|
||||
struct mg_str encoded = mg_url_encode(encode_me);
|
||||
ASSERT_MG_STREQ(
|
||||
encoded,
|
||||
"I%27m%20a.little_tea-pot,here%27s$my;spout~oink(oink)oink/%21");
|
||||
free((void *) encoded.p);
|
||||
}
|
||||
{
|
||||
struct mg_str encoded = mg_url_encode_opt(encode_me, mg_mk_str(NULL), 0);
|
||||
ASSERT_MG_STREQ(encoded,
|
||||
"I%27m%20a%2elittle%5ftea%2dpot%2chere%27s%24my%3bspout%"
|
||||
"7eoink%28oink%29oink%2f%21");
|
||||
free((void *) encoded.p);
|
||||
}
|
||||
{
|
||||
struct mg_str encoded = mg_url_encode_opt(encode_me, mg_mk_str(" /!"),
|
||||
MG_URL_ENCODE_F_UPPERCASE_HEX);
|
||||
ASSERT_MG_STREQ(encoded,
|
||||
"I%27m "
|
||||
"a%2Elittle%5Ftea%2Dpot%2Chere%27s%24my%3Bspout%7Eoink%"
|
||||
"28oink%29oink/!");
|
||||
free((void *) encoded.p);
|
||||
}
|
||||
{
|
||||
struct mg_str encoded = mg_url_encode_opt(
|
||||
encode_me, mg_mk_str("/!"),
|
||||
MG_URL_ENCODE_F_SPACE_AS_PLUS | MG_URL_ENCODE_F_UPPERCASE_HEX);
|
||||
ASSERT_MG_STREQ(encoded,
|
||||
"I%27m+a%2Elittle%5Ftea%2Dpot%2Chere%27s%24my%3Bspout%"
|
||||
"7Eoink%28oink%29oink/!");
|
||||
free((void *) encoded.p);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user