Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect HTTP/1.1 501 Not Implemented log messge for websocket connection #659

Open
mcenkar opened this issue Jul 23, 2021 · 3 comments
Open

Comments

@mcenkar
Copy link

mcenkar commented Jul 23, 2021

Hi,

when connecting to BlazeWebSocketExample.scala if I change line 85 to:

.withHttpApp(org.http4s.server.middleware.Logger.httpApp(logHeaders = false, logBody = false)(routes.orNotFound))

then when I connect to WS instead of actual 101 Switching Protocols code:

image

in logs it prints:

14:45:18.748 [io-compute-3] INFO  org.http4s.server.middleware.Logger - HTTP/1.1 GET /ws?encoding=text
14:45:18.748 [io-compute-3] INFO  org.http4s.server.middleware.Logger - HTTP/1.1 501 Not Implemented

and also afterwards after disconnecting it prints incorrect Unknown type: Close or Unknown type: Close(Array(2)) (but this is example issue)

@rossabaker
Copy link
Member

rossabaker commented Jul 29, 2021

Ooh, this is tricky. An implementation detail is that websockets are implemented as an HTTP fallback response (the 501) with an attribute that contains the websocket. Backends that support web sockets look for this attribute and perform the connection upgrade instead of rendering the fallback response. But the Logger middleware doesn't know about any of this trickery.

We could:

  1. Special case web sockets in the logging middleware. (Yuck!)
  2. Send back web sockets as a 101 response, and figure out some other way to gracefully degrade them to a 501. (Yuck!)
  3. ???

/cc @ChristopherDavenport for logger expertise
/cc @RaasAhsan for recent work on web sockets in Ember

@RaasAhsan
Copy link

Yeah this is definitely a tricky one. This may just be a fundamental flaw in how http4s models middleware and web sockets. You see similar problems when isolated to middleware too. Imagine you position a logger middleware to execute before a retry middleware. Whenever an error happens, the logger is going to log the failed response, but then the retry middleware will throw that response away and perform the action again.

Obviously the solution for that example is to position the logger middleware after every other middleware, but it highlights the problem: middleware generally has no post facto context about what happens to a response. Similarly, any manipulation performed on a response by a backend will be hidden to a middleware

Another yucky solution to the problem is to expose backend-level middleware that runs right before a response is written to the socket. Its not composable and its backend-specific, but its general enough that there may be other use cases for it

@rossabaker
Copy link
Member

Yes, I agree with Raas. A long time ago, I tried to create a general event stream to peer deeper into these things that happen in the backends, but the backends are by nature not very general, and the event system was not particularly functional. Our logging and metrics approach sacrifice a small slice of accuracy for general composition. Servlets have their own metrics and logging, but Ember and Blaze, our two most popular, don't.

It has never been my itch, because I've always had some sidecar or cloud gateway in front that does know the "post facto context." But that's a sorry answer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants