{"action":"created","issue":{"url":"https://api.github.com/repos/rack/rack/issues/323","repository_url":"https://api.github.com/repos/rack/rack","labels_url":"https://api.github.com/repos/rack/rack/issues/323/labels{/name}","comments_url":"https://api.github.com/repos/rack/rack/issues/323/comments","events_url":"https://api.github.com/repos/rack/rack/issues/323/events","html_url":"https://github.com/rack/rack/issues/323","id":2918896,"number":323,"title":"Multipart filename can not be decoded.","user":{"login":"comron","id":126529,"avatar_url":"https://avatars.githubusercontent.com/u/126529?v=3","gravatar_id":"","url":"https://api.github.com/users/comron","html_url":"https://github.com/comron","followers_url":"https://api.github.com/users/comron/followers","following_url":"https://api.github.com/users/comron/following{/other_user}","gists_url":"https://api.github.com/users/comron/gists{/gist_id}","starred_url":"https://api.github.com/users/comron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/comron/subscriptions","organizations_url":"https://api.github.com/users/comron/orgs","repos_url":"https://api.github.com/users/comron/repos","events_url":"https://api.github.com/users/comron/events{/privacy}","received_events_url":"https://api.github.com/users/comron/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rack/rack/labels/Future","name":"Future","color":"02d7e1"},{"url":"https://api.github.com/repos/rack/rack/labels/Refactor","name":"Refactor","color":"0b02e1"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/rack/rack/milestones/11","html_url":"https://github.com/rack/rack/milestones/Rack%202.0","labels_url":"https://api.github.com/repos/rack/rack/milestones/11/labels","id":97132,"number":11,"title":"Rack 2.0","description":"","creator":{"login":"raggi","id":348,"avatar_url":"https://avatars.githubusercontent.com/u/348?v=3","gravatar_id":"","url":"https://api.github.com/users/raggi","html_url":"https://github.com/raggi","followers_url":"https://api.github.com/users/raggi/followers","following_url":"https://api.github.com/users/raggi/following{/other_user}","gists_url":"https://api.github.com/users/raggi/gists{/gist_id}","starred_url":"https://api.github.com/users/raggi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raggi/subscriptions","organizations_url":"https://api.github.com/users/raggi/orgs","repos_url":"https://api.github.com/users/raggi/repos","events_url":"https://api.github.com/users/raggi/events{/privacy}","received_events_url":"https://api.github.com/users/raggi/received_events","type":"User","site_admin":false},"open_issues":10,"closed_issues":12,"state":"open","created_at":"2012-03-17T18:38:20Z","updated_at":"2015-09-04T21:18:22Z","due_on":"2013-07-31T07:00:00Z","closed_at":null},"comments":24,"created_at":"2012-01-21T00:44:18Z","updated_at":"2016-03-07T19:58:43Z","closed_at":null,"body":"I'm using a simple form on a rails application to upload a file, it looks as if the browser is not encoding the filename in the multipart \"Content-Disposition\" header, and as a result rack cannot decode the filename if it has a % in it, as it expects this to be the start of an escape sequence.\r\n\r\n```\r\n<form accept-charset=\"UTF-8\" action=\"/documents.json\" enctype=\"multipart/form-data\" method=\"post\">\r\n  <input name=\"utf8\" type=\"hidden\" value=\"✓\">\r\n  <input id=\"document_attachment\" name=\"document[attachment]\" type=\"file\">\r\n  <input type=\"submit\">\r\n</form>\r\n```\r\n\r\nResults in the following request\r\n\r\n```\r\nAccept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nContent-Type:multipart/form-data; boundary=----WebKitFormBoundary2NHc7OhsgU68l3Al\r\nOrigin:http://localhost:3000\r\nReferer:http://localhost:3000/\r\nUser-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.18 (KHTML, like Gecko) Chrome/18.0.1010.0 Safari/535.18\r\n\r\n------WebKitFormBoundary2NHc7OhsgU68l3Al\r\nContent-Disposition: form-data; name=\"utf8\"\r\n\r\nâœ“\r\n------WebKitFormBoundary2NHc7OhsgU68l3Al\r\nContent-Disposition: form-data; name=\"document[attachment]\"; filename=\"100% of a photo.jpeg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary2NHc7OhsgU68l3Al--\r\n```\r\n\r\nAs you can see the filename is not encoded, but the % causes rack to throw an error. Where exactly is the problem? It seems I have no control over the browser (Chrome and Firefox on OS X) encoding this name, and rack assumes it is always encoded, in multipart/parser.rb.\r\n\r\nThanks and sorry if this is the wrong forum for such a question."},"comment":{"url":"https://api.github.com/repos/rack/rack/issues/comments/193423932","html_url":"https://github.com/rack/rack/issues/323#issuecomment-193423932","issue_url":"https://api.github.com/repos/rack/rack/issues/323","id":193423932,"user":{"login":"raggi","id":348,"avatar_url":"https://avatars.githubusercontent.com/u/348?v=3","gravatar_id":"","url":"https://api.github.com/users/raggi","html_url":"https://github.com/raggi","followers_url":"https://api.github.com/users/raggi/followers","following_url":"https://api.github.com/users/raggi/following{/other_user}","gists_url":"https://api.github.com/users/raggi/gists{/gist_id}","starred_url":"https://api.github.com/users/raggi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raggi/subscriptions","organizations_url":"https://api.github.com/users/raggi/orgs","repos_url":"https://api.github.com/users/raggi/repos","events_url":"https://api.github.com/users/raggi/events{/privacy}","received_events_url":"https://api.github.com/users/raggi/received_events","type":"User","site_admin":false},"created_at":"2016-03-07T19:58:43Z","updated_at":"2016-03-07T19:58:43Z","body":"FTR, https://tools.ietf.org/html/rfc7578 saying \"MAY be percent encoded\" is a fucking joke, because it means that the decoding of filenames is entirely ambiguous. That said, it is possible with the relatively clear definition in RFC7578 now to create a percent-encoding parser that will work for this task. There is nothing in MRI standard lib that conforms to this today."}}