djproxy
djproxy copied to clipboard
websockets/channels
Hi thomas, great proxy you have developed there, thanks in first place :+1: Just a question if you took a look already at supporting websockets via the django-channels project? I was said to be included in django 1.10 but it wasn't but i wanted to ask if you would consider supporting it anyway?? Thanks!
In short: Yes, definitely looking at it and I'm excited that it may finally allow proxying of websockets in a reasonable way.
I was disappointed that channels was dropped from 1.10 and waiting for 1.11 to roll just doesn't seem like a viable option. People (myself included) need this functionality now (er, really, yesterday). In any event, the next step is to fix the parts of djproxy that aren't 1.10 compatible (url pattern generation) and then starting work towards channels integration would follow immediately after that.
I'll leave this open and update it once I have a chance to investigate websocket proxying via channels.
Django 1.10 support has been released: https://github.com/thomasw/djproxy/pull/23 👍
Great that you keep working on this project and there's a chance that also proxying of websockets will be possible in the near future... how complicated do you think it is to implement a stable solution to use django as a reverse proxy with websockets??
I would need to redirect traffic from django to a jupyter notebook server running on a different port on the same machine in a docker-container. there is a implementation for this with tornado, called jupyterhub but I'd like to use django for all the user-mgmt and so on...
I haven't implemented anything with channels yet, so it's hard for me to answer with any certainty. Conceptually, I think it maps well to this problem and that it seems feasible to implement, but there's a lot of protocol level nuance that might make it impractical. I won't really be able to commit to anything until I have a prototype that I can point at lots of different targets to get a better idea of their behavior when there's a likely slightly less than completely transparent middleman sitting between them and the client.
That aside, based on your description, there might be a simpler way to achieve what you're going for rather than trying to roll your own jupyter proxy: You could build a django based backend that provides user management, authentication endpoints, session handling, etc. You could then add an API endpoint to that backend that responds to GET requests with data about the currently logged in user (and a 403 or some data indicating not authenticated for logged out users). I usually refer to that type of implementation as a "me endpoint".
Once you have that mechanism in place on the Django side, you can roll out a jupyterhub based implementation with one critical addition: when clients connect to jupyterhub, you make an API call to your django implementation that forwards along whatever cookie data was sent in the original request. If your "me" implementation says the user is authenticated, great, proceed as normal and, if not, 403.
This approach has the advantage of being more decoupled. Rather than making your django implementation the architectural overlord, you can instead make it a provider that allows clients to verify session data whenever they receive it. The disadvantage is that multiple, distinct services leads to configuration and deployment complexity in the short term. However, I'd argue that this architecture eventually becomes hugely advantageous because you can do things like the following: 1. Check out your jupyterhub implementation locally. 2. Point it at some remote environment that has all of the services it depends on running on it. 3. Do work on jupyterhub without having to run and configure your entire platform on your dev machine.
If you aren't familiar with microservices as an architectural strategy, that's more or less what I'm advocating here and it's worth reading up on them to see if that approach meshes well with whatever you're trying to build. I suspect it will.
Any news on this?
Sadly, no. I'd love to come back around to this but it's difficult for me to predict when exactly I might have the capacity. If anyone coming across this thread happens to hack together a proof of concept and is willing to share, please do so. The biggest barrier here is not knowing whether or not this is even possible through django-channels and not really having the time to investigate that thoroughly.
On a related note, django 3.0 is right around the corner with ASGI support baked in. However, it doesn't seem as though it provides any additional affordances for websockets. I need to look into it a bit more to be sure on that though.
@thomasw, I have a proof of concept for this. I'm using djproxy in combination with a Django Channels based websocket proxy consumer to proxy VS Code/code-server as well as NoVNC connections (not in production). I have made this available in a proof of concept gist.