mirror of
https://github.com/lammertb/libhttp.git
synced 2026-01-27 08:02:47 +03:00
Moved functions to own file
This commit is contained in:
3
Makefile
3
Makefile
@@ -44,10 +44,13 @@ BUILD_DIRS = $(BUILD_DIR) $(BUILD_DIR)/src $(BUILD_DIR)/resources
|
||||
LIB_SOURCES = src/libhttp.c \
|
||||
src/httplib_accept_new_connection.c \
|
||||
src/httplib_check_feature.c \
|
||||
src/httplib_consume_socket.c \
|
||||
src/httplib_free_context.c \
|
||||
src/httplib_get_response_code_text.c \
|
||||
src/httplib_get_system_name.c \
|
||||
src/httplib_master_thread.c \
|
||||
src/httplib_process_new_connection.c \
|
||||
src/httplib_produce_socket.c \
|
||||
src/httplib_start.c \
|
||||
src/httplib_stop.c \
|
||||
src/httplib_version.c \
|
||||
|
||||
87
src/httplib_consume_socket.c
Normal file
87
src/httplib_consume_socket.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* int XX_httplib_consume_socket( struct mg_context *ctx, struct socket *sp, int thread_index );
|
||||
*
|
||||
* The function XX_httplib_consume_socket() takes an accepted socket from the
|
||||
* queue for further processing.
|
||||
*/
|
||||
|
||||
#if defined(ALTERNATIVE_QUEUE)
|
||||
|
||||
int XX_httplib_consume_socket( struct mg_context *ctx, struct socket *sp, int thread_index ) {
|
||||
|
||||
ctx->client_socks[thread_index].in_use = 0;
|
||||
event_wait(ctx->client_wait_events[thread_index]);
|
||||
*sp = ctx->client_socks[thread_index];
|
||||
|
||||
return !ctx->stop_flag;
|
||||
|
||||
} /* XX_httplib_consume_socket */
|
||||
|
||||
#else /* ALTERNATIVE_QUEUE */
|
||||
|
||||
/* Worker threads take accepted socket from the queue */
|
||||
int XX_httplib_consume_socket( struct mg_context *ctx, struct socket *sp, int thread_index ) {
|
||||
|
||||
#define QUEUE_SIZE(ctx) ((int)(ARRAY_SIZE(ctx->queue)))
|
||||
|
||||
(void)thread_index;
|
||||
|
||||
pthread_mutex_lock(&ctx->thread_mutex);
|
||||
|
||||
/* If the queue is empty, wait. We're idle at this point. */
|
||||
while (ctx->sq_head == ctx->sq_tail && ctx->stop_flag == 0) {
|
||||
pthread_cond_wait(&ctx->sq_full, &ctx->thread_mutex);
|
||||
}
|
||||
|
||||
/* If we're stopping, sq_head may be equal to sq_tail. */
|
||||
if (ctx->sq_head > ctx->sq_tail) {
|
||||
/* Copy socket from the queue and increment tail */
|
||||
*sp = ctx->queue[ctx->sq_tail % QUEUE_SIZE(ctx)];
|
||||
ctx->sq_tail++;
|
||||
|
||||
/* Wrap pointers if needed */
|
||||
while (ctx->sq_tail > QUEUE_SIZE(ctx)) {
|
||||
ctx->sq_tail -= QUEUE_SIZE(ctx);
|
||||
ctx->sq_head -= QUEUE_SIZE(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_cond_signal(&ctx->sq_empty);
|
||||
pthread_mutex_unlock(&ctx->thread_mutex);
|
||||
|
||||
return !ctx->stop_flag;
|
||||
#undef QUEUE_SIZE
|
||||
|
||||
} /* XX_httplib_consume_socket */
|
||||
|
||||
#endif /* ALTERNATIVE_QUEUE */
|
||||
145
src/httplib_process_new_connection.c
Normal file
145
src/httplib_process_new_connection.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void XX_httplib_process_new_connection( struct mg_connection *conn );
|
||||
*
|
||||
* The function XX_httplib_process_new_connection() is used to process a new
|
||||
* incoming connection on a socket.
|
||||
*/
|
||||
|
||||
void XX_httplib_process_new_connection( struct mg_connection *conn ) {
|
||||
|
||||
if (conn && conn->ctx) {
|
||||
struct mg_request_info *ri = &conn->request_info;
|
||||
int keep_alive_enabled, keep_alive, discard_len;
|
||||
char ebuf[100];
|
||||
const char *hostend;
|
||||
int reqerr, uri_type;
|
||||
|
||||
keep_alive_enabled = ! strcmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes");
|
||||
|
||||
/* Important: on new connection, reset the receiving buffer. Credit
|
||||
* goes to crule42. */
|
||||
conn->data_len = 0;
|
||||
do {
|
||||
if (!XX_httplib_getreq(conn, ebuf, sizeof(ebuf), &reqerr)) {
|
||||
/* The request sent by the client could not be understood by
|
||||
* the server, or it was incomplete or a timeout. Send an
|
||||
* error message and close the connection. */
|
||||
if (reqerr > 0) {
|
||||
/*assert(ebuf[0] != '\0');*/
|
||||
XX_httplib_send_http_error(conn, reqerr, "%s", ebuf);
|
||||
}
|
||||
} else if (strcmp(ri->http_version, "1.0") && strcmp(ri->http_version, "1.1")) {
|
||||
|
||||
XX_httplib_snprintf(conn, NULL, ebuf, sizeof(ebuf), "Bad HTTP version: [%s]", ri->http_version);
|
||||
XX_httplib_send_http_error(conn, 505, "%s", ebuf);
|
||||
}
|
||||
|
||||
if (ebuf[0] == '\0') {
|
||||
uri_type = XX_httplib_get_uri_type(conn->request_info.request_uri);
|
||||
switch (uri_type) {
|
||||
case 1:
|
||||
/* Asterisk */
|
||||
conn->request_info.local_uri = NULL;
|
||||
break;
|
||||
case 2:
|
||||
/* relative uri */
|
||||
conn->request_info.local_uri =
|
||||
conn->request_info.request_uri;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
/* absolute uri (with/without port) */
|
||||
hostend = XX_httplib_get_rel_url_at_current_server( conn->request_info.request_uri, conn);
|
||||
|
||||
if (hostend) conn->request_info.local_uri = hostend;
|
||||
else conn->request_info.local_uri = NULL;
|
||||
break;
|
||||
default:
|
||||
XX_httplib_snprintf(conn, NULL, ebuf, sizeof(ebuf), "Invalid URI");
|
||||
XX_httplib_send_http_error(conn, 400, "%s", ebuf);
|
||||
conn->request_info.local_uri = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: cleanup uri, local_uri and request_uri */
|
||||
conn->request_info.uri = conn->request_info.local_uri;
|
||||
}
|
||||
|
||||
if (ebuf[0] == '\0') {
|
||||
if (conn->request_info.local_uri) {
|
||||
/* handle request to local server */
|
||||
XX_httplib_handle_request(conn);
|
||||
if (conn->ctx->callbacks.end_request != NULL) conn->ctx->callbacks.end_request(conn, conn->status_code);
|
||||
XX_httplib_log_access(conn);
|
||||
} else {
|
||||
/* TODO: handle non-local request (PROXY) */
|
||||
conn->must_close = 1;
|
||||
}
|
||||
} else conn->must_close = 1;
|
||||
|
||||
if (ri->remote_user != NULL) {
|
||||
XX_httplib_free((void *)ri->remote_user);
|
||||
/* Important! When having connections with and without auth
|
||||
* would cause double free and then crash */
|
||||
ri->remote_user = NULL;
|
||||
}
|
||||
|
||||
/* NOTE(lsm): order is important here. XX_httplib_should_keep_alive() call
|
||||
* is
|
||||
* using parsed request, which will be invalid after memmove's
|
||||
* below.
|
||||
* Therefore, memorize XX_httplib_should_keep_alive() result now for later
|
||||
* use
|
||||
* in loop exit condition. */
|
||||
keep_alive = conn->ctx->stop_flag == 0 && keep_alive_enabled && conn->content_len >= 0 && XX_httplib_should_keep_alive(conn);
|
||||
|
||||
/* Discard all buffered data for this request */
|
||||
discard_len = ((conn->content_len >= 0) && (conn->request_len > 0)
|
||||
&& ((conn->request_len + conn->content_len)
|
||||
< (int64_t)conn->data_len))
|
||||
? (int)(conn->request_len + conn->content_len)
|
||||
: conn->data_len;
|
||||
/*assert(discard_len >= 0);*/
|
||||
if (discard_len < 0) break;
|
||||
conn->data_len -= discard_len;
|
||||
if (conn->data_len > 0) memmove(conn->buf, conn->buf + discard_len, (size_t)conn->data_len);
|
||||
|
||||
/* assert(conn->data_len >= 0); */
|
||||
/* assert(conn->data_len <= conn->buf_size); */
|
||||
|
||||
if ((conn->data_len < 0) || (conn->data_len > conn->buf_size)) break;
|
||||
|
||||
} while (keep_alive);
|
||||
}
|
||||
|
||||
} /* XX_httplib_process_new_connection */
|
||||
86
src/httplib_produce_socket.c
Normal file
86
src/httplib_produce_socket.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void XX_httplib_produce_socket( struct mg_context *ctx, const struct socket *sp );
|
||||
*
|
||||
* The function XX_httplib_produce_socket() is used to produce a socket.
|
||||
*/
|
||||
|
||||
#if defined(ALTERNATIVE_QUEUE)
|
||||
|
||||
void XX_httplib_produce_socket( struct mg_context *ctx, const struct socket *sp ) {
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (;;) {
|
||||
for (i = 0; i < ctx->cfg_worker_threads; i++) {
|
||||
/* find a free worker slot and signal it */
|
||||
if (ctx->client_socks[i].in_use == 0) {
|
||||
ctx->client_socks[i] = *sp;
|
||||
ctx->client_socks[i].in_use = 1;
|
||||
event_signal(ctx->client_wait_events[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* queue is full */
|
||||
mg_sleep(1);
|
||||
}
|
||||
|
||||
} /* XX_httplib_produce_socket */
|
||||
|
||||
#else /* ALTERNATIVE_QUEUE */
|
||||
|
||||
/* Master thread adds accepted socket to a queue */
|
||||
void XX_httplib_produce_socket(struct mg_context *ctx, const struct socket *sp) {
|
||||
|
||||
#define QUEUE_SIZE(ctx) ((int)(ARRAY_SIZE(ctx->queue)))
|
||||
if (!ctx) return;
|
||||
pthread_mutex_lock(&ctx->thread_mutex);
|
||||
|
||||
/* If the queue is full, wait */
|
||||
while (ctx->stop_flag == 0
|
||||
&& ctx->sq_head - ctx->sq_tail >= QUEUE_SIZE(ctx)) {
|
||||
(void)pthread_cond_wait(&ctx->sq_empty, &ctx->thread_mutex);
|
||||
}
|
||||
|
||||
if (ctx->sq_head - ctx->sq_tail < QUEUE_SIZE(ctx)) {
|
||||
/* Copy socket to the queue and increment head */
|
||||
ctx->queue[ctx->sq_head % QUEUE_SIZE(ctx)] = *sp;
|
||||
ctx->sq_head++;
|
||||
}
|
||||
|
||||
pthread_cond_signal(&ctx->sq_full);
|
||||
pthread_mutex_unlock(&ctx->thread_mutex);
|
||||
#undef QUEUE_SIZE
|
||||
|
||||
} /* XX_httplib_produce_socket */
|
||||
|
||||
#endif /* ALTERNATIVE_QUEUE */
|
||||
@@ -405,6 +405,8 @@ typedef int SOCKET;
|
||||
WINDOWS / UNIX include block */
|
||||
|
||||
|
||||
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
|
||||
|
||||
|
||||
#if !defined(MSG_NOSIGNAL)
|
||||
#define MSG_NOSIGNAL (0)
|
||||
@@ -808,10 +810,16 @@ struct mg_connection * XX_httplib_fc( struct mg_context *ctx );
|
||||
void XX_httplib_free_context( struct mg_context *ctx );
|
||||
int XX_httplib_get_option_index( const char *name );
|
||||
uint64_t XX_httplib_get_random( void );
|
||||
const char * XX_httplib_get_rel_url_at_current_server( const char *uri, const struct mg_connection *conn );
|
||||
void XX_httplib_get_system_name( char **sysName );
|
||||
int XX_httplib_get_uri_type( const char *uri );
|
||||
int XX_httplib_getreq( struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err );
|
||||
void XX_httplib_handle_request( struct mg_connection *conn );
|
||||
int XX_httplib_join_thread( pthread_t threadid );
|
||||
void XX_httplib_log_access( const struct mg_connection *conn );
|
||||
void XX_httplib_process_new_connection( struct mg_connection *conn );
|
||||
void XX_httplib_produce_socket( struct mg_context *ctx, const struct socket *sp );
|
||||
void XX_httplib_send_http_error( struct mg_connection *, int, PRINTF_FORMAT_STRING(const char *fmt), ... ) PRINTF_ARGS(3, 4);
|
||||
int XX_httplib_set_acl_option( struct mg_context *ctx );
|
||||
int XX_httplib_set_gpass_option( struct mg_context *ctx );
|
||||
int XX_httplib_set_ports_option( struct mg_context *ctx );
|
||||
@@ -820,6 +828,8 @@ int XX_httplib_set_ssl_option( struct mg_context *ctx );
|
||||
int XX_httplib_set_tcp_nodelay( SOCKET sock, int nodelay_on );
|
||||
void XX_httplib_set_thread_name( const char *name );
|
||||
int XX_httplib_set_uid_option( struct mg_context *ctx );
|
||||
int XX_httplib_should_keep_alive( const struct mg_connection *conn );
|
||||
void XX_httplib_snprintf( const struct mg_connection *conn, int *truncated, char *buf, size_t buflen, PRINTF_FORMAT_STRING(const char *fmt), ... ) PRINTF_ARGS(5, 6);
|
||||
void XX_httplib_sockaddr_to_string(char *buf, size_t len, const union usa *usa);
|
||||
void XX_httplib_ssl_get_client_cert_info( struct mg_connection *conn );
|
||||
int XX_httplib_sslize( struct mg_connection *conn, SSL_CTX *s, int (*func)(SSL *) );
|
||||
|
||||
1248
src/libhttp.c
1248
src/libhttp.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user