1
0
mirror of https://github.com/lammertb/libhttp.git synced 2026-01-27 08:02:47 +03:00

Moved log_access to own file

This commit is contained in:
Lammert Bies
2016-12-10 11:33:57 +01:00
parent 640863e02d
commit fb8806ca6f
5 changed files with 233 additions and 274 deletions

View File

@@ -60,6 +60,7 @@ LIB_SOURCES = src/libhttp.c \
src/httplib_getreq.c \
src/httplib_initialize_ssl.c \
src/httplib_load_dll.c \
src/httplib_log_access.c \
src/httplib_master_thread.c \
src/httplib_process_new_connection.c \
src/httplib_produce_socket.c \

View File

@@ -20,35 +20,27 @@
*/
static int
url_encoded_field_found(const struct mg_connection *conn,
static int url_encoded_field_found(const struct mg_connection *conn,
const char *key,
size_t key_len,
const char *filename,
size_t filename_len,
char *path,
size_t path_len,
struct mg_form_data_handler *fdh)
{
struct mg_form_data_handler *fdh) {
char key_dec[1024];
char filename_dec[1024];
int key_dec_len;
int filename_dec_len;
int ret;
key_dec_len =
mg_url_decode(key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
key_dec_len = mg_url_decode(key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
if (((size_t)key_dec_len >= (size_t)sizeof(key_dec)) || (key_dec_len < 0)) {
return FORM_FIELD_STORAGE_SKIP;
}
if (((size_t)key_dec_len >= (size_t)sizeof(key_dec)) || (key_dec_len < 0)) return FORM_FIELD_STORAGE_SKIP;
if (filename) {
filename_dec_len = mg_url_decode(filename,
(int)filename_len,
filename_dec,
(int)sizeof(filename_dec),
1);
filename_dec_len = mg_url_decode(filename, (int)filename_len, filename_dec, (int)sizeof(filename_dec), 1);
if (((size_t)filename_dec_len >= (size_t)sizeof(filename_dec))
|| (filename_dec_len < 0)) {
@@ -56,9 +48,8 @@ url_encoded_field_found(const struct mg_connection *conn,
mg_cry(conn, "%s: Cannot decode filename", __func__);
return FORM_FIELD_STORAGE_SKIP;
}
} else {
filename_dec[0] = 0;
}
} else filename_dec[0] = 0;
ret =
fdh->field_found(key_dec, filename_dec, path, path_len, fdh->user_data);
@@ -80,14 +71,13 @@ url_encoded_field_found(const struct mg_connection *conn,
}
static int
url_encoded_field_get(const struct mg_connection *conn,
static int url_encoded_field_get(const struct mg_connection *conn,
const char *key,
size_t key_len,
const char *value,
size_t value_len,
struct mg_form_data_handler *fdh)
{
struct mg_form_data_handler *fdh) {
char key_dec[1024];
char *value_dec = XX_httplib_malloc(value_len + 1);
@@ -95,23 +85,15 @@ url_encoded_field_get(const struct mg_connection *conn,
if (!value_dec) {
/* Log error message and stop parsing the form data. */
mg_cry(conn,
"%s: Not enough memory (required: %lu)",
__func__,
(unsigned long)(value_len + 1));
mg_cry(conn, "%s: Not enough memory (required: %lu)", __func__, (unsigned long)(value_len + 1));
return FORM_FIELD_STORAGE_ABORT;
}
mg_url_decode(key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
value_dec_len =
mg_url_decode(value, (int)value_len, value_dec, (int)value_len + 1, 1);
ret = fdh->field_get(key_dec,
value_dec,
(size_t)value_dec_len,
fdh->user_data);
value_dec_len = mg_url_decode(value, (int)value_len, value_dec, (int)value_len + 1, 1);
ret = fdh->field_get(key_dec, value_dec, (size_t)value_dec_len, fdh->user_data);
XX_httplib_free(value_dec);
return ret;
@@ -124,8 +106,8 @@ unencoded_field_get(const struct mg_connection *conn,
size_t key_len,
const char *value,
size_t value_len,
struct mg_form_data_handler *fdh)
{
struct mg_form_data_handler *fdh) {
char key_dec[1024];
(void)conn;
@@ -135,12 +117,8 @@ unencoded_field_get(const struct mg_connection *conn,
}
static int
field_stored(const struct mg_connection *conn,
const char *path,
long long file_size,
struct mg_form_data_handler *fdh)
{
static int field_stored(const struct mg_connection *conn, const char *path, long long file_size, struct mg_form_data_handler *fdh) {
/* Equivalent to "upload" callback of "mg_upload". */
(void)conn; /* we do not need mg_cry here, so conn is currently unused */
@@ -149,12 +127,8 @@ field_stored(const struct mg_connection *conn,
}
static const char *
search_boundary(const char *buf,
size_t buf_len,
const char *boundary,
size_t boundary_len)
{
static const char * search_boundary(const char *buf, size_t buf_len, const char *boundary, size_t boundary_len) {
/* We must do a binary search here, not a string search, since the buffer
* may contain '\x00' bytes, if binary data is transferred. */
int clen = (int)buf_len - (int)boundary_len - 4;
@@ -171,10 +145,8 @@ search_boundary(const char *buf,
}
int
mg_handle_form_request(struct mg_connection *conn,
struct mg_form_data_handler *fdh)
{
int mg_handle_form_request(struct mg_connection *conn, struct mg_form_data_handler *fdh) {
const char *content_type;
char path[512];
char buf[1024];
@@ -186,8 +158,7 @@ mg_handle_form_request(struct mg_connection *conn,
int64_t file_size = 0; /* init here, to a avoid a false positive
"uninitialized variable used" warning */
int has_body_data =
(conn->request_info.content_length > 0) || (conn->is_chunked);
int has_body_data = (conn->request_info.content_length > 0) || (conn->is_chunked);
/* There are three ways to encode data from a HTML form:
* 1) method: GET (default)
@@ -243,14 +214,7 @@ mg_handle_form_request(struct mg_connection *conn,
*/
memset(path, 0, sizeof(path));
field_count++;
field_storage = url_encoded_field_found(conn,
data,
(size_t)keylen,
NULL,
0,
path,
sizeof(path) - 1,
fdh);
field_storage = url_encoded_field_found(conn, data, (size_t)keylen, NULL, 0, path, sizeof(path) - 1, fdh);
val++;
next = strchr(val, '&');
@@ -269,18 +233,13 @@ mg_handle_form_request(struct mg_connection *conn,
}
if (field_storage == FORM_FIELD_STORAGE_STORE) {
/* Store the content to a file */
if (mg_fopen(conn, path, "wb", &fstore) == 0) {
fstore.fp = NULL;
}
if (XX_httplib_fopen(conn, path, "wb", &fstore) == 0) fstore.fp = NULL;
file_size = 0;
if (fstore.fp != NULL) {
size_t n =
(size_t)fwrite(val, 1, (size_t)vallen, fstore.fp);
if ((n != (size_t)vallen) || (ferror(fstore.fp))) {
mg_cry(conn,
"%s: Cannot write file %s",
__func__,
path);
mg_cry(conn, "%s: Cannot write file %s", __func__, path);
fclose(fstore.fp);
fstore.fp = NULL;
remove_bad_file(conn, path);
@@ -293,18 +252,13 @@ mg_handle_form_request(struct mg_connection *conn,
/* stored successfully */
field_stored(conn, path, file_size, fdh);
} else {
mg_cry(conn,
"%s: Error saving file %s",
__func__,
path);
mg_cry(conn, "%s: Error saving file %s", __func__, path);
remove_bad_file(conn, path);
}
fstore.fp = NULL;
}
} else {
mg_cry(conn, "%s: Cannot create file %s", __func__, path);
}
} else mg_cry(conn, "%s: Cannot create file %s", __func__, path);
}
/* if (field_storage == FORM_FIELD_STORAGE_READ) { */
@@ -320,8 +274,7 @@ mg_handle_form_request(struct mg_connection *conn,
*/
/* } */
if ((field_storage & FORM_FIELD_STORAGE_ABORT)
== FORM_FIELD_STORAGE_ABORT) {
if ((field_storage & FORM_FIELD_STORAGE_ABORT) == FORM_FIELD_STORAGE_ABORT) {
/* Stop parsing the request */
break;
}
@@ -373,9 +326,7 @@ mg_handle_form_request(struct mg_connection *conn,
}
buf_fill += r;
buf[buf_fill] = 0;
if (buf_fill < 1) {
break;
}
if (buf_fill < 1) break;
}
val = strchr(buf, '=');
@@ -389,14 +340,7 @@ mg_handle_form_request(struct mg_connection *conn,
/* Call callback */
memset(path, 0, sizeof(path));
field_count++;
field_storage = url_encoded_field_found(conn,
buf,
(size_t)keylen,
NULL,
0,
path,
sizeof(path) - 1,
fdh);
field_storage = url_encoded_field_found(conn, buf, (size_t)keylen, NULL, 0, path, sizeof(path) - 1, fdh);
if ((field_storage & FORM_FIELD_STORAGE_ABORT)
== FORM_FIELD_STORAGE_ABORT) {
@@ -405,13 +349,9 @@ mg_handle_form_request(struct mg_connection *conn,
}
if (field_storage == FORM_FIELD_STORAGE_STORE) {
if (mg_fopen(conn, path, "wb", &fstore) == 0) {
fstore.fp = NULL;
}
if (XX_httplib_fopen(conn, path, "wb", &fstore) == 0) fstore.fp = NULL;
file_size = 0;
if (!fstore.fp) {
mg_cry(conn, "%s: Cannot create file %s", __func__, path);
}
if (!fstore.fp) mg_cry(conn, "%s: Cannot create file %s", __func__, path);
}
get_block = 0;
@@ -447,13 +387,9 @@ mg_handle_form_request(struct mg_connection *conn,
get_block++;
}
if (fstore.fp) {
size_t n =
(size_t)fwrite(val, 1, (size_t)vallen, fstore.fp);
size_t n = (size_t)fwrite(val, 1, (size_t)vallen, fstore.fp);
if ((n != (size_t)vallen) || (ferror(fstore.fp))) {
mg_cry(conn,
"%s: Cannot write file %s",
__func__,
path);
mg_cry(conn, "%s: Cannot write file %s", __func__, path);
fclose(fstore.fp);
fstore.fp = NULL;
remove_bad_file(conn, path);
@@ -463,9 +399,7 @@ mg_handle_form_request(struct mg_connection *conn,
if (!end_of_key_value_pair_found) {
used = next - buf;
memmove(buf,
buf + (size_t)used,
sizeof(buf) - (size_t)used);
memmove(buf, buf + (size_t)used, sizeof(buf) - (size_t)used);
buf_fill -= (int)used;
if ((size_t)buf_fill < (sizeof(buf) - 1)) {
@@ -485,9 +419,7 @@ mg_handle_form_request(struct mg_connection *conn,
}
buf_fill += r;
buf[buf_fill] = 0;
if (buf_fill < 1) {
break;
}
if (buf_fill < 1) break;
val = buf;
}
}
@@ -523,7 +455,12 @@ mg_handle_form_request(struct mg_connection *conn,
size_t bl;
ptrdiff_t used;
struct mg_request_info part_header;
char *hbuf, *hend, *fbeg, *fend, *nbeg, *nend;
char *hbuf;
char *hend;
char *fbeg;
char *fend;
char *nbeg;
char *nend;
const char *content_disp;
const char *next;
@@ -531,9 +468,7 @@ mg_handle_form_request(struct mg_connection *conn,
/* Skip all spaces between MULTIPART/FORM-DATA; and BOUNDARY= */
bl = 20;
while (content_type[bl] == ' ') {
bl++;
}
while (content_type[bl] == ' ') bl++;
/* There has to be a BOUNDARY definition in the Content-Type header */
if (mg_strncasecmp(content_type + bl, "BOUNDARY=", 9)) {
@@ -560,9 +495,7 @@ mg_handle_form_request(struct mg_connection *conn,
size_t towrite, n;
int get_block;
r = mg_read(conn,
buf + (size_t)buf_fill,
sizeof(buf) - 1 - (size_t)buf_fill);
r = mg_read(conn, buf + (size_t)buf_fill, sizeof(buf) - 1 - (size_t)buf_fill);
if (r < 0) {
/* read error */
return -1;
@@ -648,38 +581,22 @@ mg_handle_form_request(struct mg_connection *conn,
/* TODO: check Content-Type */
/* Content-Type: application/octet-stream */
} else {
fend = fbeg;
}
} else fend = fbeg;
memset(path, 0, sizeof(path));
field_count++;
field_storage = url_encoded_field_found(conn,
nbeg,
(size_t)(nend - nbeg),
fbeg,
(size_t)(fend - fbeg),
path,
sizeof(path) - 1,
fdh);
field_storage = url_encoded_field_found(conn, nbeg, (size_t)(nend - nbeg), fbeg, (size_t)(fend - fbeg), path, sizeof(path) - 1, fdh);
/* If the boundary is already in the buffer, get the address,
* otherwise next will be NULL. */
next = search_boundary(hbuf,
(size_t)((buf - hbuf) + buf_fill),
boundary,
bl);
next = search_boundary(hbuf, (size_t)((buf - hbuf) + buf_fill), boundary, bl);
if (field_storage == FORM_FIELD_STORAGE_STORE) {
/* Store the content to a file */
if (mg_fopen(conn, path, "wb", &fstore) == 0) {
fstore.fp = NULL;
}
if (XX_httplib_fopen(conn, path, "wb", &fstore) == 0) fstore.fp = NULL;
file_size = 0;
if (!fstore.fp) {
mg_cry(conn, "%s: Cannot create file %s", __func__, path);
}
if (!fstore.fp) mg_cry(conn, "%s: Cannot create file %s", __func__, path);
}
get_block = 0;
@@ -710,10 +627,7 @@ mg_handle_form_request(struct mg_connection *conn,
/* Store the content of the buffer. */
n = (size_t)fwrite(hend, 1, towrite, fstore.fp);
if ((n != towrite) || (ferror(fstore.fp))) {
mg_cry(conn,
"%s: Cannot write file %s",
__func__,
path);
mg_cry(conn, "%s: Cannot write file %s", __func__, path);
fclose(fstore.fp);
fstore.fp = NULL;
remove_bad_file(conn, path);
@@ -727,9 +641,7 @@ mg_handle_form_request(struct mg_connection *conn,
hend = buf;
/* Read new data */
r = mg_read(conn,
buf + (size_t)buf_fill,
sizeof(buf) - 1 - (size_t)buf_fill);
r = mg_read(conn, buf + (size_t)buf_fill, sizeof(buf) - 1 - (size_t)buf_fill);
if (r < 0) {
/* read error */
return -1;
@@ -763,10 +675,7 @@ mg_handle_form_request(struct mg_connection *conn,
if (fstore.fp) {
n = (size_t)fwrite(hend, 1, towrite, fstore.fp);
if ((n != towrite) || (ferror(fstore.fp))) {
mg_cry(conn,
"%s: Cannot write file %s",
__func__,
path);
mg_cry(conn, "%s: Cannot write file %s", __func__, path);
fclose(fstore.fp);
fstore.fp = NULL;
remove_bad_file(conn, path);
@@ -783,10 +692,7 @@ mg_handle_form_request(struct mg_connection *conn,
/* stored successfully */
field_stored(conn, path, file_size, fdh);
} else {
mg_cry(conn,
"%s: Error saving file %s",
__func__,
path);
mg_cry(conn, "%s: Error saving file %s", __func__, path);
remove_bad_file(conn, path);
}
fstore.fp = NULL;

124
src/httplib_log_access.c Normal file
View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2016 Lammert Bies
* Copyright (c) 2013-2016 the Civetweb developers
* Copyright (c) 2004-2013 Sergey Lyubka
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "libhttp-private.h"
static const char *header_val( const struct mg_connection *conn, const char *header );
/*
* void XX_httplib_log_access( const struct mg_connection *conn );
*
* The function XX_httplib_log_access() logs an access of a client.
*/
void XX_httplib_log_access( const struct mg_connection *conn ) {
const struct mg_request_info *ri;
struct file fi;
char date[64];
char src_addr[IP_ADDR_STR_LEN];
struct tm *tm;
const char *referer;
const char *user_agent;
char buf[4096];
if (!conn || !conn->ctx) return;
if (conn->ctx->config[ACCESS_LOG_FILE] != NULL) {
if (XX_httplib_fopen(conn, conn->ctx->config[ACCESS_LOG_FILE], "a+", &fi) == 0) fi.fp = NULL;
} else fi.fp = NULL;
/* Log is written to a file and/or a callback. If both are not set,
* executing the rest of the function is pointless. */
if ((fi.fp == NULL) && (conn->ctx->callbacks.log_access == NULL)) return;
tm = localtime(&conn->conn_birth_time);
if (tm != NULL) {
strftime(date, sizeof(date), "%d/%b/%Y:%H:%M:%S %z", tm);
} else {
XX_httplib_strlcpy(date, "01/Jan/1970:00:00:00 +0000", sizeof(date));
date[sizeof(date) - 1] = '\0';
}
ri = &conn->request_info;
XX_httplib_sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
referer = header_val(conn, "Referer");
user_agent = header_val(conn, "User-Agent");
XX_httplib_snprintf(conn,
NULL, /* Ignore truncation in access log */
buf,
sizeof(buf),
"%s - %s [%s] \"%s %s%s%s HTTP/%s\" %d %" INT64_FMT " %s %s",
src_addr,
(ri->remote_user == NULL) ? "-" : ri->remote_user,
date,
ri->request_method ? ri->request_method : "-",
ri->request_uri ? ri->request_uri : "-",
ri->query_string ? "?" : "",
ri->query_string ? ri->query_string : "",
ri->http_version,
conn->status_code,
conn->num_bytes_sent,
referer,
user_agent);
if (conn->ctx->callbacks.log_access) conn->ctx->callbacks.log_access(conn, buf);
if (fi.fp) {
flockfile(fi.fp);
fprintf(fi.fp, "%s\n", buf);
fflush(fi.fp);
funlockfile(fi.fp);
XX_httplib_fclose(&fi);
}
} /* XX_httplib_log_access */
/*
* static const char *header_val( const struct mg_connection *conn, const char *header );
*
* The function header_val() returns the value of a specific header of a
* connection.
*/
static const char *header_val( const struct mg_connection *conn, const char *header ) {
const char *header_value;
if ((header_value = mg_get_header(conn, header)) == NULL) return "-";
else return header_value;
} /* header_val */

View File

@@ -840,6 +840,8 @@ int XX_httplib_connect_socket( struct mg_context *ctx, const char *host, int p
int XX_httplib_consume_socket( struct mg_context *ctx, struct socket *sp, int thread_index );
void XX_httplib_set_close_on_exec( SOCKET sock, struct mg_connection *conn );
struct mg_connection * XX_httplib_fc( struct mg_context *ctx );
void XX_httplib_fclose( struct file *filep );
int XX_httplib_fopen( const struct mg_connection *conn, const char *path, const char *mode, struct file *filep );
void XX_httplib_free_context( struct mg_context *ctx );
const char * XX_httplib_get_header( const struct mg_request_info *ri, const char *name );
int XX_httplib_get_option_index( const char *name );
@@ -885,6 +887,7 @@ int XX_httplib_ssl_use_pem_file( struct mg_context *ctx, const char *pem );
int XX_httplib_sslize( struct mg_connection *conn, SSL_CTX *s, int (*func)(SSL *) );
int XX_httplib_stat( struct mg_connection *conn, const char *path, struct file *filep );
char * XX_httplib_strdup( const char *str );
void XX_httplib_strlcpy( register char *dst, register const char *src, size_t n );
void XX_httplib_tls_dtor( void *key );
void XX_httplib_uninitialize_ssl( struct mg_context *ctx );
int XX_httplib_vprintf( struct mg_connection *conn, const char *fmt, va_list ap );

View File

@@ -871,7 +871,7 @@ static int is_file_in_memory(const struct mg_connection *conn, const char *path,
filep->membuf = conn->ctx->callbacks.open_file(conn, path, &size);
if (filep->membuf != NULL) {
/* NOTE: override filep->size only on success. Otherwise, it might
* break constructs like if (!XX_httplib_stat() || !mg_fopen()) ... */
* break constructs like if (!XX_httplib_stat() || !XX_httplib_fopen()) ... */
filep->size = size;
}
}
@@ -890,18 +890,18 @@ static bool is_file_opened( const struct file *filep ) {
} /* is_file_opened */
/* mg_fopen will open a file either in memory or on the disk.
/* XX_httplib_fopen will open a file either in memory or on the disk.
* The input parameter path is a string in UTF-8 encoding.
* The input parameter mode is the same as for fopen.
* Either fp or membuf will be set in the output struct filep.
* The function returns 1 on success, 0 on error. */
static int mg_fopen(const struct mg_connection *conn, const char *path, const char *mode, struct file *filep) {
int XX_httplib_fopen( const struct mg_connection *conn, const char *path, const char *mode, struct file *filep ) {
struct stat st;
if (!filep) return 0;
/* TODO (high): mg_fopen should only open a file, while XX_httplib_stat should
/* TODO (high): XX_httplib_fopen should only open a file, while XX_httplib_stat should
* only get the file status. They should not work on different members of
* the same structure (bad cohesion). */
memset(filep, 0, sizeof(*filep));
@@ -921,20 +921,24 @@ static int mg_fopen(const struct mg_connection *conn, const char *path, const ch
}
return is_file_opened(filep);
}
} /* XX_httplib_fopen */
static void mg_fclose(struct file *filep) {
if (filep != NULL && filep->fp != NULL) { fclose(filep->fp); }
}
void XX_httplib_fclose( struct file *filep ) {
if (filep != NULL && filep->fp != NULL) fclose(filep->fp);
} /* XX_httplib_fclose */
static void mg_strlcpy(register char *dst, register const char *src, size_t n) {
void XX_httplib_strlcpy( register char *dst, register const char *src, size_t n ) {
for (; *src != '\0' && n > 1; n--) { *dst++ = *src++; }
*dst = '\0';
}
} /* XX_httplib_strlcpy */
static int lowercase(const char *s) {
@@ -973,7 +977,7 @@ static char * mg_strndup(const char *ptr, size_t len) {
char *p;
if ((p = (char *)XX_httplib_malloc(len + 1)) != NULL) mg_strlcpy(p, ptr, len + 1);
if ((p = (char *)XX_httplib_malloc(len + 1)) != NULL) XX_httplib_strlcpy(p, ptr, len + 1);
return p;
}
@@ -1158,7 +1162,7 @@ static void gmt_time_string(char *buf, size_t buf_len, time_t *t) {
if (tm != NULL) {
strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm);
} else {
mg_strlcpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len);
XX_httplib_strlcpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len);
buf[buf_len - 1] = '\0';
}
}
@@ -1198,7 +1202,7 @@ void mg_cry(const struct mg_connection *conn, const char *fmt, ...) {
|| (conn->ctx->callbacks.log_message(conn, buf) == 0)) {
if (conn->ctx->config[ERROR_LOG_FILE] != NULL) {
if (mg_fopen(conn, conn->ctx->config[ERROR_LOG_FILE], "a+", &fi)
if (XX_httplib_fopen(conn, conn->ctx->config[ERROR_LOG_FILE], "a+", &fi)
== 0) {
fi.fp = NULL;
}
@@ -1225,7 +1229,7 @@ void mg_cry(const struct mg_connection *conn, const char *fmt, ...) {
fputc('\n', fi.fp);
fflush(fi.fp);
funlockfile(fi.fp);
mg_fclose(&fi);
XX_httplib_fclose(&fi);
}
}
}
@@ -1915,7 +1919,7 @@ static void path_to_unicode(const struct mg_connection *conn, const char *path,
DWORD err;
int (*fcompare)(const wchar_t *, const wchar_t *) = mg_wcscasecmp;
mg_strlcpy(buf, path, sizeof(buf));
XX_httplib_strlcpy(buf, path, sizeof(buf));
change_slashes_to_backslashes(buf);
/* Convert to Unicode and back. If doubly-converted string does not
@@ -1991,7 +1995,7 @@ int XX_httplib_stat( struct mg_connection *conn, const char *path, struct file *
* memset */
filep->last_modified = time(NULL);
/* last_modified = now ... assumes the file may change during runtime,
* so every mg_fopen call may return different data */
* so every XX_httplib_fopen call may return different data */
/* last_modified = conn->ctx.start_time;
* May be used it the data does not change during runtime. This allows
* browser caching. Since we do not know, we have to assume the file
@@ -2346,10 +2350,10 @@ static pid_t spawn_process(struct mg_connection *conn, const char *prog, char *e
goto spawn_cleanup;
}
if (mg_fopen(conn, cmdline, "r", &file)) {
if (XX_httplib_fopen(conn, cmdline, "r", &file)) {
p = (char *)file.membuf;
mg_fgets(buf, sizeof(buf), &file, &p);
mg_fclose(&file);
XX_httplib_fclose(&file);
buf[sizeof(buf) - 1] = '\0';
}
@@ -3298,7 +3302,7 @@ int mg_get_cookie(const char *cookie_header, const char *var_name, char *dst, si
}
if ((size_t)(p - s) < dst_size) {
len = (int)(p - s);
mg_strlcpy(dst, s, (size_t)len + 1);
XX_httplib_strlcpy(dst, s, (size_t)len + 1);
} else len = -3;
break;
}
@@ -3849,7 +3853,7 @@ static void open_auth_file(struct mg_connection *conn, const char *path, struct
if (gpass != NULL) {
/* Use global passwords file */
if (!mg_fopen(conn, gpass, "r", filep)) {
if (!XX_httplib_fopen(conn, gpass, "r", filep)) {
#ifdef DEBUG
mg_cry(conn, "fopen(%s): %s", gpass, strerror(ERRNO));
#endif
@@ -3860,7 +3864,7 @@ static void open_auth_file(struct mg_connection *conn, const char *path, struct
} else if (XX_httplib_stat(conn, path, &file) && file.is_directory) {
XX_httplib_snprintf(conn, &truncated, name, sizeof(name), "%s/%s", path, PASSWORDS_FILE_NAME);
if (truncated || !mg_fopen(conn, name, "r", filep)) {
if (truncated || !XX_httplib_fopen(conn, name, "r", filep)) {
#ifdef DEBUG
mg_cry(conn, "fopen(%s): %s", name, strerror(ERRNO));
#endif
@@ -3872,7 +3876,7 @@ static void open_auth_file(struct mg_connection *conn, const char *path, struct
}
XX_httplib_snprintf(conn, &truncated, name, sizeof(name), "%.*s/%s", (int)(e - p), p, PASSWORDS_FILE_NAME);
if (truncated || !mg_fopen(conn, name, "r", filep)) {
if (truncated || !XX_httplib_fopen(conn, name, "r", filep)) {
#ifdef DEBUG
mg_cry(conn, "fopen(%s): %s", name, strerror(ERRNO));
#endif
@@ -3908,7 +3912,7 @@ static int parse_auth_header(struct mg_connection *conn, char *buf, size_t buf_s
if ((auth_header = mg_get_header(conn, "Authorization")) == NULL || mg_strncasecmp(auth_header, "Digest ", 7) != 0) return 0;
/* Make modifiable copy of the auth header */
mg_strlcpy(buf, auth_header + 7, buf_size);
XX_httplib_strlcpy(buf, auth_header + 7, buf_size);
s = buf;
/* Parse authorization header */
@@ -4052,9 +4056,9 @@ static int read_auth_file(struct file *filep, struct read_auth_file_struct *work
/* :# is a comment */
continue;
} else if (!strncmp(workdata->f_user + 1, "include=", 8)) {
if (mg_fopen(workdata->conn, workdata->f_user + 9, "r", &fp)) {
if (XX_httplib_fopen(workdata->conn, workdata->f_user + 9, "r", &fp)) {
is_authorized = read_auth_file(&fp, workdata);
mg_fclose(&fp);
XX_httplib_fclose(&fp);
} else {
mg_cry(workdata->conn, "%s: cannot open authorization file: %s", __func__, workdata->buf);
}
@@ -4135,7 +4139,7 @@ static int check_authorization(struct mg_connection *conn, const char *path) {
if (!memcmp(conn->request_info.local_uri, uri_vec.ptr, uri_vec.len)) {
XX_httplib_snprintf(conn, &truncated, fname, sizeof(fname), "%.*s", (int)filename_vec.len, filename_vec.ptr);
if (truncated || !mg_fopen(conn, fname, "r", &file)) {
if (truncated || !XX_httplib_fopen(conn, fname, "r", &file)) {
mg_cry(conn, "%s: cannot open %s: %s", __func__, fname, strerror(errno));
}
break;
@@ -4146,7 +4150,7 @@ static int check_authorization(struct mg_connection *conn, const char *path) {
if (is_file_opened(&file)) {
authorized = authorize(conn, &file);
mg_fclose(&file);
XX_httplib_fclose(&file);
}
return authorized;
@@ -4199,9 +4203,9 @@ static int is_authorized_for_put(struct mg_connection *conn) {
const char *passfile = conn->ctx->config[PUT_DELETE_PASSWORDS_FILE];
int ret = 0;
if (passfile != NULL && mg_fopen(conn, passfile, "r", &file)) {
if (passfile != NULL && XX_httplib_fopen(conn, passfile, "r", &file)) {
ret = authorize(conn, &file);
mg_fclose(&file);
XX_httplib_fclose(&file);
}
return ret;
@@ -4492,7 +4496,7 @@ static void print_dir_entry(struct de *de) {
if (tm != NULL) {
strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", tm);
} else {
mg_strlcpy(mod, "01-Jan-1970 00:00", sizeof(mod));
XX_httplib_strlcpy(mod, "01-Jan-1970 00:00", sizeof(mod));
mod[sizeof(mod) - 1] = '\0';
}
mg_url_encode(de->file_name, href, sizeof(href));
@@ -4932,7 +4936,7 @@ static void handle_static_file_request(struct mg_connection *conn, const char *p
encoding = "Content-Encoding: gzip\r\n";
}
if (!mg_fopen(conn, path, "rb", filep)) {
if (!XX_httplib_fopen(conn, path, "rb", filep)) {
XX_httplib_send_http_error(conn, 500, "Error: Cannot open file\nfopen(%s): %s", path, strerror(ERRNO));
return;
}
@@ -4947,7 +4951,7 @@ static void handle_static_file_request(struct mg_connection *conn, const char *p
/* actually, range requests don't play well with a pre-gzipped
* file (since the range is specified in the uncompressed space) */
if (filep->gzipped) {
XX_httplib_send_http_error( conn, 501, "%s", "Error: Range requests in gzipped files are not supported"); mg_fclose(filep);
XX_httplib_send_http_error( conn, 501, "%s", "Error: Range requests in gzipped files are not supported"); XX_httplib_fclose(filep);
return;
}
conn->status_code = 206;
@@ -5010,7 +5014,7 @@ static void handle_static_file_request(struct mg_connection *conn, const char *p
} else mg_printf(conn, "\r\n");
if (strcmp(conn->request_info.request_method, "HEAD") != 0) send_file_data(conn, filep, r1, cl);
mg_fclose(filep);
XX_httplib_fclose(filep);
}
@@ -5141,20 +5145,20 @@ long long mg_store_body( struct mg_connection *conn, const char *path ) {
return 0;
}
if (mg_fopen(conn, path, "w", &fi) == 0) return -12;
if (XX_httplib_fopen(conn, path, "w", &fi) == 0) return -12;
ret = mg_read(conn, buf, sizeof(buf));
while (ret > 0) {
n = (int)fwrite(buf, 1, (size_t)ret, fi.fp);
if (n != ret) {
mg_fclose(&fi);
XX_httplib_fclose(&fi);
remove_bad_file(conn, path);
return -13;
}
ret = mg_read(conn, buf, sizeof(buf));
}
/* TODO: mg_fclose should return an error,
/* TODO: XX_httplib_fclose should return an error,
* and every caller should check and handle it. */
if (fclose(fi.fp) != 0) {
remove_bad_file(conn, path);
@@ -5381,7 +5385,7 @@ static int substitute_index_file(struct mg_connection *conn, char *path, size_t
if (filename_vec.len > path_len - (n + 2)) continue;
/* Prepare full path to the index file */
mg_strlcpy(path + n + 1, filename_vec.ptr, filename_vec.len + 1);
XX_httplib_strlcpy(path + n + 1, filename_vec.ptr, filename_vec.len + 1);
/* Does it exist? */
if (XX_httplib_stat(conn, path, &file)) {
@@ -6060,8 +6064,8 @@ static void put_file(struct mg_connection *conn, const char *path) {
}
/* A file should be created or overwritten. */
if (!mg_fopen(conn, path, "wb+", &file) || file.fp == NULL) {
mg_fclose(&file);
if (!XX_httplib_fopen(conn, path, "wb+", &file) || file.fp == NULL) {
XX_httplib_fclose(&file);
XX_httplib_send_http_error(conn, 500, "Error: Can not create file\nfopen(%s): %s", path, strerror(ERRNO));
return;
}
@@ -6078,7 +6082,7 @@ static void put_file(struct mg_connection *conn, const char *path) {
/* forward_body_data failed.
* The error code has already been sent to the client,
* and conn->status_code is already set. */
mg_fclose(&file);
XX_httplib_fclose(&file);
return;
}
@@ -6087,7 +6091,7 @@ static void put_file(struct mg_connection *conn, const char *path) {
send_no_cache_header(conn);
mg_printf(conn, "Date: %s\r\n" "Content-Length: 0\r\n" "Connection: %s\r\n\r\n", date, suggest_connection_header(conn));
mg_fclose(&file);
XX_httplib_fclose(&file);
}
@@ -6189,7 +6193,7 @@ static void do_ssi_include(struct mg_connection *conn, const char *ssi, char *ta
return;
}
if (!mg_fopen(conn, path, "rb", &file)) {
if (!XX_httplib_fopen(conn, path, "rb", &file)) {
mg_cry(conn, "Cannot open SSI #include: [%s]: fopen(%s): %s", tag, path, strerror(ERRNO));
} else {
fclose_on_exec(&file, conn);
@@ -6200,7 +6204,7 @@ static void do_ssi_include(struct mg_connection *conn, const char *ssi, char *ta
} else {
send_file_data(conn, &file, 0, INT64_MAX);
}
mg_fclose(&file);
XX_httplib_fclose(&file);
}
}
@@ -6327,7 +6331,7 @@ static void handle_ssi_file_request(struct mg_connection *conn, const char *path
cors3 = "";
}
if (!mg_fopen(conn, path, "rb", filep)) {
if (!XX_httplib_fopen(conn, path, "rb", filep)) {
/* File exists (precondition for calling this function),
* but can not be opened by the server. */
XX_httplib_send_http_error(conn, 500, "Error: Cannot read file\nfopen(%s): %s", path, strerror(ERRNO));
@@ -6348,7 +6352,7 @@ static void handle_ssi_file_request(struct mg_connection *conn, const char *path
date,
suggest_connection_header(conn));
send_ssi_file(conn, path, filep, 0);
mg_fclose(filep);
XX_httplib_fclose(filep);
}
}
@@ -7254,7 +7258,7 @@ static void redirect_to_https_port(struct mg_connection *conn, int ssl_index) {
if (host_header != NULL) {
char *pos;
mg_strlcpy(host, host_header, hostlen);
XX_httplib_strlcpy(host, host_header, hostlen);
host[hostlen - 1] = '\0';
pos = strchr(host, ':');
if (pos != NULL) *pos = '\0';
@@ -8048,9 +8052,7 @@ int XX_httplib_set_ports_option( struct mg_context *ctx ) {
int portsTotal = 0;
int portsOk = 0;
if (!ctx) {
return 0;
}
if ( ctx == NULL ) return 0;
memset(&so, 0, sizeof(so));
memset(&usa, 0, sizeof(usa));
@@ -8221,80 +8223,3 @@ int XX_httplib_set_ports_option( struct mg_context *ctx ) {
return portsOk;
} /* XX_httplib_set_ports_option */
static const char *header_val(const struct mg_connection *conn, const char *header) {
const char *header_value;
if ((header_value = mg_get_header(conn, header)) == NULL) return "-";
else return header_value;
}
void XX_httplib_log_access( const struct mg_connection *conn ) {
const struct mg_request_info *ri;
struct file fi;
char date[64];
char src_addr[IP_ADDR_STR_LEN];
struct tm *tm;
const char *referer;
const char *user_agent;
char buf[4096];
if (!conn || !conn->ctx) return;
if (conn->ctx->config[ACCESS_LOG_FILE] != NULL) {
if (mg_fopen(conn, conn->ctx->config[ACCESS_LOG_FILE], "a+", &fi) == 0) fi.fp = NULL;
} else fi.fp = NULL;
/* Log is written to a file and/or a callback. If both are not set,
* executing the rest of the function is pointless. */
if ((fi.fp == NULL) && (conn->ctx->callbacks.log_access == NULL)) return;
tm = localtime(&conn->conn_birth_time);
if (tm != NULL) {
strftime(date, sizeof(date), "%d/%b/%Y:%H:%M:%S %z", tm);
} else {
mg_strlcpy(date, "01/Jan/1970:00:00:00 +0000", sizeof(date));
date[sizeof(date) - 1] = '\0';
}
ri = &conn->request_info;
XX_httplib_sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
referer = header_val(conn, "Referer");
user_agent = header_val(conn, "User-Agent");
XX_httplib_snprintf(conn,
NULL, /* Ignore truncation in access log */
buf,
sizeof(buf),
"%s - %s [%s] \"%s %s%s%s HTTP/%s\" %d %" INT64_FMT " %s %s",
src_addr,
(ri->remote_user == NULL) ? "-" : ri->remote_user,
date,
ri->request_method ? ri->request_method : "-",
ri->request_uri ? ri->request_uri : "-",
ri->query_string ? "?" : "",
ri->query_string ? ri->query_string : "",
ri->http_version,
conn->status_code,
conn->num_bytes_sent,
referer,
user_agent);
if (conn->ctx->callbacks.log_access) conn->ctx->callbacks.log_access(conn, buf);
if (fi.fp) {
flockfile(fi.fp);
fprintf(fi.fp, "%s\n", buf);
fflush(fi.fp);
funlockfile(fi.fp);
mg_fclose(&fi);
}
} /* XX_httplib_log_access */