broken_clients.ezdoc 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. ::: Dealing with broken clients
  2. There exists a very large number of implementations for the
  3. HTTP protocol. Most widely used clients, like browsers,
  4. follow the standard quite well, but others may not. In
  5. particular custom enterprise clients tend to be very badly
  6. written.
  7. Cowboy tries to follow the standard as much as possible,
  8. but is not trying to handle every possible special cases.
  9. Instead Cowboy focuses on the cases reported in the wild,
  10. on the public Web.
  11. That means clients that ignore the HTTP standard completely
  12. may fail to understand Cowboy's responses. There are of
  13. course workarounds. This chapter aims to cover them.
  14. :: Lowercase headers
  15. Cowboy converts all headers it receives to lowercase, and
  16. similarly sends back headers all in lowercase. Some broken
  17. HTTP clients have issues with that.
  18. A simple way to solve this is to create an `onresponse` hook
  19. that will format the header names with the expected case.
  20. ``` erlang
  21. capitalize_hook(Status, Headers, Body, Req) ->
  22. Headers2 = [{cowboy_bstr:capitalize_token(N), V}
  23. || {N, V} <- Headers],
  24. cowboy_req:reply(Status, Headers2, Body, Req).
  25. ```
  26. Note that SPDY clients do not have that particular issue
  27. because the specification explicitly says all headers are
  28. lowercase, unlike HTTP which allows any case but treats
  29. them as case insensitive.
  30. :: Camel-case headers
  31. Sometimes it is desirable to keep the actual case used by
  32. clients, for example when acting as a proxy between two broken
  33. implementations. There is no easy solution for this other than
  34. forking the project and editing the `cowboy_protocol` file
  35. directly.
  36. :: Chunked transfer-encoding
  37. Sometimes an HTTP client advertises itself as HTTP/1.1 but
  38. does not support chunked transfer-encoding. This is invalid
  39. behavior, as HTTP/1.1 clients are required to support it.
  40. A simple workaround exists in these cases. By changing the
  41. Req object response state to `waiting_stream`, Cowboy will
  42. understand that it must use the identity transfer-encoding
  43. when replying, just like if it was an HTTP/1.0 client.
  44. ``` erlang
  45. Req2 = cowboy_req:set(resp_state, waiting_stream).
  46. ```