WIP: Allow http upgrades w/o using connect method.
This commit is contained in:
parent
f44d0f387b
commit
70da0c0e3b
@ -235,6 +235,14 @@ Allow 127.0.0.1
|
||||
#
|
||||
#AddHeader "X-My-Header" "Powered by Tinyproxy"
|
||||
|
||||
#
|
||||
# AllowUpgrade: 'Upgrade' and 'Connection' headers are stripped in
|
||||
# non-HTTPS connections per proxy operation in the HTTP RFC. Enabling
|
||||
# fixes unencrypted WebSocket connections but is RFC 2616 non-compliant.
|
||||
# May cause issues with in-connection upgrades to unencrypted HTTP/2.
|
||||
# Don't enable unless you know what you are doing.
|
||||
# AllowUpgrade Yes
|
||||
|
||||
#
|
||||
# ViaProxyName: The "Via" header is required by the HTTP RFC, but using
|
||||
# the real host name is a security concern. If the following directive
|
||||
|
@ -126,6 +126,7 @@ static HANDLE_FUNC (handle_defaulterrorfile);
|
||||
static HANDLE_FUNC (handle_deny);
|
||||
static HANDLE_FUNC (handle_errorfile);
|
||||
static HANDLE_FUNC (handle_addheader);
|
||||
static HANDLE_FUNC (handle_allowupgrade);
|
||||
#ifdef FILTER_ENABLE
|
||||
static HANDLE_FUNC (handle_filter);
|
||||
static HANDLE_FUNC (handle_filtercasesensitive);
|
||||
@ -235,6 +236,7 @@ struct {
|
||||
STDCONF ("basicauth", ALNUM WS ALNUM, handle_basicauth),
|
||||
STDCONF ("errorfile", INT WS STR, handle_errorfile),
|
||||
STDCONF ("addheader", STR WS STR, handle_addheader),
|
||||
STDCONF ("allowupgrade", BOOL, handle_allowupgrade),
|
||||
|
||||
#ifdef FILTER_ENABLE
|
||||
/* filtering */
|
||||
@ -952,6 +954,12 @@ static HANDLE_FUNC (handle_addheader)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HANDLE_FUNC (handle_allowupgrade)
|
||||
{
|
||||
return set_bool_arg (&conf->allowupgrade, line, &match[2]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Log level's strings.
|
||||
|
||||
|
@ -111,6 +111,14 @@ struct config_s {
|
||||
* Extra headers to be added to outgoing HTTP requests.
|
||||
*/
|
||||
vector_t add_headers;
|
||||
|
||||
/*
|
||||
* Allow Upgrade and Connection headers to pass through proxy.
|
||||
* Enables unencrypted WebSocket connections violates RFC
|
||||
* requirements of not passing Connection/Upgrade through a
|
||||
* proxy. Unexpected behavior may result.
|
||||
*/
|
||||
unsigned int allowupgrade; /* boolean */
|
||||
};
|
||||
|
||||
extern int reload_config_file (const char *config_fname, struct config_s *conf,
|
||||
|
58
src/reqs.c
58
src/reqs.c
@ -82,6 +82,30 @@
|
||||
#define CHECK_LWS(header, len) \
|
||||
((len) > 0 && (header[0] == ' ' || header[0] == '\t'))
|
||||
|
||||
static const char *skip_headers_allow_upgrade[] = {
|
||||
"host",
|
||||
"keep-alive",
|
||||
"proxy-connection",
|
||||
"te",
|
||||
"trailers"
|
||||
};
|
||||
static const char *skip_headers_default[] = {
|
||||
"host",
|
||||
"keep-alive",
|
||||
"proxy-connection",
|
||||
"te",
|
||||
"trailers",
|
||||
"upgrade"
|
||||
};
|
||||
|
||||
static const char *connection_headers_allow_upgrade[] = {
|
||||
"proxy-connection"
|
||||
};
|
||||
static const char *connection_headers_default[] = {
|
||||
"connection",
|
||||
"proxy-connection"
|
||||
};
|
||||
|
||||
/*
|
||||
* Read in the first line from the client (the request line for HTTP
|
||||
* connections. The request line is allocated from the heap, but it must
|
||||
@ -281,6 +305,13 @@ establish_http_connection (struct conn_s *connptr, struct request_s *request)
|
||||
request->method, request->path,
|
||||
request->host, portbuff,
|
||||
connptr->upstream_proxy->ua.authstr);
|
||||
} else if (config.allowupgrade) {
|
||||
/* Allow websockets to not be closed after handshake. */
|
||||
return write_message (connptr->server_fd,
|
||||
"%s %s HTTP/1.0\r\n"
|
||||
"Host: %s%s\r\n"
|
||||
request->method, request->path,
|
||||
request->host, portbuff);
|
||||
} else {
|
||||
return write_message (connptr->server_fd,
|
||||
"%s %s HTTP/1.0\r\n"
|
||||
@ -721,16 +752,18 @@ static int get_all_headers (int fd, hashmap_t hashofheaders)
|
||||
*/
|
||||
static int remove_connection_headers (hashmap_t hashofheaders)
|
||||
{
|
||||
static const char *headers[] = {
|
||||
"connection",
|
||||
"proxy-connection"
|
||||
};
|
||||
|
||||
char **headers;
|
||||
char *data;
|
||||
char *ptr;
|
||||
ssize_t len;
|
||||
int i;
|
||||
|
||||
headers = connection_headers_default;
|
||||
|
||||
if (config.allowupgrade) {
|
||||
headers = connection_headers_allow_upgrade;
|
||||
}
|
||||
|
||||
for (i = 0; i != (sizeof (headers) / sizeof (char *)); ++i) {
|
||||
/* Look for the connection header. If it's not found, return. */
|
||||
len =
|
||||
@ -850,20 +883,19 @@ done:
|
||||
static int
|
||||
process_client_headers (struct conn_s *connptr, hashmap_t hashofheaders)
|
||||
{
|
||||
static const char *skipheaders[] = {
|
||||
"host",
|
||||
"keep-alive",
|
||||
"proxy-connection",
|
||||
"te",
|
||||
"trailers",
|
||||
"upgrade"
|
||||
};
|
||||
char **skipheaders;
|
||||
int i;
|
||||
hashmap_iter iter;
|
||||
int ret = 0;
|
||||
|
||||
char *data, *header;
|
||||
|
||||
skipheaders = skip_headers_default;
|
||||
|
||||
if (config.allowupgrade) {
|
||||
skipheaders = skip_headers_allow_upgrade;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't send headers if there's already an error, if the request was
|
||||
* a stats request, or if this was a CONNECT method (unless upstream
|
||||
|
Loading…
Reference in New Issue
Block a user