Adding comet session attributes via HTTP headers in WS upgrade request

16 views
Skip to first unread message

Cosimo

unread,
Oct 18, 2019, 5:59:37 AM10/18/19
to cometd...@googlegroups.com
Hi,

I was wondering if it's possible to add custom HTTP headers (X-client-ip or something along
those lines) to the initial websocket upgrade request, so that the resulting websocket
comet session would have access to those headers.

In this way I could stash additional information in the comet session that is
normally not accessible to me.

Example: websocket sessions are proxied through nginx to my jetty
server running cometd. The comet session IP addresses are local proxy
IPs and ports, while ideally I'd like to have access to the client IP,
which is normally stored in a custom HTTP header like X-client-ip.

Possible?

--
Cosimo

Simone Bordet

unread,
Oct 18, 2019, 8:31:34 AM10/18/19
to cometd-users
Hi,
This particular latter case is possible to achieve (and recommended)
using the PROXY protocol rather than HTTP headers.
https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/

Adding other HTTP header for other use cases is trivial when using
non-browser clients, and impossible when using browsers (because the
WebSocket browser API do not allow to add HTTP headers).

--
Simone Bordet
----
http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.

Cosimo

unread,
Oct 18, 2019, 9:25:18 AM10/18/19
to cometd...@googlegroups.com
On Fri, Oct 18, 2019, at 14:31, Simone Bordet wrote:
> On Fri, Oct 18, 2019 at 11:59 AM Cosimo <cosi...@streppone.it> wrote:
> >
> > Example: websocket sessions are proxied through nginx to my jetty
> > server running cometd. The comet session IP addresses are local proxy
> > IPs and ports, while ideally I'd like to have access to the client IP,
> > which is normally stored in a custom HTTP header like X-client-ip.
>
> This particular latter case is possible to achieve (and recommended)
> using the PROXY protocol rather than HTTP headers.
> https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/

Will look into that, thanks.

> Adding other HTTP header for other use cases is trivial when using
> non-browser clients, and impossible when using browsers (because the
> WebSocket browser API do not allow to add HTTP headers).

More in general, I was hoping to inject arbitrary information when
the websocket is created, whether that is an HTTP header or something
else, f.ex. it could be a random request-id string or fingerprint added by
our nginx layer to the websocket upgrade request, so not necessarily
with browser interaction.

I seem to understand there's a few mechanisms to do this (WebSocketUpgradeFilter,
WebSocketCreator, WebSocketServlet? ...) but I can't see yet if and how they
would be accessible from the comet server classes.

Tried searching in the comet source distribution and tests but didn't find
anything similar.

--
Cosimo

Simone Bordet

unread,
Oct 18, 2019, 9:49:32 AM10/18/19
to cometd-users
Hi,

On Fri, Oct 18, 2019 at 3:25 PM Cosimo <cosi...@streppone.it> wrote:
> More in general, I was hoping to inject arbitrary information when
> the websocket is created, whether that is an HTTP header or something
> else, f.ex. it could be a random request-id string or fingerprint added by
> our nginx layer to the websocket upgrade request, so not necessarily
> with browser interaction.

This is already available on the server-side via BayeuxServer.getContext().
If you add a header in nginx, you will be able to see it in the BayeuxContext.

OTOH, if you have a client and want to add a header to be processed by
the server, as I said it's possible in non-browser clients only.

Cosimo

unread,
Jan 14, 2020, 10:57:49 AM1/14/20
to cometd...@googlegroups.com
On Fri, Oct 18, 2019, at 15:49, Simone Bordet wrote:
> On Fri, Oct 18, 2019 at 3:25 PM Cosimo <cosi...@streppone.it> wrote:
> > More in general, I was hoping to inject arbitrary information when
> > the websocket is created, whether that is an HTTP header or something
> > else, f.ex. it could be a random request-id string or fingerprint added by
> > our nginx layer to the websocket upgrade request, so not necessarily
> > with browser interaction.
>
> This is already available on the server-side via BayeuxServer.getContext().
> If you add a header in nginx, you will be able to see it in the BayeuxContext.

Hi again,

Coming back to this thread :-)
I did manage to extract the HTTP headers from the BayeuxContext.

Now I am thinking of attaching information of my own to the context.
Possible?

Example: enrich the BayeuxContext with the timestamp
of the last received message (from the same session).

I see there is no way for me to setContextAttribute(), and setHttpSessionAttribute()
does not seem to work in that way. Should I consider the context as read-only?
If so, I'm wondering what setHttpSessionAttribute() is for.

--
Cosimo

Simone Bordet

unread,
Jan 14, 2020, 11:09:19 AM1/14/20
to cometd-users
Hi,

On Tue, Jan 14, 2020 at 4:57 PM Cosimo <cosi...@streppone.it> wrote:
> Now I am thinking of attaching information of my own to the context.
> Possible?
>
> Example: enrich the BayeuxContext with the timestamp
> of the last received message (from the same session).
>
> I see there is no way for me to setContextAttribute(), and setHttpSessionAttribute()
> does not seem to work in that way. Should I consider the context as read-only?
> If so, I'm wondering what setHttpSessionAttribute() is for.

It is possible, by using ServerSession.setAttribute(...).

You want to use BayeuxContext the least possible, as it contains
transport specific information that may break your application when
you switch to another transport (e.g. from HTTP to WebSocket).

Cosimo

unread,
Jan 14, 2020, 3:27:57 PM1/14/20
to cometd...@googlegroups.com
On Tue, Jan 14, 2020, at 17:09, Simone Bordet wrote:
> Hi,
>
> On Tue, Jan 14, 2020 at 4:57 PM Cosimo <cosi...@streppone.it> wrote:
> > Now I am thinking of attaching information of my own to the context.
> > Possible?
> >
> > Example: enrich the BayeuxContext with the timestamp
> > of the last received message (from the same session).
> >
> It is possible, by using ServerSession.setAttribute(...).

Will do as suggested, thanks!

--
Cosimo
Reply all
Reply to author
Forward
0 new messages