|
@@ -29,6 +29,11 @@
|
|
#define __STDC_LIMIT_MACROS // C++ wants that for INT64_MAX
|
|
#define __STDC_LIMIT_MACROS // C++ wants that for INT64_MAX
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#if defined (_MSC_VER)
|
|
|
|
+#pragma warning (disable : 4127) // conditional expression is constant: introduced by FD_SET(..)
|
|
|
|
+#pragma warning (disable : 4204) // non-constant aggregate initializer: issued due to missing C99 support
|
|
|
|
+#endif
|
|
|
|
+
|
|
// Disable WIN32_LEAN_AND_MEAN.
|
|
// Disable WIN32_LEAN_AND_MEAN.
|
|
// This makes windows.h always include winsock2.h
|
|
// This makes windows.h always include winsock2.h
|
|
#ifdef WIN32_LEAN_AND_MEAN
|
|
#ifdef WIN32_LEAN_AND_MEAN
|
|
@@ -146,6 +151,8 @@ static int pthread_mutex_lock(pthread_mutex_t *);
|
|
static int pthread_mutex_unlock(pthread_mutex_t *);
|
|
static int pthread_mutex_unlock(pthread_mutex_t *);
|
|
|
|
|
|
static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len);
|
|
static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len);
|
|
|
|
+
|
|
|
|
+struct file;
|
|
static char *mg_fgets(char *buf, size_t size, struct file *filep, char **p);
|
|
static char *mg_fgets(char *buf, size_t size, struct file *filep, char **p);
|
|
|
|
|
|
#if defined(HAVE_STDINT)
|
|
#if defined(HAVE_STDINT)
|
|
@@ -1639,13 +1646,7 @@ static int url_decode(const char *src, int src_len, char *dst,
|
|
return i >= src_len ? j : -1;
|
|
return i >= src_len ? j : -1;
|
|
}
|
|
}
|
|
|
|
|
|
-// Scan given buffer and fetch the value of the given variable.
|
|
|
|
-// It can be specified in query string, or in the POST data.
|
|
|
|
-// Return -1 if the variable not found, or length of the URL-decoded value
|
|
|
|
-// stored in dst. The dst buffer is guaranteed to be NUL-terminated if it
|
|
|
|
-// is not NULL or zero-length. If dst is NULL or zero-length, then
|
|
|
|
-// -2 is returned.
|
|
|
|
-int mg_get_var(const char *buf, size_t buf_len, const char *name,
|
|
|
|
|
|
+int mg_get_var(const char *data, size_t data_len, const char *name,
|
|
char *dst, size_t dst_len) {
|
|
char *dst, size_t dst_len) {
|
|
const char *p, *e, *s;
|
|
const char *p, *e, *s;
|
|
size_t name_len;
|
|
size_t name_len;
|
|
@@ -1653,18 +1654,18 @@ int mg_get_var(const char *buf, size_t buf_len, const char *name,
|
|
|
|
|
|
if (dst == NULL || dst_len == 0) {
|
|
if (dst == NULL || dst_len == 0) {
|
|
len = -2;
|
|
len = -2;
|
|
- } else if (buf == NULL || name == NULL || buf_len == 0) {
|
|
|
|
|
|
+ } else if (data == NULL || name == NULL || data_len == 0) {
|
|
len = -1;
|
|
len = -1;
|
|
dst[0] = '\0';
|
|
dst[0] = '\0';
|
|
} else {
|
|
} else {
|
|
name_len = strlen(name);
|
|
name_len = strlen(name);
|
|
- e = buf + buf_len;
|
|
|
|
|
|
+ e = data + data_len;
|
|
len = -1;
|
|
len = -1;
|
|
dst[0] = '\0';
|
|
dst[0] = '\0';
|
|
|
|
|
|
- // buf is "var1=val1&var2=val2...". Find variable first
|
|
|
|
- for (p = buf; p + name_len < e; p++) {
|
|
|
|
- if ((p == buf || p[-1] == '&') && p[name_len] == '=' &&
|
|
|
|
|
|
+ // data is "var1=val1&var2=val2...". Find variable first
|
|
|
|
+ for (p = data; p + name_len < e; p++) {
|
|
|
|
+ if ((p == data || p[-1] == '&') && p[name_len] == '=' &&
|
|
!mg_strncasecmp(name, p, name_len)) {
|
|
!mg_strncasecmp(name, p, name_len)) {
|
|
|
|
|
|
// Point p to variable value
|
|
// Point p to variable value
|
|
@@ -1679,6 +1680,11 @@ int mg_get_var(const char *buf, size_t buf_len, const char *name,
|
|
|
|
|
|
// Decode variable into destination buffer
|
|
// Decode variable into destination buffer
|
|
len = url_decode(p, (size_t)(s - p), dst, dst_len, 1);
|
|
len = url_decode(p, (size_t)(s - p), dst, dst_len, 1);
|
|
|
|
+
|
|
|
|
+ // Redirect error code from -1 to -2 (destination buffer too small).
|
|
|
|
+ if (len == -1) {
|
|
|
|
+ len = -2;
|
|
|
|
+ }
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1886,6 +1892,7 @@ static const struct {
|
|
{".mp3", 4, "audio/x-mp3"},
|
|
{".mp3", 4, "audio/x-mp3"},
|
|
{".mid", 4, "audio/mid"},
|
|
{".mid", 4, "audio/mid"},
|
|
{".m3u", 4, "audio/x-mpegurl"},
|
|
{".m3u", 4, "audio/x-mpegurl"},
|
|
|
|
+ {".ogg", 4, "audio/ogg"},
|
|
{".ram", 4, "audio/x-pn-realaudio"},
|
|
{".ram", 4, "audio/x-pn-realaudio"},
|
|
{".xml", 4, "text/xml"},
|
|
{".xml", 4, "text/xml"},
|
|
{".json", 5, "text/json"},
|
|
{".json", 5, "text/json"},
|
|
@@ -5075,6 +5082,7 @@ struct mg_context *mg_start(mg_callback_t user_callback, void *user_data,
|
|
}
|
|
}
|
|
if (ctx->config[i] != NULL) {
|
|
if (ctx->config[i] != NULL) {
|
|
cry(fc(ctx), "warning: %s: duplicate option", name);
|
|
cry(fc(ctx), "warning: %s: duplicate option", name);
|
|
|
|
+ free(ctx->config[i]);
|
|
}
|
|
}
|
|
ctx->config[i] = mg_strdup(value);
|
|
ctx->config[i] = mg_strdup(value);
|
|
DEBUG_TRACE(("[%s] -> [%s]", name, value));
|
|
DEBUG_TRACE(("[%s] -> [%s]", name, value));
|