1
0
mirror of https://github.com/lammertb/libhttp.git synced 2025-08-09 03:22:45 +03:00

Add funtion to store body data

This commit is contained in:
bel
2016-02-21 21:36:37 +01:00
parent 9d7e746d03
commit 92099ed0da
3 changed files with 140 additions and 77 deletions

View File

@@ -63,9 +63,9 @@ ExampleHandler(struct mg_connection *conn, void *cbdata)
mg_printf(conn, mg_printf(conn,
"<p>To see a page from the *.foo handler <a " "<p>To see a page from the *.foo handler <a "
"href=\"xy.foo\">click xy.foo</a></p>"); "href=\"xy.foo\">click xy.foo</a></p>");
mg_printf( mg_printf(conn,
conn, "<p>To see a page from the close handler <a "
"<p>To see a page from the close handler <a href=\"close\">click close</a></p>"); "href=\"close\">click close</a></p>");
mg_printf(conn, mg_printf(conn,
"<p>To see a page from the FileHandler handler <a " "<p>To see a page from the FileHandler handler <a "
"href=\"form\">click form</a> (this is the form test page)</p>"); "href=\"form\">click form</a> (this is the form test page)</p>");
@@ -155,7 +155,8 @@ CloseHandler(struct mg_connection *conn, void *cbdata)
mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"); mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");
mg_printf(conn, "<html><body>"); mg_printf(conn, "<html><body>");
mg_printf(conn, "<h2>This handler will close the connection in a second</h2>"); mg_printf(conn,
"<h2>This handler will close the connection in a second</h2>");
#ifdef _WIN32 #ifdef _WIN32
Sleep(1000); Sleep(1000);
#else #else

View File

@@ -589,6 +589,16 @@ CIVETWEB_API int mg_printf(struct mg_connection *,
CIVETWEB_API void mg_send_file(struct mg_connection *conn, const char *path); CIVETWEB_API void mg_send_file(struct mg_connection *conn, const char *path);
/* Store body data into a file. */
CIVETWEB_API long long mg_store_body(struct mg_connection *conn,
const char *path);
/* Read entire request body and stor it in a file "path".
Return:
< 0 Error
>= 0 Number of bytes stored in file "path".
*/
/* Read data from the remote end, return number of bytes read. /* Read data from the remote end, return number of bytes read.
Return: Return:
0 connection has been closed by peer. No more data could be read. 0 connection has been closed by peer. No more data could be read.

View File

@@ -1085,7 +1085,8 @@ enum {
#endif #endif
ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_ALLOW_ORIGIN,
ERROR_PAGES, ERROR_PAGES,
CONFIG_TCP_NODELAY, /* Prepended CONFIG_ to avoid conflict with the socket option typedef TCP_NODELAY */ CONFIG_TCP_NODELAY, /* Prepended CONFIG_ to avoid conflict with the socket
option typedef TCP_NODELAY */
NUM_OPTIONS NUM_OPTIONS
}; };
@@ -2889,6 +2890,7 @@ mg_remove(const char *path)
to_unicode(path, wbuf, ARRAY_SIZE(wbuf)); to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
return DeleteFileW(wbuf) ? 0 : -1; return DeleteFileW(wbuf) ? 0 : -1;
} }
#endif
static int static int
@@ -2905,7 +2907,7 @@ mg_mkdir(const char *path, int mode)
return CreateDirectoryW(wbuf, NULL) ? 0 : -1; return CreateDirectoryW(wbuf, NULL) ? 0 : -1;
} }
#endif
/* Create substitutes for POSIX functions in Win32. */ /* Create substitutes for POSIX functions in Win32. */
@@ -6446,6 +6448,98 @@ mg_send_file(struct mg_connection *conn, const char *path)
} }
/* For a given PUT path, create all intermediate subdirectories.
* Return 0 if the path itself is a directory.
* Return 1 if the path leads to a file.
* Return -1 for if the path is too long.
* Return -2 if path can not be created.
*/
static int
put_dir(struct mg_connection *conn, const char *path)
{
char buf[PATH_MAX];
const char *s, *p;
struct file file = STRUCT_FILE_INITIALIZER;
size_t len;
int res = 1;
for (s = p = path + 2; (p = strchr(s, '/')) != NULL; s = ++p) {
len = (size_t)(p - path);
if (len >= sizeof(buf)) {
/* path too long */
res = -1;
break;
}
memcpy(buf, path, len);
buf[len] = '\0';
/* Try to create intermediate directory */
DEBUG_TRACE("mkdir(%s)", buf);
if (!mg_stat(conn, buf, &file) && mg_mkdir(buf, 0755) != 0) {
/* path does not exixt and can not be created */
res = -2;
break;
}
/* Is path itself a directory? */
if (p[1] == '\0') {
res = 0;
}
}
return res;
}
long long
mg_store_body(struct mg_connection *conn, const char *path)
{
char buf[MG_BUF_LEN];
long long len = 0;
int ret, n;
FILE *f;
if (conn->consumed_content != 0) {
mg_cry(conn, "%s: Contents already consumed", __func__);
return -11;
}
ret = put_dir(conn, path);
if (ret < 0) {
/* -1 for path too long,
* -2 for path can not be created. */
return ret;
}
if (ret != 1) {
/* Return 0 means, path itself is a directory. */
return 0;
}
f = fopen(path, "w");
if (!f) {
return -12;
}
ret = mg_read(conn, buf, sizeof(buf));
while (ret > 0) {
n = (int)fwrite(buf, 1, (size_t)ret, f);
if (n != ret) {
fclose(f);
remove(path);
return -13;
}
ret = mg_read(conn, buf, sizeof(buf));
}
if (fclose(f) != 0) {
remove(path);
return -14;
}
return len;
}
/* Parse HTTP headers from the given buffer, advance buffer to the point /* Parse HTTP headers from the given buffer, advance buffer to the point
* where parsing stopped. */ * where parsing stopped. */
static void static void
@@ -6788,7 +6882,7 @@ forward_body_data(struct mg_connection *conn, FILE *fp, SOCKET sock, SSL *ssl)
} }
if (conn->consumed_content == conn->content_len) { if (conn->consumed_content == conn->content_len) {
success = nread >= 0; success = (nread >= 0);
} }
/* Each error code path in this function must send an error */ /* Each error code path in this function must send an error */
@@ -7353,49 +7447,6 @@ done:
#if !defined(NO_FILES) #if !defined(NO_FILES)
/* For a given PUT path, create all intermediate subdirectories.
* Return 0 if the path itself is a directory.
* Return 1 if the path leads to a file.
* Return -1 for if the path is too long.
* Return -2 if path can not be created.
*/
static int
put_dir(struct mg_connection *conn, const char *path)
{
char buf[PATH_MAX];
const char *s, *p;
struct file file = STRUCT_FILE_INITIALIZER;
size_t len;
int res = 1;
for (s = p = path + 2; (p = strchr(s, '/')) != NULL; s = ++p) {
len = (size_t)(p - path);
if (len >= sizeof(buf)) {
/* path too long */
res = -1;
break;
}
memcpy(buf, path, len);
buf[len] = '\0';
/* Try to create intermediate directory */
DEBUG_TRACE("mkdir(%s)", buf);
if (!mg_stat(conn, buf, &file) && mg_mkdir(buf, 0755) != 0) {
/* path does not exixt and can not be created */
res = -2;
break;
}
/* Is path itself a directory? */
if (p[1] == '\0') {
res = 0;
}
}
return res;
}
static void static void
mkcol(struct mg_connection *conn, const char *path) mkcol(struct mg_connection *conn, const char *path)
{ {
@@ -7585,6 +7636,7 @@ put_file(struct mg_connection *conn, const char *path)
/* forward_body_data failed. /* forward_body_data failed.
* The error code has already been sent to the client, * The error code has already been sent to the client,
* and conn->status_code is already set. */ * and conn->status_code is already set. */
mg_fclose(&file);
return; return;
} }