mirror of
https://github.com/cesanta/mongoose.git
synced 2025-01-15 10:18:11 +08:00
removed ssl chain file option. restored context param in fc() call
This commit is contained in:
parent
d9f9911d9b
commit
4408083b4d
113
mongoose.c
113
mongoose.c
@ -429,7 +429,7 @@ struct socket {
|
|||||||
enum {
|
enum {
|
||||||
CGI_EXTENSIONS, CGI_ENVIRONMENT, PUT_DELETE_PASSWORDS_FILE, CGI_INTERPRETER,
|
CGI_EXTENSIONS, CGI_ENVIRONMENT, PUT_DELETE_PASSWORDS_FILE, CGI_INTERPRETER,
|
||||||
PROTECT_URI, AUTHENTICATION_DOMAIN, SSI_EXTENSIONS,
|
PROTECT_URI, AUTHENTICATION_DOMAIN, SSI_EXTENSIONS,
|
||||||
ACCESS_LOG_FILE, SSL_CHAIN_FILE, ENABLE_DIRECTORY_LISTING, ERROR_LOG_FILE,
|
ACCESS_LOG_FILE, ENABLE_DIRECTORY_LISTING, ERROR_LOG_FILE,
|
||||||
GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST,
|
GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST,
|
||||||
EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE,
|
EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE,
|
||||||
NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES,
|
NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES,
|
||||||
@ -445,7 +445,6 @@ static const char *config_options[] = {
|
|||||||
"R", "authentication_domain", "mydomain.com",
|
"R", "authentication_domain", "mydomain.com",
|
||||||
"S", "ssi_pattern", "**.shtml$|**.shtm$",
|
"S", "ssi_pattern", "**.shtml$|**.shtm$",
|
||||||
"a", "access_log_file", NULL,
|
"a", "access_log_file", NULL,
|
||||||
"c", "ssl_chain_file", NULL,
|
|
||||||
"d", "enable_directory_listing", "yes",
|
"d", "enable_directory_listing", "yes",
|
||||||
"e", "error_log_file", NULL,
|
"e", "error_log_file", NULL,
|
||||||
"g", "global_passwords_file", NULL,
|
"g", "global_passwords_file", NULL,
|
||||||
@ -597,10 +596,9 @@ static void cry(struct mg_connection *conn, const char *fmt, ...) {
|
|||||||
|
|
||||||
// Return fake connection structure. Used for logging, if connection
|
// Return fake connection structure. Used for logging, if connection
|
||||||
// is not applicable at the moment of logging.
|
// is not applicable at the moment of logging.
|
||||||
static struct mg_connection *fc(void) {
|
static struct mg_connection *fc(struct mg_context *ctx) {
|
||||||
static struct mg_context fake_context;
|
|
||||||
static struct mg_connection fake_connection;
|
static struct mg_connection fake_connection;
|
||||||
fake_connection.ctx = &fake_context;
|
fake_connection.ctx = ctx;
|
||||||
return &fake_connection;
|
return &fake_connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2141,7 +2139,7 @@ static FILE *open_auth_file(struct mg_connection *conn, const char *path) {
|
|||||||
// Use global passwords file
|
// Use global passwords file
|
||||||
fp = mg_fopen(ctx->config[GLOBAL_PASSWORDS_FILE], "r");
|
fp = mg_fopen(ctx->config[GLOBAL_PASSWORDS_FILE], "r");
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
cry(fc(), "fopen(%s): %s",
|
cry(fc(ctx), "fopen(%s): %s",
|
||||||
ctx->config[GLOBAL_PASSWORDS_FILE], strerror(ERRNO));
|
ctx->config[GLOBAL_PASSWORDS_FILE], strerror(ERRNO));
|
||||||
} else if (!mg_stat(path, &st) && st.is_directory) {
|
} else if (!mg_stat(path, &st) && st.is_directory) {
|
||||||
(void) mg_snprintf(conn, name, sizeof(name), "%s%c%s",
|
(void) mg_snprintf(conn, name, sizeof(name), "%s%c%s",
|
||||||
@ -3131,7 +3129,7 @@ static void handle_cgi_request(struct mg_connection *conn, const char *prog) {
|
|||||||
// Do not send anything back to client, until we buffer in all
|
// Do not send anything back to client, until we buffer in all
|
||||||
// HTTP headers.
|
// HTTP headers.
|
||||||
data_len = 0;
|
data_len = 0;
|
||||||
headers_len = read_request(out, fc(), buf, sizeof(buf), &data_len);
|
headers_len = read_request(out, conn, buf, sizeof(buf), &data_len);
|
||||||
if (headers_len <= 0) {
|
if (headers_len <= 0) {
|
||||||
send_http_error(conn, 500, http_500_error,
|
send_http_error(conn, 500, http_500_error,
|
||||||
"CGI program sent malformed or too big (>%u bytes) "
|
"CGI program sent malformed or too big (>%u bytes) "
|
||||||
@ -3610,12 +3608,12 @@ static int set_ports_option(struct mg_context *ctx) {
|
|||||||
|
|
||||||
while (success && (list = next_option(list, &vec, NULL)) != NULL) {
|
while (success && (list = next_option(list, &vec, NULL)) != NULL) {
|
||||||
if (!parse_port_string(&vec, &so)) {
|
if (!parse_port_string(&vec, &so)) {
|
||||||
cry(fc(), "%s: %.*s: invalid port spec. Expecting list of: %s",
|
cry(fc(ctx), "%s: %.*s: invalid port spec. Expecting list of: %s",
|
||||||
__func__, (int) vec.len, vec.ptr, "[IP_ADDRESS:]PORT[s|p]");
|
__func__, (int) vec.len, vec.ptr, "[IP_ADDRESS:]PORT[s|p]");
|
||||||
success = 0;
|
success = 0;
|
||||||
} else if (so.is_ssl &&
|
} else if (so.is_ssl &&
|
||||||
(ctx->ssl_ctx == NULL || ctx->config[SSL_CERTIFICATE] == NULL)) {
|
(ctx->ssl_ctx == NULL || ctx->config[SSL_CERTIFICATE] == NULL)) {
|
||||||
cry(fc(), "Cannot add SSL socket, is -ssl_certificate option set?");
|
cry(fc(ctx), "Cannot add SSL socket, is -ssl_certificate option set?");
|
||||||
success = 0;
|
success = 0;
|
||||||
} else if ((sock = socket(so.lsa.sa.sa_family, SOCK_STREAM, 6)) ==
|
} else if ((sock = socket(so.lsa.sa.sa_family, SOCK_STREAM, 6)) ==
|
||||||
INVALID_SOCKET ||
|
INVALID_SOCKET ||
|
||||||
@ -3637,14 +3635,14 @@ static int set_ports_option(struct mg_context *ctx) {
|
|||||||
bind(sock, &so.lsa.sa, sizeof(so.lsa)) != 0 ||
|
bind(sock, &so.lsa.sa, sizeof(so.lsa)) != 0 ||
|
||||||
listen(sock, SOMAXCONN) != 0) {
|
listen(sock, SOMAXCONN) != 0) {
|
||||||
closesocket(sock);
|
closesocket(sock);
|
||||||
cry(fc(), "%s: cannot bind to %.*s: %s", __func__,
|
cry(fc(ctx), "%s: cannot bind to %.*s: %s", __func__,
|
||||||
vec.len, vec.ptr, strerror(ERRNO));
|
vec.len, vec.ptr, strerror(ERRNO));
|
||||||
success = 0;
|
success = 0;
|
||||||
} else if ((listener = (struct socket *)
|
} else if ((listener = (struct socket *)
|
||||||
calloc(1, sizeof(*listener))) == NULL) {
|
calloc(1, sizeof(*listener))) == NULL) {
|
||||||
// NOTE(lsm): order is important: call cry before closesocket(),
|
// NOTE(lsm): order is important: call cry before closesocket(),
|
||||||
// cause closesocket() alters the errno.
|
// cause closesocket() alters the errno.
|
||||||
cry(fc(), "%s: %s", __func__, strerror(ERRNO));
|
cry(fc(ctx), "%s: %s", __func__, strerror(ERRNO));
|
||||||
closesocket(sock);
|
closesocket(sock);
|
||||||
success = 0;
|
success = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -3732,18 +3730,18 @@ static int check_acl(struct mg_context *ctx, const union usa *usa) {
|
|||||||
mask = 32;
|
mask = 32;
|
||||||
|
|
||||||
if (sscanf(vec.ptr, "%c%d.%d.%d.%d%n", &flag, &a, &b, &c, &d, &n) != 5) {
|
if (sscanf(vec.ptr, "%c%d.%d.%d.%d%n", &flag, &a, &b, &c, &d, &n) != 5) {
|
||||||
cry(fc(), "%s: subnet must be [+|-]x.x.x.x[/x]", __func__);
|
cry(fc(ctx), "%s: subnet must be [+|-]x.x.x.x[/x]", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
} else if (flag != '+' && flag != '-') {
|
} else if (flag != '+' && flag != '-') {
|
||||||
cry(fc(), "%s: flag must be + or -: [%s]", __func__, vec.ptr);
|
cry(fc(ctx), "%s: flag must be + or -: [%s]", __func__, vec.ptr);
|
||||||
return -1;
|
return -1;
|
||||||
} else if (!isbyte(a)||!isbyte(b)||!isbyte(c)||!isbyte(d)) {
|
} else if (!isbyte(a)||!isbyte(b)||!isbyte(c)||!isbyte(d)) {
|
||||||
cry(fc(), "%s: bad ip address: [%s]", __func__, vec.ptr);
|
cry(fc(ctx), "%s: bad ip address: [%s]", __func__, vec.ptr);
|
||||||
return -1;
|
return -1;
|
||||||
} else if (sscanf(vec.ptr + n, "/%d", &mask) == 0) {
|
} else if (sscanf(vec.ptr + n, "/%d", &mask) == 0) {
|
||||||
// Do nothing, no mask specified
|
// Do nothing, no mask specified
|
||||||
} else if (mask < 0 || mask > 32) {
|
} else if (mask < 0 || mask > 32) {
|
||||||
cry(fc(), "%s: bad subnet mask: %d [%s]", __func__, n, vec.ptr);
|
cry(fc(ctx), "%s: bad subnet mask: %d [%s]", __func__, n, vec.ptr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3775,11 +3773,11 @@ static int set_uid_option(struct mg_context *ctx) {
|
|||||||
success = 1;
|
success = 1;
|
||||||
} else {
|
} else {
|
||||||
if ((pw = getpwnam(uid)) == NULL) {
|
if ((pw = getpwnam(uid)) == NULL) {
|
||||||
cry(fc(), "%s: unknown user [%s]", __func__, uid);
|
cry(fc(ctx), "%s: unknown user [%s]", __func__, uid);
|
||||||
} else if (setgid(pw->pw_gid) == -1) {
|
} else if (setgid(pw->pw_gid) == -1) {
|
||||||
cry(fc(), "%s: setgid(%s): %s", __func__, uid, strerror(errno));
|
cry(fc(ctx), "%s: setgid(%s): %s", __func__, uid, strerror(errno));
|
||||||
} else if (setuid(pw->pw_uid) == -1) {
|
} else if (setuid(pw->pw_uid) == -1) {
|
||||||
cry(fc(), "%s: setuid(%s): %s", __func__, uid, strerror(errno));
|
cry(fc(ctx), "%s: setuid(%s): %s", __func__, uid, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
success = 1;
|
success = 1;
|
||||||
}
|
}
|
||||||
@ -3816,13 +3814,14 @@ static unsigned long ssl_id_callback(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(NO_SSL_DL)
|
#if !defined(NO_SSL_DL)
|
||||||
static int load_dll(const char *dll_name, struct ssl_func *sw) {
|
static int load_dll(struct mg_context *ctx, const char *dll_name,
|
||||||
|
struct ssl_func *sw) {
|
||||||
union {void *p; void (*fp)(void);} u;
|
union {void *p; void (*fp)(void);} u;
|
||||||
void *dll_handle;
|
void *dll_handle;
|
||||||
struct ssl_func *fp;
|
struct ssl_func *fp;
|
||||||
|
|
||||||
if ((dll_handle = dlopen(dll_name, RTLD_LAZY)) == NULL) {
|
if ((dll_handle = dlopen(dll_name, RTLD_LAZY)) == NULL) {
|
||||||
cry(fc(), "%s: cannot load %s", __func__, dll_name);
|
cry(fc(ctx), "%s: cannot load %s", __func__, dll_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3836,7 +3835,7 @@ static int load_dll(const char *dll_name, struct ssl_func *sw) {
|
|||||||
u.p = dlsym(dll_handle, fp->name);
|
u.p = dlsym(dll_handle, fp->name);
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
if (u.fp == NULL) {
|
if (u.fp == NULL) {
|
||||||
cry(fc(), "%s: %s: cannot find %s", __func__, dll_name, fp->name);
|
cry(fc(ctx), "%s: %s: cannot find %s", __func__, dll_name, fp->name);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
fp->ptr = u.fp;
|
fp->ptr = u.fp;
|
||||||
@ -3849,13 +3848,13 @@ static int load_dll(const char *dll_name, struct ssl_func *sw) {
|
|||||||
|
|
||||||
// Dynamically load SSL library. Set up ctx->ssl_ctx pointer.
|
// Dynamically load SSL library. Set up ctx->ssl_ctx pointer.
|
||||||
static int set_ssl_option(struct mg_context *ctx) {
|
static int set_ssl_option(struct mg_context *ctx) {
|
||||||
struct mg_request_info request_info;
|
static struct mg_request_info fake_request_info;
|
||||||
int i, size;
|
int i, size;
|
||||||
const char *pem = ctx->config[SSL_CERTIFICATE];
|
const char *pem = ctx->config[SSL_CERTIFICATE];
|
||||||
const char *chain = ctx->config[SSL_CHAIN_FILE];
|
|
||||||
|
|
||||||
#if !defined(NO_SSL_DL)
|
#if !defined(NO_SSL_DL)
|
||||||
if (!load_dll(SSL_LIB, ssl_sw) || !load_dll(CRYPTO_LIB, crypto_sw)) {
|
if (!load_dll(ctx, SSL_LIB, ssl_sw) ||
|
||||||
|
!load_dll(ctx, CRYPTO_LIB, crypto_sw)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif // NO_SSL_DL
|
#endif // NO_SSL_DL
|
||||||
@ -3865,38 +3864,32 @@ static int set_ssl_option(struct mg_context *ctx) {
|
|||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
|
|
||||||
if ((ctx->client_ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) {
|
if ((ctx->client_ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) {
|
||||||
cry(fc(), "SSL_CTX_new error: %s", ssl_error());
|
cry(fc(ctx), "SSL_CTX_new (client) error: %s", ssl_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) {
|
if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) {
|
||||||
cry(fc(), "SSL_CTX_new error: %s", ssl_error());
|
cry(fc(ctx), "SSL_CTX_new (server) error: %s", ssl_error());
|
||||||
} else if (ctx->user_callback != NULL) {
|
return 0;
|
||||||
memset(&request_info, 0, sizeof(request_info));
|
}
|
||||||
request_info.user_data = ctx->user_data;
|
|
||||||
|
if (ctx->user_callback != NULL) {
|
||||||
|
fake_request_info.user_data = ctx->user_data;
|
||||||
ctx->user_callback(MG_INIT_SSL, (struct mg_connection *) ctx->ssl_ctx);
|
ctx->user_callback(MG_INIT_SSL, (struct mg_connection *) ctx->ssl_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->ssl_ctx != NULL && pem != NULL &&
|
if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, pem, SSL_FILETYPE_PEM) == 0 ||
|
||||||
SSL_CTX_use_certificate_file(ctx->ssl_ctx, pem, SSL_FILETYPE_PEM) == 0) {
|
|
||||||
cry(fc(), "%s: cannot open %s: %s", __func__, pem, ssl_error());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (ctx->ssl_ctx != NULL && pem != NULL &&
|
|
||||||
SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, pem, SSL_FILETYPE_PEM) == 0) {
|
SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, pem, SSL_FILETYPE_PEM) == 0) {
|
||||||
cry(fc(), "%s: cannot open %s: %s", __func__, pem, ssl_error());
|
cry(fc(ctx), "%s: cannot open %s: %s", __func__, pem, ssl_error());
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (ctx->ssl_ctx != NULL && chain != NULL &&
|
|
||||||
SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, chain) == 0) {
|
|
||||||
cry(fc(), "%s: cannot open %s: %s", __func__, chain, ssl_error());
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(void) SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, pem);
|
||||||
|
|
||||||
// Initialize locking callbacks, needed for thread safety.
|
// Initialize locking callbacks, needed for thread safety.
|
||||||
// http://www.openssl.org/support/faq.html#PROG1
|
// http://www.openssl.org/support/faq.html#PROG1
|
||||||
size = sizeof(pthread_mutex_t) * CRYPTO_num_locks();
|
size = sizeof(pthread_mutex_t) * CRYPTO_num_locks();
|
||||||
if ((ssl_mutexes = (pthread_mutex_t *) malloc((size_t)size)) == NULL) {
|
if ((ssl_mutexes = (pthread_mutex_t *) malloc((size_t)size)) == NULL) {
|
||||||
cry(fc(), "%s: cannot allocate mutexes: %s", __func__, ssl_error());
|
cry(fc(ctx), "%s: cannot allocate mutexes: %s", __func__, ssl_error());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3994,22 +3987,22 @@ struct mg_connection *mg_connect(struct mg_context *ctx,
|
|||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
if (use_ssl && (ctx == NULL || ctx->client_ssl_ctx == NULL)) {
|
if (use_ssl && (ctx == NULL || ctx->client_ssl_ctx == NULL)) {
|
||||||
cry(fc(), "%s: SSL is not initialized", __func__);
|
cry(fc(ctx), "%s: SSL is not initialized", __func__);
|
||||||
} else if ((he = gethostbyname(host)) == NULL) {
|
} else if ((he = gethostbyname(host)) == NULL) {
|
||||||
cry(fc(), "%s: gethostbyname(%s): %s", __func__, host, strerror(ERRNO));
|
cry(fc(ctx), "%s: gethostbyname(%s): %s", __func__, host, strerror(ERRNO));
|
||||||
} else if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
|
} else if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
|
||||||
cry(fc(), "%s: socket: %s", __func__, strerror(ERRNO));
|
cry(fc(ctx), "%s: socket: %s", __func__, strerror(ERRNO));
|
||||||
} else {
|
} else {
|
||||||
sin.sin_family = AF_INET;
|
sin.sin_family = AF_INET;
|
||||||
sin.sin_port = htons((uint16_t) port);
|
sin.sin_port = htons((uint16_t) port);
|
||||||
sin.sin_addr = * (struct in_addr *) he->h_addr_list[0];
|
sin.sin_addr = * (struct in_addr *) he->h_addr_list[0];
|
||||||
if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) != 0) {
|
if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) != 0) {
|
||||||
cry(fc(), "%s: connect(%s:%d): %s", __func__, host, port,
|
cry(fc(ctx), "%s: connect(%s:%d): %s", __func__, host, port,
|
||||||
strerror(ERRNO));
|
strerror(ERRNO));
|
||||||
closesocket(sock);
|
closesocket(sock);
|
||||||
} else if ((newconn = (struct mg_connection *)
|
} else if ((newconn = (struct mg_connection *)
|
||||||
calloc(1, sizeof(*newconn))) == NULL) {
|
calloc(1, sizeof(*newconn))) == NULL) {
|
||||||
cry(fc(), "%s: calloc: %s", __func__, strerror(ERRNO));
|
cry(fc(ctx), "%s: calloc: %s", __func__, strerror(ERRNO));
|
||||||
closesocket(sock);
|
closesocket(sock);
|
||||||
} else {
|
} else {
|
||||||
newconn->ctx = ctx;
|
newconn->ctx = ctx;
|
||||||
@ -4036,29 +4029,29 @@ FILE *mg_fetch(struct mg_context *ctx, const char *url, const char *path,
|
|||||||
} else if (sscanf(url, "%9[htps]://%1024[^/]/%n", proto, host, &n) == 2) {
|
} else if (sscanf(url, "%9[htps]://%1024[^/]/%n", proto, host, &n) == 2) {
|
||||||
port = mg_strcasecmp(proto, "https") == 0 ? 443 : 80;
|
port = mg_strcasecmp(proto, "https") == 0 ? 443 : 80;
|
||||||
} else {
|
} else {
|
||||||
cry(fc(), "%s: invalid URL: [%s]", __func__, url);
|
cry(fc(ctx), "%s: invalid URL: [%s]", __func__, url);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((newconn = mg_connect(ctx, host, port,
|
if ((newconn = mg_connect(ctx, host, port,
|
||||||
!strcmp(proto, "https"))) == NULL) {
|
!strcmp(proto, "https"))) == NULL) {
|
||||||
cry(fc(), "%s: mg_connect(%s): %s", __func__, url, strerror(ERRNO));
|
cry(fc(ctx), "%s: mg_connect(%s): %s", __func__, url, strerror(ERRNO));
|
||||||
} else {
|
} else {
|
||||||
mg_printf(newconn, "GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n", url + n, host);
|
mg_printf(newconn, "GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n", url + n, host);
|
||||||
data_length = 0;
|
data_length = 0;
|
||||||
req_length = read_request(NULL, newconn, buf, buf_len, &data_length);
|
req_length = read_request(NULL, newconn, buf, buf_len, &data_length);
|
||||||
if (req_length <= 0) {
|
if (req_length <= 0) {
|
||||||
cry(fc(), "%s(%s): invalid HTTP reply", __func__, url);
|
cry(fc(ctx), "%s(%s): invalid HTTP reply", __func__, url);
|
||||||
} else if (parse_http_response(buf, req_length, ri) <= 0) {
|
} else if (parse_http_response(buf, req_length, ri) <= 0) {
|
||||||
cry(fc(), "%s(%s): cannot parse HTTP headers", __func__, url);
|
cry(fc(ctx), "%s(%s): cannot parse HTTP headers", __func__, url);
|
||||||
} else if ((fp = fopen(path, "w+b")) == NULL) {
|
} else if ((fp = fopen(path, "w+b")) == NULL) {
|
||||||
cry(fc(), "%s: fopen(%s): %s", __func__, path, strerror(ERRNO));
|
cry(fc(ctx), "%s: fopen(%s): %s", __func__, path, strerror(ERRNO));
|
||||||
} else {
|
} else {
|
||||||
// Write chunk of data that may be in the user's buffer
|
// Write chunk of data that may be in the user's buffer
|
||||||
data_length -= req_length;
|
data_length -= req_length;
|
||||||
if (data_length > 0 &&
|
if (data_length > 0 &&
|
||||||
fwrite(buf + req_length, 1, data_length, fp) != (size_t) data_length) {
|
fwrite(buf + req_length, 1, data_length, fp) != (size_t) data_length) {
|
||||||
cry(fc(), "%s: fwrite(%s): %s", __func__, path, strerror(ERRNO));
|
cry(fc(ctx), "%s: fwrite(%s): %s", __func__, path, strerror(ERRNO));
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
}
|
}
|
||||||
@ -4066,7 +4059,7 @@ FILE *mg_fetch(struct mg_context *ctx, const char *url, const char *path,
|
|||||||
// mg_read() cause we didn't set newconn->content_len properly.
|
// mg_read() cause we didn't set newconn->content_len properly.
|
||||||
while (fp && (data_length = pull(0, newconn, buf2, sizeof(buf2))) > 0) {
|
while (fp && (data_length = pull(0, newconn, buf2, sizeof(buf2))) > 0) {
|
||||||
if (fwrite(buf2, 1, data_length, fp) != (size_t) data_length) {
|
if (fwrite(buf2, 1, data_length, fp) != (size_t) data_length) {
|
||||||
cry(fc(), "%s: fwrite(%s): %s", __func__, path, strerror(ERRNO));
|
cry(fc(ctx), "%s: fwrite(%s): %s", __func__, path, strerror(ERRNO));
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
break;
|
break;
|
||||||
@ -4185,7 +4178,7 @@ static void worker_thread(struct mg_context *ctx) {
|
|||||||
|
|
||||||
conn = (struct mg_connection *) calloc(1, sizeof(*conn) + MAX_REQUEST_SIZE);
|
conn = (struct mg_connection *) calloc(1, sizeof(*conn) + MAX_REQUEST_SIZE);
|
||||||
if (conn == NULL) {
|
if (conn == NULL) {
|
||||||
cry(fc(), "%s", "Cannot create new connection struct, OOM");
|
cry(fc(ctx), "%s", "Cannot create new connection struct, OOM");
|
||||||
} else {
|
} else {
|
||||||
conn->buf_size = MAX_REQUEST_SIZE;
|
conn->buf_size = MAX_REQUEST_SIZE;
|
||||||
conn->buf = (char *) (conn + 1);
|
conn->buf = (char *) (conn + 1);
|
||||||
@ -4267,7 +4260,7 @@ static void accept_new_connection(const struct socket *listener,
|
|||||||
produce_socket(ctx, &accepted);
|
produce_socket(ctx, &accepted);
|
||||||
} else {
|
} else {
|
||||||
sockaddr_to_string(src_addr, sizeof(src_addr), &accepted.rsa);
|
sockaddr_to_string(src_addr, sizeof(src_addr), &accepted.rsa);
|
||||||
cry(fc(), "%s: %s is not allowed to connect", __func__, src_addr);
|
cry(fc(ctx), "%s: %s is not allowed to connect", __func__, src_addr);
|
||||||
(void) closesocket(accepted.sock);
|
(void) closesocket(accepted.sock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4411,16 +4404,16 @@ struct mg_context *mg_start(mg_callback_t user_callback, void *user_data,
|
|||||||
|
|
||||||
while (options && (name = *options++) != NULL) {
|
while (options && (name = *options++) != NULL) {
|
||||||
if ((i = get_option_index(name)) == -1) {
|
if ((i = get_option_index(name)) == -1) {
|
||||||
cry(fc(), "Invalid option: %s", name);
|
cry(fc(ctx), "Invalid option: %s", name);
|
||||||
free_context(ctx);
|
free_context(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if ((value = *options++) == NULL) {
|
} else if ((value = *options++) == NULL) {
|
||||||
cry(fc(), "%s: option value cannot be NULL", name);
|
cry(fc(ctx), "%s: option value cannot be NULL", name);
|
||||||
free_context(ctx);
|
free_context(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (ctx->config[i] != NULL) {
|
if (ctx->config[i] != NULL) {
|
||||||
cry(fc(), "warning: %s: duplicate option", name);
|
cry(fc(ctx), "warning: %s: duplicate option", name);
|
||||||
}
|
}
|
||||||
ctx->config[i] = mg_strdup(value);
|
ctx->config[i] = mg_strdup(value);
|
||||||
DEBUG_TRACE(("[%s] -> [%s]", name, value));
|
DEBUG_TRACE(("[%s] -> [%s]", name, value));
|
||||||
@ -4471,7 +4464,7 @@ struct mg_context *mg_start(mg_callback_t user_callback, void *user_data,
|
|||||||
// Start worker threads
|
// Start worker threads
|
||||||
for (i = 0; i < atoi(ctx->config[NUM_THREADS]); i++) {
|
for (i = 0; i < atoi(ctx->config[NUM_THREADS]); i++) {
|
||||||
if (mg_start_thread((mg_thread_func_t) worker_thread, ctx) != 0) {
|
if (mg_start_thread((mg_thread_func_t) worker_thread, ctx) != 0) {
|
||||||
cry(fc(), "Cannot start worker thread: %d", ERRNO);
|
cry(fc(ctx), "Cannot start worker thread: %d", ERRNO);
|
||||||
} else {
|
} else {
|
||||||
ctx->num_threads++;
|
ctx->num_threads++;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user