Hi,

thanks for bringing this to my attention, i've commited
my latest diff.

/Benno

Daniel Lamando(d...@danopia.net) on 2019.02.28 21:09:35 -0800:
> Hi all,
> 
> I noticed that relayd doesn't support Websocket connections.
> When a Websocket request is forwarded through relayd,
> the handshake completes ok, but the backend never
> receives further packets sent from the client.
> 
> I found several messages in the openbsd-misc archive
> mentioning websockets not working with relayd:
>   - https://marc.info/?l=openbsd-misc&m=152510591921674
>   - https://marc.info/?l=openbsd-misc&m=152558941423236
>   - https://marc.info/?l=openbsd-misc&m=153997265632162
> 
> After examining conversations and the relayd source I've traced
> this to the fact that Websockets negotiate using the GET method.
> relayd does not currently forward any request body upstream
> after forwarding a GET message from the client:
> 
>       case HTTP_METHOD_GET:
>               cre->toread = 0;
> 
> I found that relayd already supports bidirectional client<->server
> communication when the HTTP CONNECT method is sent by
> the client. Websockets are signalled slightly differently.
> The client includes a 'Connection: Upgrade' header, and
> the server returns an HTTP 101 response body.
> There are also other websocket-specific headers but they
> do not concern us as a proxy server.
> 
> The Websocket handshake is completed by the server sending:
>       HTTP/1.1 101 Switching Protocols
> According to RFC 2616's section on HTTP 101:
>       The server will switch protocols to those defined by the response's
>       Upgrade header field immediately after the empty line which
>       terminates the 101 response.
> 
> I've attached a small patch for relayd which re-enables
> client->server forwarding when an HTTP 101 is passed down.
> Applying this patch over OpenBSD 6.5-beta allows relayd to
> pass bidirectional websocket data, fixing my chat app :)
> 
> PS: I???ve also tested relayd by relaying the example server from here:
>       https://www.websocket.org/echo.html
> If you try that, note that the server is strict about the `Connection???
> request header being preserved. Otherwise it will 400.
> 
> 
> Index: relay_http.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
> retrieving revision 1.71
> diff -u -p -r1.71 relay_http.c
> --- relay_http.c      6 Aug 2018 17:31:31 -0000       1.71
> +++ relay_http.c      1 Mar 2019 04:52:26 -0000
> @@ -276,6 +276,13 @@ relay_read_http(struct bufferevent *bev,
>                       DPRINTF("http_version %s http_rescode %s "
>                           "http_resmesg %s", desc->http_version,
>                           desc->http_rescode, desc->http_resmesg);
> +
> +                     /* HTTP 101 Switching Protocols */
> +                     if (desc->http_status == 101) {
> +                             cre->dst->toread = TOREAD_UNLIMITED;
> +                             cre->dst->bev->readcb = relay_read;
> +                     }
> +
>                       goto lookup;
>               } else if (cre->line == 1 && cre->dir == RELAY_DIR_REQUEST) {
>                       if ((desc->http_method = relay_httpmethod_byname(key))
> 

Reply via email to