mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-23 00:00:06 +01:00

This allows the client stuff to understand that addresses beginning with '+' represent unix sockets. If the first character after the '+' is '@', it understands that the '@' should be read as '\0', in order to use Linux "abstract namespace" sockets. Further the lws_parse_uri() helper is extended to understand the convention that an address starting with + is a unix socket, and treats the socket path as delimited by ':', eg http://+/var/run/mysocket:/my/path HTTP Proxy is updated to allow mounts to these unix socket paths. Proxy connections go out on h1, but are dynamically translated to h1 or h2 on the incoming side. Proxy usage of libhubbub is separated out... LWS_WITH_HTTP_PROXY is on by default, and LWS_WITH_HUBBUB is off by default.
191 lines
4.9 KiB
C
191 lines
4.9 KiB
C
/*
|
|
* libwebsockets - server access log handling
|
|
*
|
|
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation:
|
|
* version 2.1 of the License.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "core/private.h"
|
|
|
|
/*
|
|
* Produce Apache-compatible log string for wsi, like this:
|
|
*
|
|
* 2.31.234.19 - - [27/Mar/2016:03:22:44 +0800]
|
|
* "GET /aep-screen.png HTTP/1.1"
|
|
* 200 152987 "https://libwebsockets.org/index.html"
|
|
* "Mozilla/5.0 (Macint... Chrome/49.0.2623.87 Safari/537.36"
|
|
*
|
|
*/
|
|
|
|
extern const char * const method_names[];
|
|
|
|
static const char * const hver[] = {
|
|
"HTTP/1.0", "HTTP/1.1", "HTTP/2"
|
|
};
|
|
|
|
void
|
|
lws_prepare_access_log_info(struct lws *wsi, char *uri_ptr, int uri_len, int meth)
|
|
{
|
|
#ifdef LWS_WITH_IPV6
|
|
char ads[INET6_ADDRSTRLEN];
|
|
#else
|
|
char ads[INET_ADDRSTRLEN];
|
|
#endif
|
|
char da[64], uri[256];
|
|
const char *pa, *me;
|
|
struct tm *tmp;
|
|
time_t t = time(NULL);
|
|
int l = 256, m;
|
|
|
|
if (!wsi->vhost)
|
|
return;
|
|
|
|
/* only worry about preparing it if we store it */
|
|
if (wsi->vhost->log_fd == (int)LWS_INVALID_FILE)
|
|
return;
|
|
|
|
if (wsi->access_log_pending)
|
|
lws_access_log(wsi);
|
|
|
|
wsi->http.access_log.header_log = lws_malloc(l, "access log");
|
|
if (wsi->http.access_log.header_log) {
|
|
|
|
tmp = localtime(&t);
|
|
if (tmp)
|
|
strftime(da, sizeof(da), "%d/%b/%Y:%H:%M:%S %z", tmp);
|
|
else
|
|
strcpy(da, "01/Jan/1970:00:00:00 +0000");
|
|
|
|
pa = lws_get_peer_simple(wsi, ads, sizeof(ads));
|
|
if (!pa)
|
|
pa = "(unknown)";
|
|
|
|
if (wsi->http2_substream)
|
|
me = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_METHOD);
|
|
else
|
|
me = method_names[meth];
|
|
if (!me)
|
|
me = "(null)";
|
|
|
|
m = uri_len;
|
|
if (m > (int)sizeof(uri) - 1)
|
|
m = sizeof(uri) - 1;
|
|
|
|
strncpy(uri, uri_ptr, m);
|
|
uri[m] = '\0';
|
|
|
|
lws_snprintf(wsi->http.access_log.header_log, l,
|
|
"%s - - [%s] \"%s %s %s\"",
|
|
pa, da, me, uri,
|
|
hver[wsi->http.request_version]);
|
|
|
|
//lwsl_notice("%s\n", wsi->http.access_log.header_log);
|
|
|
|
l = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_USER_AGENT);
|
|
if (l) {
|
|
wsi->http.access_log.user_agent = lws_malloc(l + 2, "access log");
|
|
if (!wsi->http.access_log.user_agent) {
|
|
lwsl_err("OOM getting user agent\n");
|
|
lws_free_set_NULL(wsi->http.access_log.header_log);
|
|
return;
|
|
}
|
|
|
|
lws_hdr_copy(wsi, wsi->http.access_log.user_agent,
|
|
l + 1, WSI_TOKEN_HTTP_USER_AGENT);
|
|
|
|
for (m = 0; m < l; m++)
|
|
if (wsi->http.access_log.user_agent[m] == '\"')
|
|
wsi->http.access_log.user_agent[m] = '\'';
|
|
}
|
|
l = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_REFERER);
|
|
if (l) {
|
|
wsi->http.access_log.referrer = lws_malloc(l + 2, "referrer");
|
|
if (!wsi->http.access_log.referrer) {
|
|
lwsl_err("OOM getting user agent\n");
|
|
lws_free_set_NULL(wsi->http.access_log.user_agent);
|
|
lws_free_set_NULL(wsi->http.access_log.header_log);
|
|
return;
|
|
}
|
|
lws_hdr_copy(wsi, wsi->http.access_log.referrer,
|
|
l + 1, WSI_TOKEN_HTTP_REFERER);
|
|
|
|
for (m = 0; m < l; m++)
|
|
if (wsi->http.access_log.referrer[m] == '\"')
|
|
wsi->http.access_log.referrer[m] = '\'';
|
|
}
|
|
wsi->access_log_pending = 1;
|
|
}
|
|
}
|
|
|
|
|
|
int
|
|
lws_access_log(struct lws *wsi)
|
|
{
|
|
char *p = wsi->http.access_log.user_agent, ass[512],
|
|
*p1 = wsi->http.access_log.referrer;
|
|
int l;
|
|
|
|
if (!wsi->vhost)
|
|
return 0;
|
|
|
|
if (wsi->vhost->log_fd == (int)LWS_INVALID_FILE)
|
|
return 0;
|
|
|
|
if (!wsi->access_log_pending)
|
|
return 0;
|
|
|
|
if (!wsi->http.access_log.header_log)
|
|
return 0;
|
|
|
|
if (!p)
|
|
p = "";
|
|
|
|
if (!p1)
|
|
p1 = "";
|
|
|
|
/*
|
|
* We do this in two parts to restrict an oversize referrer such that
|
|
* we will always have space left to append an empty useragent, while
|
|
* maintaining the structure of the log text
|
|
*/
|
|
l = lws_snprintf(ass, sizeof(ass) - 7, "%s %d %lu \"%s",
|
|
wsi->http.access_log.header_log,
|
|
wsi->http.access_log.response, wsi->http.access_log.sent, p1);
|
|
if (strlen(p) > sizeof(ass) - 6 - l)
|
|
p[sizeof(ass) - 6 - l] = '\0';
|
|
l += lws_snprintf(ass + l, sizeof(ass) - 1 - l, "\" \"%s\"\n", p);
|
|
|
|
if (write(wsi->vhost->log_fd, ass, l) != l)
|
|
lwsl_err("Failed to write log\n");
|
|
|
|
if (wsi->http.access_log.header_log) {
|
|
lws_free(wsi->http.access_log.header_log);
|
|
wsi->http.access_log.header_log = NULL;
|
|
}
|
|
if (wsi->http.access_log.user_agent) {
|
|
lws_free(wsi->http.access_log.user_agent);
|
|
wsi->http.access_log.user_agent = NULL;
|
|
}
|
|
if (wsi->http.access_log.referrer) {
|
|
lws_free(wsi->http.access_log.referrer);
|
|
wsi->http.access_log.referrer = NULL;
|
|
}
|
|
wsi->access_log_pending = 0;
|
|
|
|
return 0;
|
|
}
|
|
|