|
@@ -2070,10 +2070,14 @@ struct mg_file_in_memory {
|
|
struct mg_file_access {
|
|
struct mg_file_access {
|
|
/* File properties filled by mg_fopen: */
|
|
/* File properties filled by mg_fopen: */
|
|
FILE *fp;
|
|
FILE *fp;
|
|
- /* TODO (low): Replace "membuf" implementation by a "file in memory"
|
|
|
|
- * support library. Use some struct mg_file_in_memory *mf; instead of
|
|
|
|
- * membuf char pointer. */
|
|
|
|
|
|
+#if defined(MG_USE_OPEN_FILE)
|
|
|
|
+ /* TODO (low): Remove obsolete "file in memory" implementation.
|
|
|
|
+ * In an "early 2017" discussion at Google groups
|
|
|
|
+ * https://groups.google.com/forum/#!topic/civetweb/h9HT4CmeYqI
|
|
|
|
+ * we decided to get rid of this feature (after some fade-out
|
|
|
|
+ * phase). */
|
|
const char *membuf;
|
|
const char *membuf;
|
|
|
|
+#endif
|
|
};
|
|
};
|
|
|
|
|
|
struct mg_file {
|
|
struct mg_file {
|
|
@@ -2081,6 +2085,8 @@ struct mg_file {
|
|
struct mg_file_access access;
|
|
struct mg_file_access access;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+#if defined(MG_USE_OPEN_FILE)
|
|
|
|
+
|
|
#define STRUCT_FILE_INITIALIZER \
|
|
#define STRUCT_FILE_INITIALIZER \
|
|
{ \
|
|
{ \
|
|
{ \
|
|
{ \
|
|
@@ -2092,6 +2098,22 @@ struct mg_file {
|
|
} \
|
|
} \
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#else
|
|
|
|
+
|
|
|
|
+#define STRUCT_FILE_INITIALIZER \
|
|
|
|
+ { \
|
|
|
|
+ { \
|
|
|
|
+ (uint64_t)0, (time_t)0, 0, 0, 0 \
|
|
|
|
+ } \
|
|
|
|
+ , \
|
|
|
|
+ { \
|
|
|
|
+ (FILE *) NULL \
|
|
|
|
+ } \
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+
|
|
/* Describes listening socket, or socket which was accept()-ed by the master
|
|
/* Describes listening socket, or socket which was accept()-ed by the master
|
|
* thread and queued for future handling by the worker thread. */
|
|
* thread and queued for future handling by the worker thread. */
|
|
struct socket {
|
|
struct socket {
|
|
@@ -2913,7 +2935,12 @@ is_file_opened(const struct mg_file_access *fileacc)
|
|
if (!fileacc) {
|
|
if (!fileacc) {
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+#if defined(MG_USE_OPEN_FILE)
|
|
return (fileacc->membuf != NULL) || (fileacc->fp != NULL);
|
|
return (fileacc->membuf != NULL) || (fileacc->fp != NULL);
|
|
|
|
+#else
|
|
|
|
+ return (fileacc->fp != NULL);
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2940,7 +2967,9 @@ mg_fopen(const struct mg_connection *conn,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
filep->access.fp = NULL;
|
|
filep->access.fp = NULL;
|
|
|
|
+#if defined(MG_USE_OPEN_FILE)
|
|
filep->access.membuf = NULL;
|
|
filep->access.membuf = NULL;
|
|
|
|
+#endif
|
|
|
|
|
|
if (!is_file_in_memory(conn, path)) {
|
|
if (!is_file_in_memory(conn, path)) {
|
|
|
|
|
|
@@ -2996,11 +3025,13 @@ mg_fopen(const struct mg_connection *conn,
|
|
return (filep->access.fp != NULL);
|
|
return (filep->access.fp != NULL);
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
+#if defined(MG_USE_OPEN_FILE)
|
|
/* is_file_in_memory returned true */
|
|
/* is_file_in_memory returned true */
|
|
if (open_file_in_memory(conn, path, filep, mode)) {
|
|
if (open_file_in_memory(conn, path, filep, mode)) {
|
|
/* file is in memory */
|
|
/* file is in memory */
|
|
return (filep->access.membuf != NULL);
|
|
return (filep->access.membuf != NULL);
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
/* Open failed */
|
|
/* Open failed */
|
|
@@ -3016,8 +3047,10 @@ mg_fclose(struct mg_file_access *fileacc)
|
|
if (fileacc != NULL) {
|
|
if (fileacc != NULL) {
|
|
if (fileacc->fp != NULL) {
|
|
if (fileacc->fp != NULL) {
|
|
ret = fclose(fileacc->fp);
|
|
ret = fclose(fileacc->fp);
|
|
|
|
+#if defined(MG_USE_OPEN_FILE)
|
|
} else if (fileacc->membuf != NULL) {
|
|
} else if (fileacc->membuf != NULL) {
|
|
ret = 0;
|
|
ret = 0;
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
/* reset all members of fileacc */
|
|
/* reset all members of fileacc */
|
|
memset(fileacc, 0, sizeof(*fileacc));
|
|
memset(fileacc, 0, sizeof(*fileacc));
|
|
@@ -7771,14 +7804,17 @@ parse_auth_header(struct mg_connection *conn,
|
|
static const char *
|
|
static const char *
|
|
mg_fgets(char *buf, size_t size, struct mg_file *filep, char **p)
|
|
mg_fgets(char *buf, size_t size, struct mg_file *filep, char **p)
|
|
{
|
|
{
|
|
|
|
+#if defined(MG_USE_OPEN_FILE)
|
|
const char *eof;
|
|
const char *eof;
|
|
size_t len;
|
|
size_t len;
|
|
const char *memend;
|
|
const char *memend;
|
|
|
|
+#endif
|
|
|
|
|
|
if (!filep) {
|
|
if (!filep) {
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#if defined(MG_USE_OPEN_FILE)
|
|
if ((filep->access.membuf != NULL) && (*p != NULL)) {
|
|
if ((filep->access.membuf != NULL) && (*p != NULL)) {
|
|
memend = (const char *)&filep->access.membuf[filep->stat.size];
|
|
memend = (const char *)&filep->access.membuf[filep->stat.size];
|
|
/* Search for \n from p till the end of stream */
|
|
/* Search for \n from p till the end of stream */
|
|
@@ -7794,7 +7830,9 @@ mg_fgets(char *buf, size_t size, struct mg_file *filep, char **p)
|
|
buf[len] = '\0';
|
|
buf[len] = '\0';
|
|
*p += len;
|
|
*p += len;
|
|
return len ? eof : NULL;
|
|
return len ? eof : NULL;
|
|
- } else if (filep->access.fp != NULL) {
|
|
|
|
|
|
+ } else /* filep->access.fp block below */
|
|
|
|
+#endif
|
|
|
|
+ if (filep->access.fp != NULL) {
|
|
return fgets(buf, (int)size, filep->access.fp);
|
|
return fgets(buf, (int)size, filep->access.fp);
|
|
} else {
|
|
} else {
|
|
return NULL;
|
|
return NULL;
|
|
@@ -7828,7 +7866,7 @@ read_auth_file(struct mg_file *filep,
|
|
struct read_auth_file_struct *workdata,
|
|
struct read_auth_file_struct *workdata,
|
|
int depth)
|
|
int depth)
|
|
{
|
|
{
|
|
- char *p;
|
|
|
|
|
|
+ char *p = NULL /* init if MG_USE_OPEN_FILE is not set */;
|
|
int is_authorized = 0;
|
|
int is_authorized = 0;
|
|
struct mg_file fp;
|
|
struct mg_file fp;
|
|
size_t l;
|
|
size_t l;
|
|
@@ -7837,8 +7875,10 @@ read_auth_file(struct mg_file *filep,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
- /* Loop over passwords file */
|
|
|
|
|
|
+/* Loop over passwords file */
|
|
|
|
+#if defined(MG_USE_OPEN_FILE)
|
|
p = (char *)filep->access.membuf;
|
|
p = (char *)filep->access.membuf;
|
|
|
|
+#endif
|
|
while (mg_fgets(workdata->buf, sizeof(workdata->buf), filep, &p) != NULL) {
|
|
while (mg_fgets(workdata->buf, sizeof(workdata->buf), filep, &p) != NULL) {
|
|
l = strlen(workdata->buf);
|
|
l = strlen(workdata->buf);
|
|
while (l > 0) {
|
|
while (l > 0) {
|
|
@@ -8915,13 +8955,16 @@ send_file_data(struct mg_connection *conn,
|
|
: (int64_t)(filep->stat.size);
|
|
: (int64_t)(filep->stat.size);
|
|
offset = (offset < 0) ? 0 : ((offset > size) ? size : offset);
|
|
offset = (offset < 0) ? 0 : ((offset > size) ? size : offset);
|
|
|
|
|
|
|
|
+#if defined(MG_USE_OPEN_FILE)
|
|
if ((len > 0) && (filep->access.membuf != NULL) && (size > 0)) {
|
|
if ((len > 0) && (filep->access.membuf != NULL) && (size > 0)) {
|
|
/* file stored in memory */
|
|
/* file stored in memory */
|
|
if (len > size - offset) {
|
|
if (len > size - offset) {
|
|
len = size - offset;
|
|
len = size - offset;
|
|
}
|
|
}
|
|
mg_write(conn, filep->access.membuf + offset, (size_t)len);
|
|
mg_write(conn, filep->access.membuf + offset, (size_t)len);
|
|
- } else if (len > 0 && filep->access.fp != NULL) {
|
|
|
|
|
|
+ } else /* else block below */
|
|
|
|
+#endif
|
|
|
|
+ if (len > 0 && filep->access.fp != NULL) {
|
|
/* file stored on disk */
|
|
/* file stored on disk */
|
|
#if defined(__linux__)
|
|
#if defined(__linux__)
|
|
/* sendfile is only available for Linux */
|
|
/* sendfile is only available for Linux */
|
|
@@ -10745,9 +10788,10 @@ put_file(struct mg_connection *conn, const char *path)
|
|
rc = 0;
|
|
rc = 0;
|
|
|
|
|
|
} else {
|
|
} else {
|
|
- /* File exists and is not a directory. */
|
|
|
|
- /* Can it be replaced? */
|
|
|
|
|
|
+/* File exists and is not a directory. */
|
|
|
|
+/* Can it be replaced? */
|
|
|
|
|
|
|
|
+#if defined(MG_USE_OPEN_FILE)
|
|
if (file.access.membuf != NULL) {
|
|
if (file.access.membuf != NULL) {
|
|
/* This is an "in-memory" file, that can not be replaced */
|
|
/* This is an "in-memory" file, that can not be replaced */
|
|
mg_send_http_error(conn,
|
|
mg_send_http_error(conn,
|
|
@@ -10757,6 +10801,7 @@ put_file(struct mg_connection *conn, const char *path)
|
|
path);
|
|
path);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
|
|
|
|
/* Check if the server may write this file */
|
|
/* Check if the server may write this file */
|
|
if (access(path, W_OK) == 0) {
|
|
if (access(path, W_OK) == 0) {
|
|
@@ -11055,10 +11100,13 @@ mg_fgetc(struct mg_file *filep, int offset)
|
|
if (filep == NULL) {
|
|
if (filep == NULL) {
|
|
return EOF;
|
|
return EOF;
|
|
}
|
|
}
|
|
|
|
+#if defined(MG_USE_OPEN_FILE)
|
|
if ((filep->access.membuf != NULL) && (offset >= 0)
|
|
if ((filep->access.membuf != NULL) && (offset >= 0)
|
|
&& (((unsigned int)(offset)) < filep->stat.size)) {
|
|
&& (((unsigned int)(offset)) < filep->stat.size)) {
|
|
return ((const unsigned char *)filep->access.membuf)[offset];
|
|
return ((const unsigned char *)filep->access.membuf)[offset];
|
|
- } else if (filep->access.fp != NULL) {
|
|
|
|
|
|
+ } else /* else block below */
|
|
|
|
+#endif
|
|
|
|
+ if (filep->access.fp != NULL) {
|
|
return fgetc(filep->access.fp);
|
|
return fgetc(filep->access.fp);
|
|
} else {
|
|
} else {
|
|
return EOF;
|
|
return EOF;
|