{"action":"created","issue":{"url":"https://api.github.com/repos/KeepSafe/aiohttp/issues/476","labels_url":"https://api.github.com/repos/KeepSafe/aiohttp/issues/476/labels{/name}","comments_url":"https://api.github.com/repos/KeepSafe/aiohttp/issues/476/comments","events_url":"https://api.github.com/repos/KeepSafe/aiohttp/issues/476/events","html_url":"https://github.com/KeepSafe/aiohttp/issues/476","id":103561906,"number":476,"title":"StreamResponse + HTTP/1.0 = corrupted file ","user":{"login":"vbraun","id":888729,"avatar_url":"https://avatars.githubusercontent.com/u/888729?v=3","gravatar_id":"","url":"https://api.github.com/users/vbraun","html_url":"https://github.com/vbraun","followers_url":"https://api.github.com/users/vbraun/followers","following_url":"https://api.github.com/users/vbraun/following{/other_user}","gists_url":"https://api.github.com/users/vbraun/gists{/gist_id}","starred_url":"https://api.github.com/users/vbraun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vbraun/subscriptions","organizations_url":"https://api.github.com/users/vbraun/orgs","repos_url":"https://api.github.com/users/vbraun/repos","events_url":"https://api.github.com/users/vbraun/events{/privacy}","received_events_url":"https://api.github.com/users/vbraun/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/KeepSafe/aiohttp/milestones/1","html_url":"https://github.com/KeepSafe/aiohttp/milestones/0.18","labels_url":"https://api.github.com/repos/KeepSafe/aiohttp/milestones/1/labels","id":1250551,"number":1,"title":"0.18","description":"aiohttp 0.18 major release","creator":{"login":"asvetlov","id":356399,"avatar_url":"https://avatars.githubusercontent.com/u/356399?v=3","gravatar_id":"","url":"https://api.github.com/users/asvetlov","html_url":"https://github.com/asvetlov","followers_url":"https://api.github.com/users/asvetlov/followers","following_url":"https://api.github.com/users/asvetlov/following{/other_user}","gists_url":"https://api.github.com/users/asvetlov/gists{/gist_id}","starred_url":"https://api.github.com/users/asvetlov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/asvetlov/subscriptions","organizations_url":"https://api.github.com/users/asvetlov/orgs","repos_url":"https://api.github.com/users/asvetlov/repos","events_url":"https://api.github.com/users/asvetlov/events{/privacy}","received_events_url":"https://api.github.com/users/asvetlov/received_events","type":"User","site_admin":false},"open_issues":6,"closed_issues":4,"state":"open","created_at":"2015-08-11T19:36:14Z","updated_at":"2015-09-01T13:33:22Z","due_on":null,"closed_at":null},"comments":7,"created_at":"2015-08-27T17:56:15Z","updated_at":"2015-09-01T15:17:28Z","closed_at":null,"body":"I'm using StreamResponse to serve files. My code is\r\n\r\n    from aiohttp import web\r\n    response = web.StreamResponse()\r\n    response.enable_chunked_encoding()\r\n    response.content_length = statinfo.st_size\r\n    response.content_type = 'application/octet-stream'\r\n    response.start(request)\r\n    with open(filename, 'rb') as f:\r\n        while True:\r\n            chunk = f.read(CHUNK_SIZE)\r\n            if not chunk:\r\n                return response\r\n            response.write(chunk)\r\n            yield from response.drain()\r\n\r\nIf I'm using wget to download the file then it works beautifully. But when I'm using Python urllib to download the file, my download is corrupted. The difference seems to be that wget can HTTP/1.1, but urllib only does HTTP/1.0. The network trace is\r\n~~~~\r\nHost: ...\r\nUser-Agent: Python-urllib/1.17\r\n\r\nHTTP/1.0 200 OK\r\nCONTENT-LENGTH: 815206\r\nCONTENT-TYPE: application/octet-stream\r\nTRANSFER-ENCODING: chunked\r\nCONNECTION: close\r\nDATE: Thu, 27 Aug 2015 17:31:25 GMT\r\nSERVER: Python/3.4 aiohttp/0.17.2\r\n\r\n10000\r\n... binary data ...\r\n~~~~\r\nand Python saves everything starting at (and including) the 10000 into the file. \r\n\r\nI think this is because `TRANSFER-ENCODING: chunked` is HTTP/1.1 only, and a HTTP/1.0 client is entirely correct in ignoring it. Aiohttp should not send chunk sizes to HTTP/1.0 clients as they almost certainly end up in the data stream. "},"comment":{"url":"https://api.github.com/repos/KeepSafe/aiohttp/issues/comments/136757275","html_url":"https://github.com/KeepSafe/aiohttp/issues/476#issuecomment-136757275","issue_url":"https://api.github.com/repos/KeepSafe/aiohttp/issues/476","id":136757275,"user":{"login":"asvetlov","id":356399,"avatar_url":"https://avatars.githubusercontent.com/u/356399?v=3","gravatar_id":"","url":"https://api.github.com/users/asvetlov","html_url":"https://github.com/asvetlov","followers_url":"https://api.github.com/users/asvetlov/followers","following_url":"https://api.github.com/users/asvetlov/following{/other_user}","gists_url":"https://api.github.com/users/asvetlov/gists{/gist_id}","starred_url":"https://api.github.com/users/asvetlov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/asvetlov/subscriptions","organizations_url":"https://api.github.com/users/asvetlov/orgs","repos_url":"https://api.github.com/users/asvetlov/repos","events_url":"https://api.github.com/users/asvetlov/events{/privacy}","received_events_url":"https://api.github.com/users/asvetlov/received_events","type":"User","site_admin":false},"created_at":"2015-09-01T15:17:28Z","updated_at":"2015-09-01T15:17:28Z","body":"If you know content length and set up `response.content_length` attr you don't need chunked encoding.\r\nJust send your data slice-by-slice without `response.enable_chunked_encoding()` call -- it works pretty well for both HTTP/1.0 and HTTP/1.1"}}