mirror of
https://github.com/jamesroberts/fastwsgi.git
synced 2025-12-19 05:09:38 -06:00
Fix bug on send iterable response without keepalive flag (#26)
* Added remote client address into log messages * Fix bug on send iterable response without keepalive flag
This commit is contained in:
@@ -33,6 +33,15 @@ void set_log_level(int level)
|
||||
}
|
||||
|
||||
static const char log_prefix[] = "[FWSGI-X]";
|
||||
static const int log_level_pos = 7;
|
||||
static const char * log_client_addr = NULL;
|
||||
static int log_client_addr_len = 0;
|
||||
|
||||
void set_log_client_addr(const char * addr)
|
||||
{
|
||||
log_client_addr = addr;
|
||||
log_client_addr_len = addr ? strlen(addr) : 0;
|
||||
}
|
||||
|
||||
void logmsg(int level, const char * fmt, ...)
|
||||
{
|
||||
@@ -40,10 +49,18 @@ void logmsg(int level, const char * fmt, ...)
|
||||
if (level <= g_log_level) {
|
||||
va_list argptr;
|
||||
va_start(argptr, fmt);
|
||||
const int prefix_len = sizeof(log_prefix); // include space
|
||||
memcpy(buf, log_prefix, prefix_len); // add prefix
|
||||
buf[prefix_len - 3] = g_log_level_str[level]; // replace X to error type
|
||||
buf[prefix_len - 1] = 0x20; // add space delimiter
|
||||
const int log_prefix_size = sizeof(log_prefix) - 1;
|
||||
memcpy(buf, log_prefix, log_prefix_size);
|
||||
buf[log_level_pos] = g_log_level_str[level]; // replace X to error type
|
||||
buf[log_prefix_size] = 0x20; // add space delimiter
|
||||
int prefix_len = log_prefix_size + 1;
|
||||
if (log_client_addr) {
|
||||
buf[prefix_len++] = '(';
|
||||
memcpy(buf + prefix_len, log_client_addr, log_client_addr_len);
|
||||
prefix_len += log_client_addr_len;
|
||||
buf[prefix_len++] = ')';
|
||||
buf[prefix_len++] = 0x20; // add space delimiter
|
||||
}
|
||||
int maxlen = sizeof(buf) - prefix_len - 8;
|
||||
int len = vsnprintf(buf + prefix_len, maxlen, fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
@@ -30,6 +30,7 @@ typedef enum {
|
||||
|
||||
extern int g_log_level;
|
||||
void set_log_level(int level);
|
||||
void set_log_client_addr(const char * addr);
|
||||
void logmsg(int level, const char * fmt, ...);
|
||||
|
||||
#define LOGMSG(_level_, ...) if (_level_ <= g_log_level) logmsg(_level_, __VA_ARGS__)
|
||||
|
||||
@@ -40,8 +40,9 @@ typedef enum {
|
||||
|
||||
void close_cb(uv_handle_t * handle)
|
||||
{
|
||||
LOGn("disconnected =================================");
|
||||
client_t * client = (client_t *)handle;
|
||||
update_log_prefix(client);
|
||||
LOGn("disconnected =================================");
|
||||
Py_XDECREF(client->request.headers);
|
||||
Py_XDECREF(client->request.wsgi_input_empty);
|
||||
Py_XDECREF(client->request.wsgi_input);
|
||||
@@ -50,6 +51,7 @@ void close_cb(uv_handle_t * handle)
|
||||
reset_response_body(client);
|
||||
free_read_buffer(client, NULL);
|
||||
free(client);
|
||||
update_log_prefix(NULL);
|
||||
}
|
||||
|
||||
void close_connection(client_t * client)
|
||||
@@ -61,6 +63,7 @@ void close_connection(client_t * client)
|
||||
void shutdown_cb(uv_shutdown_t * req, int status)
|
||||
{
|
||||
uv_handle_t * client = (uv_handle_t *)req->handle;
|
||||
update_log_prefix(client);
|
||||
LOGt("%s: status = %d", __func__, status);
|
||||
if (!uv_is_closing(client))
|
||||
uv_close(client, close_cb);
|
||||
@@ -110,6 +113,7 @@ void write_cb(uv_write_t * req, int status)
|
||||
int close_conn = 0;
|
||||
write_req_t * wreq = (write_req_t*)req;
|
||||
client_t * client = (client_t *)wreq->client;
|
||||
update_log_prefix(client);
|
||||
if (status != 0) {
|
||||
LOGe("%s: Write error: %s", __func__, uv_strerror(status));
|
||||
goto fin;
|
||||
@@ -168,7 +172,10 @@ void write_cb(uv_write_t * req, int status)
|
||||
return;
|
||||
|
||||
fin:
|
||||
if (status < 0 || !client->srv->allow_keepalive) {
|
||||
if (status < 0) {
|
||||
close_conn = 1;
|
||||
}
|
||||
if (!client->request.keep_alive || !client->srv->allow_keepalive) {
|
||||
close_conn = 1;
|
||||
}
|
||||
if (!close_conn) {
|
||||
@@ -257,6 +264,7 @@ void read_cb(uv_stream_t * handle, ssize_t nread, const uv_buf_t * buf)
|
||||
int act = CA_OK;
|
||||
client_t * client = (client_t *)handle;
|
||||
llhttp_t * parser = &client->request.parser;
|
||||
update_log_prefix(client);
|
||||
|
||||
if (nread == 0) {
|
||||
LOGd("read_cb: nread = 0");
|
||||
@@ -323,8 +331,6 @@ void read_cb(uv_stream_t * handle, ssize_t nread, const uv_buf_t * buf)
|
||||
}
|
||||
LOGi("Response created! (len = %d+%lld)", client->head.size, client->response.body_preloaded_size);
|
||||
act = stream_write(client);
|
||||
if (!client->request.keep_alive || !client->srv->allow_keepalive)
|
||||
act = CA_SHUTDOWN;
|
||||
|
||||
fin:
|
||||
if (buf->base)
|
||||
@@ -359,9 +365,10 @@ fin:
|
||||
|
||||
void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
|
||||
{
|
||||
client_t * client = (client_t *)handle;
|
||||
update_log_prefix(client);
|
||||
const int read_buffer_size = (int)g_srv.read_buffer_size;
|
||||
LOGt("%s: size = %d (suggested = %d)", __func__, read_buffer_size, (int)suggested_size);
|
||||
client_t * client = (client_t *)handle;
|
||||
buf->base = NULL;
|
||||
buf->len = 0;
|
||||
|
||||
@@ -407,11 +414,12 @@ void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
|
||||
|
||||
void connection_cb(uv_stream_t * server, int status)
|
||||
{
|
||||
update_log_prefix(NULL);
|
||||
if (status < 0) {
|
||||
LOGe("Connection error %s\n", uv_strerror(status));
|
||||
return;
|
||||
}
|
||||
LOGn("new connection =================================");
|
||||
LOGi("new connection =================================");
|
||||
client_t* client = calloc(1, sizeof(client_t) + g_srv.read_buffer_size + 8);
|
||||
client->srv = &g_srv;
|
||||
|
||||
@@ -432,12 +440,19 @@ void connection_cb(uv_stream_t * server, int status)
|
||||
rc = uv_tcp_getpeername((uv_tcp_t*)&client->handle, &sock_addr.addr, &sock_len);
|
||||
LOGw_IF(rc, "%s: cannot get remote addr (err = %d)", __func__, rc);
|
||||
if (rc == 0) {
|
||||
rc = uv_ip_name(&sock_addr.addr, client->remote_addr, sizeof(client->remote_addr));
|
||||
char ip[48];
|
||||
rc = uv_ip_name(&sock_addr.addr, ip, sizeof(ip));
|
||||
LOGw_IF(rc, "%s: cannot get remote IP-addr (err = %d)", __func__, rc);
|
||||
if (rc)
|
||||
client->remote_addr[0] = 0;
|
||||
LOGn_IF(rc == 0, "remote IP-addr: %s", client->remote_addr);
|
||||
ip[0] = 0;
|
||||
if (sock_addr.addr.sa_family == AF_INET6) {
|
||||
sprintf(client->remote_addr, "[%s]:%d", ip, (int)sock_addr.in6.sin6_port);
|
||||
} else {
|
||||
sprintf(client->remote_addr, "%s:%d", ip, (int)sock_addr.in4.sin_port);
|
||||
}
|
||||
}
|
||||
update_log_prefix(client);
|
||||
LOGn("connected =================================");
|
||||
llhttp_init(&client->request.parser, HTTP_REQUEST, &g_srv.parser_settings);
|
||||
client->request.parser.data = client;
|
||||
uv_read_start((uv_stream_t*)&client->handle, alloc_cb, read_cb);
|
||||
@@ -449,6 +464,7 @@ void signal_handler(uv_signal_t * req, int signum)
|
||||
uv_stop(g_srv.loop);
|
||||
uv_signal_stop(req);
|
||||
if (g_srv.hook_sigint == 2) {
|
||||
update_log_prefix(NULL);
|
||||
LOGw("%s: halt process", __func__);
|
||||
exit(0);
|
||||
}
|
||||
@@ -528,6 +544,7 @@ PyObject * init_server(PyObject * Py_UNUSED(self), PyObject * server)
|
||||
{
|
||||
int64_t rv;
|
||||
|
||||
update_log_prefix(NULL);
|
||||
if (g_srv_inited) {
|
||||
PyErr_Format(PyExc_Exception, "server already inited");
|
||||
return PyLong_FromLong(-1000);
|
||||
@@ -565,7 +582,7 @@ PyObject * init_server(PyObject * Py_UNUSED(self), PyObject * server)
|
||||
g_srv.port = (int)port;
|
||||
|
||||
int64_t backlog = get_obj_attr_int(server, "backlog");
|
||||
if (port == LLONG_MIN) {
|
||||
if (backlog == LLONG_MIN) {
|
||||
PyErr_Format(PyExc_ValueError, "Option backlog not defined");
|
||||
return PyLong_FromLong(-1014);
|
||||
}
|
||||
@@ -696,6 +713,7 @@ PyObject * run_nowait(PyObject * self, PyObject * server)
|
||||
PyObject * close_server(PyObject * Py_UNUSED(self), PyObject * Py_UNUSED(server))
|
||||
{
|
||||
if (g_srv_inited) {
|
||||
update_log_prefix(NULL);
|
||||
LOGn("%s", __func__);
|
||||
if (g_srv.signal.signal_cb) {
|
||||
uv_signal_stop(&g_srv.signal);
|
||||
|
||||
@@ -64,7 +64,7 @@ typedef enum {
|
||||
typedef struct {
|
||||
uv_tcp_t handle; // peer connection. Placement strictly at the beginning of the structure!
|
||||
server_t * srv;
|
||||
char remote_addr[48];
|
||||
char remote_addr[64];
|
||||
xbuf_t rbuf[2]; // buffers for reading from socket
|
||||
struct {
|
||||
int load_state;
|
||||
@@ -128,5 +128,10 @@ typedef enum {
|
||||
int build_response(client_t * client, int flags, int status, const void * headers, const void * body, int body_size);
|
||||
PyObject* wsgi_iterator_get_next_chunk(client_t * client, int outpyerr);
|
||||
|
||||
inline void update_log_prefix(void * _client)
|
||||
{
|
||||
client_t * client = (client_t *)_client;
|
||||
set_log_client_addr(client ? client->remote_addr : NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user