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"
|
#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
|
# ViaProxyName: The "Via" header is required by the HTTP RFC, but using
|
||||||
# the real host name is a security concern. If the following directive
|
# 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_deny);
|
||||||
static HANDLE_FUNC (handle_errorfile);
|
static HANDLE_FUNC (handle_errorfile);
|
||||||
static HANDLE_FUNC (handle_addheader);
|
static HANDLE_FUNC (handle_addheader);
|
||||||
|
static HANDLE_FUNC (handle_allowupgrade);
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
static HANDLE_FUNC (handle_filter);
|
static HANDLE_FUNC (handle_filter);
|
||||||
static HANDLE_FUNC (handle_filtercasesensitive);
|
static HANDLE_FUNC (handle_filtercasesensitive);
|
||||||
@ -235,6 +236,7 @@ struct {
|
|||||||
STDCONF ("basicauth", ALNUM WS ALNUM, handle_basicauth),
|
STDCONF ("basicauth", ALNUM WS ALNUM, handle_basicauth),
|
||||||
STDCONF ("errorfile", INT WS STR, handle_errorfile),
|
STDCONF ("errorfile", INT WS STR, handle_errorfile),
|
||||||
STDCONF ("addheader", STR WS STR, handle_addheader),
|
STDCONF ("addheader", STR WS STR, handle_addheader),
|
||||||
|
STDCONF ("allowupgrade", BOOL, handle_allowupgrade),
|
||||||
|
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
/* filtering */
|
/* filtering */
|
||||||
@ -952,6 +954,12 @@ static HANDLE_FUNC (handle_addheader)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HANDLE_FUNC (handle_allowupgrade)
|
||||||
|
{
|
||||||
|
return set_bool_arg (&conf->allowupgrade, line, &match[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Log level's strings.
|
* Log level's strings.
|
||||||
|
|
||||||
|
@ -111,6 +111,14 @@ struct config_s {
|
|||||||
* Extra headers to be added to outgoing HTTP requests.
|
* Extra headers to be added to outgoing HTTP requests.
|
||||||
*/
|
*/
|
||||||
vector_t add_headers;
|
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,
|
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) \
|
#define CHECK_LWS(header, len) \
|
||||||
((len) > 0 && (header[0] == ' ' || header[0] == '\t'))
|
((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
|
* 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
|
* 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->method, request->path,
|
||||||
request->host, portbuff,
|
request->host, portbuff,
|
||||||
connptr->upstream_proxy->ua.authstr);
|
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 {
|
} else {
|
||||||
return write_message (connptr->server_fd,
|
return write_message (connptr->server_fd,
|
||||||
"%s %s HTTP/1.0\r\n"
|
"%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 int remove_connection_headers (hashmap_t hashofheaders)
|
||||||
{
|
{
|
||||||
static const char *headers[] = {
|
char **headers;
|
||||||
"connection",
|
|
||||||
"proxy-connection"
|
|
||||||
};
|
|
||||||
|
|
||||||
char *data;
|
char *data;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
headers = connection_headers_default;
|
||||||
|
|
||||||
|
if (config.allowupgrade) {
|
||||||
|
headers = connection_headers_allow_upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i != (sizeof (headers) / sizeof (char *)); ++i) {
|
for (i = 0; i != (sizeof (headers) / sizeof (char *)); ++i) {
|
||||||
/* Look for the connection header. If it's not found, return. */
|
/* Look for the connection header. If it's not found, return. */
|
||||||
len =
|
len =
|
||||||
@ -850,20 +883,19 @@ done:
|
|||||||
static int
|
static int
|
||||||
process_client_headers (struct conn_s *connptr, hashmap_t hashofheaders)
|
process_client_headers (struct conn_s *connptr, hashmap_t hashofheaders)
|
||||||
{
|
{
|
||||||
static const char *skipheaders[] = {
|
char **skipheaders;
|
||||||
"host",
|
|
||||||
"keep-alive",
|
|
||||||
"proxy-connection",
|
|
||||||
"te",
|
|
||||||
"trailers",
|
|
||||||
"upgrade"
|
|
||||||
};
|
|
||||||
int i;
|
int i;
|
||||||
hashmap_iter iter;
|
hashmap_iter iter;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
char *data, *header;
|
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
|
* 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
|
* a stats request, or if this was a CONNECT method (unless upstream
|
||||||
|
Loading…
Reference in New Issue
Block a user