diff --git a/mongoose.c b/mongoose.c
index 9f6d5631..bb43e9df 100644
--- a/mongoose.c
+++ b/mongoose.c
@@ -956,34 +956,11 @@ struct dirent *readdir(DIR *d) {
}
#endif
-static bool mg_is_safe(int c) {
- return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') || strchr("._-$,;~()/", c) != NULL;
-}
-
-static int mg_url_encode(const char *s, char *buf, size_t len) {
- int i, n = 0;
- for (i = 0; s[i] != '\0'; i++) {
- int c = *((const unsigned char *) (s + i));
- if ((size_t) n + 4 >= len) return 0;
- if (mg_is_safe(c)) {
- buf[n++] = s[i];
- } else {
- buf[n++] = '%';
- mg_hex(&s[i], 1, &buf[n]);
- n += 2;
- }
- }
- return n;
-}
-
static void printdirentry(struct mg_connection *c, const char *name,
mg_stat_t *stp) {
char size[64], mod[64], path[MG_PATH_MAX];
- int is_dir = S_ISDIR(stp->st_mode);
+ int is_dir = S_ISDIR(stp->st_mode), n = 0;
const char *slash = is_dir ? "/" : "";
- // const char *es = hm->uri.ptr[hm->uri.len - 1] != '/' ? "/" : "";
- int n = 0;
if (is_dir) {
snprintf(size, sizeof(size), "%s", "[DIR]");
@@ -999,7 +976,7 @@ static void printdirentry(struct mg_connection *c, const char *name,
}
}
strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", localtime(&stp->st_mtime));
- n = mg_url_encode(name, path, sizeof(path));
+ n = mg_url_encode(name, strlen(name), path, sizeof(path));
mg_printf(c,
"
| %s%s | "
"%s | %s |
\n",
@@ -1158,6 +1135,27 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
}
#endif
+static bool mg_is_url_safe(int c) {
+ return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') || c == '.' || c == '_' || c == '-' || c == '~';
+}
+
+int mg_url_encode(const char *s, size_t sl, char *buf, size_t len) {
+ size_t i, n = 0;
+ for (i = 0; i < sl; i++) {
+ int c = *(unsigned char *) &s[i];
+ if (n + 4 >= len) return 0;
+ if (mg_is_url_safe(c)) {
+ buf[n++] = s[i];
+ } else {
+ buf[n++] = '%';
+ mg_hex(&s[i], 1, &buf[n]);
+ n += 2;
+ }
+ }
+ return n;
+}
+
void mg_http_creds(struct mg_http_message *hm, char *user, int userlen,
char *pass, int passlen) {
struct mg_str *v = mg_http_get_header(hm, "Authorization");
@@ -1295,11 +1293,7 @@ int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) {
}
int mg_iobuf_init(struct mg_iobuf *io, size_t size) {
- int ok = 1;
- io->buf = NULL;
- io->len = io->size = 0;
- if (size > 0) ok = mg_iobuf_resize(io, size);
- return ok;
+ return mg_iobuf_resize(io, size);
}
size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len,
@@ -1321,8 +1315,7 @@ size_t mg_iobuf_delete(struct mg_iobuf *io, size_t len) {
}
void mg_iobuf_free(struct mg_iobuf *io) {
- free(io->buf);
- mg_iobuf_init(io, 0);
+ mg_iobuf_resize(io, 0);
}
#ifdef MG_ENABLE_LINES
@@ -2675,7 +2668,7 @@ static int ll_read(struct mg_connection *c, void *buf, int len, int *fail) {
MG_SOCK_ERRNO, *fail));
if (n > 0 && c->is_hexdumping) {
char *s = mg_hexdump(buf, n);
- // LOG(LL_INFO, ("\n-- %lu %s %s %d\n%s--", c->id, c->label, "<-", n, s));
+ LOG(LL_INFO, ("\n-- %lu %s %s %d\n%s--", c->id, c->label, "<-", n, s));
free(s);
}
return n;
@@ -2691,7 +2684,7 @@ static int ll_write(struct mg_connection *c, const void *buf, int len,
MG_SOCK_ERRNO));
if (n > 0 && c->is_hexdumping) {
char *s = mg_hexdump(buf, len);
- // LOG(LL_INFO, ("\n-- %lu %s %s %d\n%s--", c->id, c->label, "->", len, s));
+ LOG(LL_INFO, ("\n-- %lu %s %s %d\n%s--", c->id, c->label, "->", len, s));
free(s);
}
return n;
diff --git a/mongoose.h b/mongoose.h
index d07c7c01..28fe71b0 100644
--- a/mongoose.h
+++ b/mongoose.h
@@ -568,17 +568,6 @@ void mg_hmac_sha1(const unsigned char *key, size_t key_len,
struct mg_connection;
typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
void *ev_data, void *fn_data);
-#if 0
-struct mg_fn {
- struct mg_fn *next;
- mg_event_handler_t fn;
- void *fn_data;
-};
-
-void mg_fn_add(struct mg_connection *c, mg_event_handler_t fn, void *fn_data);
-void mg_fn_del(struct mg_connection *c, mg_event_handler_t fn);
-#endif
-
void mg_call(struct mg_connection *c, int ev, void *ev_data);
void mg_error(struct mg_connection *c, const char *fmt, ...);
@@ -722,6 +711,7 @@ 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);
int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
+int mg_url_encode(const char *s, size_t n, char *buf, size_t len);
void mg_http_creds(struct mg_http_message *, char *user, int, char *pass, int);
bool mg_http_match_uri(const struct mg_http_message *, const char *glob);
int mg_http_upload(struct mg_connection *, struct mg_http_message *hm,
diff --git a/src/event.h b/src/event.h
index 3879224c..0c788255 100644
--- a/src/event.h
+++ b/src/event.h
@@ -3,17 +3,6 @@
struct mg_connection;
typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
void *ev_data, void *fn_data);
-#if 0
-struct mg_fn {
- struct mg_fn *next;
- mg_event_handler_t fn;
- void *fn_data;
-};
-
-void mg_fn_add(struct mg_connection *c, mg_event_handler_t fn, void *fn_data);
-void mg_fn_del(struct mg_connection *c, mg_event_handler_t fn);
-#endif
-
void mg_call(struct mg_connection *c, int ev, void *ev_data);
void mg_error(struct mg_connection *c, const char *fmt, ...);
diff --git a/src/http.c b/src/http.c
index f05555f2..e61a1ece 100644
--- a/src/http.c
+++ b/src/http.c
@@ -536,34 +536,11 @@ struct dirent *readdir(DIR *d) {
}
#endif
-static bool mg_is_safe(int c) {
- return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') || strchr("._-$,;~()/", c) != NULL;
-}
-
-static int mg_url_encode(const char *s, char *buf, size_t len) {
- int i, n = 0;
- for (i = 0; s[i] != '\0'; i++) {
- int c = *((const unsigned char *) (s + i));
- if ((size_t) n + 4 >= len) return 0;
- if (mg_is_safe(c)) {
- buf[n++] = s[i];
- } else {
- buf[n++] = '%';
- mg_hex(&s[i], 1, &buf[n]);
- n += 2;
- }
- }
- return n;
-}
-
static void printdirentry(struct mg_connection *c, const char *name,
mg_stat_t *stp) {
char size[64], mod[64], path[MG_PATH_MAX];
- int is_dir = S_ISDIR(stp->st_mode);
+ int is_dir = S_ISDIR(stp->st_mode), n = 0;
const char *slash = is_dir ? "/" : "";
- // const char *es = hm->uri.ptr[hm->uri.len - 1] != '/' ? "/" : "";
- int n = 0;
if (is_dir) {
snprintf(size, sizeof(size), "%s", "[DIR]");
@@ -579,7 +556,7 @@ static void printdirentry(struct mg_connection *c, const char *name,
}
}
strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", localtime(&stp->st_mtime));
- n = mg_url_encode(name, path, sizeof(path));
+ n = mg_url_encode(name, strlen(name), path, sizeof(path));
mg_printf(c,
" | %s%s | "
"%s | %s |
\n",
@@ -738,6 +715,27 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
}
#endif
+static bool mg_is_url_safe(int c) {
+ return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') || c == '.' || c == '_' || c == '-' || c == '~';
+}
+
+int mg_url_encode(const char *s, size_t sl, char *buf, size_t len) {
+ size_t i, n = 0;
+ for (i = 0; i < sl; i++) {
+ int c = *(unsigned char *) &s[i];
+ if (n + 4 >= len) return 0;
+ if (mg_is_url_safe(c)) {
+ buf[n++] = s[i];
+ } else {
+ buf[n++] = '%';
+ mg_hex(&s[i], 1, &buf[n]);
+ n += 2;
+ }
+ }
+ return n;
+}
+
void mg_http_creds(struct mg_http_message *hm, char *user, int userlen,
char *pass, int passlen) {
struct mg_str *v = mg_http_get_header(hm, "Authorization");
diff --git a/src/http.h b/src/http.h
index 3079db2b..e54c8bd7 100644
--- a/src/http.h
+++ b/src/http.h
@@ -44,6 +44,7 @@ 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);
int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
+int mg_url_encode(const char *s, size_t n, char *buf, size_t len);
void mg_http_creds(struct mg_http_message *, char *user, int, char *pass, int);
bool mg_http_match_uri(const struct mg_http_message *, const char *glob);
int mg_http_upload(struct mg_connection *, struct mg_http_message *hm,
diff --git a/src/sock.c b/src/sock.c
index f3e75055..da76a964 100644
--- a/src/sock.c
+++ b/src/sock.c
@@ -135,7 +135,7 @@ static int ll_read(struct mg_connection *c, void *buf, int len, int *fail) {
MG_SOCK_ERRNO, *fail));
if (n > 0 && c->is_hexdumping) {
char *s = mg_hexdump(buf, n);
- // LOG(LL_INFO, ("\n-- %lu %s %s %d\n%s--", c->id, c->label, "<-", n, s));
+ LOG(LL_INFO, ("\n-- %lu %s %s %d\n%s--", c->id, c->label, "<-", n, s));
free(s);
}
return n;
@@ -151,7 +151,7 @@ static int ll_write(struct mg_connection *c, const void *buf, int len,
MG_SOCK_ERRNO));
if (n > 0 && c->is_hexdumping) {
char *s = mg_hexdump(buf, len);
- // LOG(LL_INFO, ("\n-- %lu %s %s %d\n%s--", c->id, c->label, "->", len, s));
+ LOG(LL_INFO, ("\n-- %lu %s %s %d\n%s--", c->id, c->label, "->", len, s));
free(s);
}
return n;
diff --git a/test/unit_test.c b/test/unit_test.c
index 8d8568d1..871a71d9 100644
--- a/test/unit_test.c
+++ b/test/unit_test.c
@@ -1124,6 +1124,31 @@ static void test_util(void) {
ASSERT(strcmp(mg_hex("abc", 3, buf), "616263") == 0);
ASSERT(mg_url_decode("a=%", 3, buf, sizeof(buf), 0) < 0);
ASSERT(mg_url_decode("&&&a=%", 6, buf, sizeof(buf), 0) < 0);
+
+ {
+ char buf[100];
+ int n;
+ ASSERT((n = mg_url_encode("", 0, buf, sizeof(buf))) == 0);
+ ASSERT((n = mg_url_encode("a", 1, buf, 0)) == 0);
+ ASSERT((n = mg_url_encode("a", 1, buf, sizeof(buf))) == 1);
+ ASSERT(strncmp(buf, "a", n) == 0);
+ ASSERT((n = mg_url_encode("._-~", 4, buf, sizeof(buf))) == 4);
+ ASSERT(strncmp(buf, "._-~", n) == 0);
+ ASSERT((n = mg_url_encode("a@%>", 4, buf, sizeof(buf))) == 10);
+ ASSERT(strncmp(buf, "a%40%25%3e", n) == 0);
+ ASSERT((n = mg_url_encode("a@b.c", 5, buf, sizeof(buf))) == 7);
+ ASSERT(strncmp(buf, "a%40b.c", n) == 0);
+ }
+
+ {
+ char buf[100], *s = buf;
+ mg_asprintf(&s, sizeof(buf), "%s", "%3d", 123);
+ ASSERT(s == buf);
+ ASSERT(strcmp(buf, "%3d") == 0);
+ mg_asprintf(&s, sizeof(buf), "%.*s", 7, "a%40b.c");
+ ASSERT(s == buf);
+ ASSERT(strcmp(buf, "a%40b.c") == 0);
+ }
}
int main(void) {