PageRenderTime 25ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/middleware/ewgi_deflate/ewgi_deflate.erl

http://github.com/skarab/ewgi
Erlang | 70 lines | 53 code | 8 blank | 9 comment | 0 complexity | ee9910f3fc781f7f123f2e3b09de5e1b MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. %% @author Filippo Pacini <filippo.pacini@gmail.com>
  2. %% @copyright 2009 S.G. Consulting.
  3. %% @doc deflate ewgi middleware.
  4. -module(ewgi_deflate).
  5. -author('Filippo Pacini <filippo.pacini@gmail.com>').
  6. -export([run/2]).
  7. -define(ENCODABLE, ["text/plain", "text/html", "text/xml"]).
  8. run(Ctx, []) ->
  9. %% get the accept encoding header
  10. AcceptEnc = ewgi_api:get_header_value("accept-encoding", Ctx),
  11. Hdrs = ewgi_api:response_headers(Ctx),
  12. %% check gzip/deflate
  13. Ctx1 = case can_encode_response(Hdrs) of
  14. true ->
  15. case parse_encoding(AcceptEnc) of
  16. false ->
  17. Ctx;
  18. gzip ->
  19. %% FIXME: does not work if response_message_body streams a file
  20. Body1 = zlib:gzip(ewgi_api:response_message_body(Ctx)),
  21. Hdrs1 = [{"Content-encoding", "gzip"}|Hdrs],
  22. ewgi_api:response_headers(
  23. Hdrs1,
  24. ewgi_api:response_message_body(Body1, Ctx)
  25. );
  26. deflate ->
  27. %% FIXME: does not work if response_message_body streams a file
  28. Body1 = zlib:compress(ewgi_api:response_message_body(Ctx)),
  29. Hdrs1 = [{"Content-encoding", "deflate"}|Hdrs],
  30. ewgi_api:response_headers(
  31. Hdrs1,
  32. ewgi_api:response_message_body(Body1, Ctx)
  33. )
  34. end;
  35. false ->
  36. Ctx
  37. end,
  38. Ctx1.
  39. can_encode_response(Headers) ->
  40. ContentType = proplists:get_value("Content-type", Headers),
  41. ContentEnc = proplists:get_value("Content-encoding", Headers),
  42. can_encode_response1(ContentType, ContentEnc).
  43. can_encode_response1(ContentType, undefined) ->
  44. lists:member(ContentType, ?ENCODABLE);
  45. can_encode_response1(_ContentType, _ContentEncoding) ->
  46. %% the response is already encoded in some way so we don't do anything
  47. false.
  48. parse_encoding(undefined) ->
  49. false;
  50. parse_encoding(Encoding) ->
  51. %% FIXME: read HTTP specs to see how to do this properly (e.g. check the q=X and the order)
  52. case string:str(Encoding, "gzip") of
  53. X when X>0 ->
  54. gzip;
  55. _ ->
  56. case string:str(Encoding, "deflate") of
  57. Y when Y>0 ->
  58. deflate;
  59. _ ->
  60. false
  61. end
  62. end.