{"action":"created","issue":{"url":"https://api.github.com/repos/elixir-lang/plug/issues/492","repository_url":"https://api.github.com/repos/elixir-lang/plug","labels_url":"https://api.github.com/repos/elixir-lang/plug/issues/492/labels{/name}","comments_url":"https://api.github.com/repos/elixir-lang/plug/issues/492/comments","events_url":"https://api.github.com/repos/elixir-lang/plug/issues/492/events","html_url":"https://github.com/elixir-lang/plug/issues/492","id":194582407,"number":492,"title":"Add support for streaming response body","user":{"login":"mspanc","id":389651,"avatar_url":"https://avatars.githubusercontent.com/u/389651?v=3","gravatar_id":"","url":"https://api.github.com/users/mspanc","html_url":"https://github.com/mspanc","followers_url":"https://api.github.com/users/mspanc/followers","following_url":"https://api.github.com/users/mspanc/following{/other_user}","gists_url":"https://api.github.com/users/mspanc/gists{/gist_id}","starred_url":"https://api.github.com/users/mspanc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mspanc/subscriptions","organizations_url":"https://api.github.com/users/mspanc/orgs","repos_url":"https://api.github.com/users/mspanc/repos","events_url":"https://api.github.com/users/mspanc/events{/privacy}","received_events_url":"https://api.github.com/users/mspanc/received_events","type":"User","site_admin":false},"labels":[{"id":66009137,"url":"https://api.github.com/repos/elixir-lang/plug/labels/Kind:Feature","name":"Kind:Feature","color":"1d76db","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":8,"created_at":"2016-12-09T12:12:35Z","updated_at":"2016-12-28T07:30:57Z","closed_at":null,"body":"I am implementing a Phoenix app that has controller that effectively acts as a HTTP proxy. It fetches file over HTTP from the upstream server (in chunks) and sends it back to the client.\r\n\r\nAt the moment I am sending chunked response using `Plug.Conn.send_chunked/2` and `Plug.Conn.chunk/2`.\r\n\r\nThe issue is that that sets Transfer-Encoding to chunked and according to the HTTP/1.1 RFC that causes Content-Length header to be obsolete. If it get further proxied through nginx, this header is just removed to match the RFC.\r\n\r\nAs I am serving audio/video to the web browsers that effectively causes them to disable seeking as total file length is unknown.\r\n\r\nAt the moment the only workaround is to download the whole from the upstream and send it to the client, but I want to do this on the fly as there's no reason to introduce this extra step.\r\n\r\nIt would be great if there would have been another interface allowing to build response body from parts but send it as regular (non-chunked) response."},"comment":{"url":"https://api.github.com/repos/elixir-lang/plug/issues/comments/269438266","html_url":"https://github.com/elixir-lang/plug/issues/492#issuecomment-269438266","issue_url":"https://api.github.com/repos/elixir-lang/plug/issues/492","id":269438266,"user":{"login":"bsuh","id":47231,"avatar_url":"https://avatars.githubusercontent.com/u/47231?v=3","gravatar_id":"","url":"https://api.github.com/users/bsuh","html_url":"https://github.com/bsuh","followers_url":"https://api.github.com/users/bsuh/followers","following_url":"https://api.github.com/users/bsuh/following{/other_user}","gists_url":"https://api.github.com/users/bsuh/gists{/gist_id}","starred_url":"https://api.github.com/users/bsuh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bsuh/subscriptions","organizations_url":"https://api.github.com/users/bsuh/orgs","repos_url":"https://api.github.com/users/bsuh/repos","events_url":"https://api.github.com/users/bsuh/events{/privacy}","received_events_url":"https://api.github.com/users/bsuh/received_events","type":"User","site_admin":false},"created_at":"2016-12-28T07:30:57Z","updated_at":"2016-12-28T07:30:57Z","body":"```\r\nwget         0.58 real         0.01 user         0.16 sys\r\nhttpc        18.25 real         1.93 user         1.54 sys\r\nibrowse       31.79 real         3.61 user         2.77 sys\r\nhackney      15.36 real         0.78 user         0.51 sys\r\nlhttpc        4.21 real         0.48 user         0.43 sys\r\nfusco did not finish for my patience\r\nshotgun       4.30 real         0.84 user         0.67 sys\r\nhttpoison       4.99 real         0.77 user         0.44 sys\r\n\r\n:inets.start\r\n:httpc.request('http://localhost:8080/test')\r\n\r\n:ibrowse.start\r\n:ibrowse.send_req('http://localhost:8080/test', [], :get); nil\r\n\r\n:hackney.start\r\n{:ok, status_code, headers, client} = :hackney.request(:get, \"http://localhost:8080/test\", [], \"\", []); nil\r\n:hackney.body(client); nil\r\n\r\n:lhttpc.start\r\n:lhttpc.request('http://localhost:8080/test', :get, [], :infinity); nil\r\n\r\n{:ok, client} = :fusco.start('http://localhost:8080', [])\r\n{:ok, result} = :fusco.request(client, \"/test\", \"GET\", [], []); nil\r\n\r\n:shotgun.start\r\n{:ok, conn} = :shotgun.open('localhost', 8080)\r\n{:ok, resp} = :shotgun.get(conn, '/test'); nil\r\n\r\nHTTPoison.start\r\nHTTPoison.get! \"http://localhost:8080/test\"; nil\r\n```\r\nGood news. I did some **unscientific** testing of various Erlang/Elixir HTTP clients downloading a 100 MB file and decided to try `lhttpc` based on the results, and it works very nicely!\r\n\r\nHere's the link again to the gist with updated code. Note that it reads private variables from Plug.Conn to pass to cowboy functions and updates the Plug.Conn manually, so it might break with dependency updates. I'm using plug 1.2.2, cowboy 1.0.4, and phoenix 1.2.1\r\nhttps://gist.github.com/bsuh/295759580d36fe42a533abb733cb912c "}}
{"actor":{"display_login":"bsuh"}}