{"action":"created","issue":{"url":"https://api.github.com/repos/rails/rails/issues/32833","repository_url":"https://api.github.com/repos/rails/rails","labels_url":"https://api.github.com/repos/rails/rails/issues/32833/labels{/name}","comments_url":"https://api.github.com/repos/rails/rails/issues/32833/comments","events_url":"https://api.github.com/repos/rails/rails/issues/32833/events","html_url":"https://github.com/rails/rails/pull/32833","id":320610838,"number":32833,"title":"Add option to ActiveStorage::Blob to set extract_content_type_from_io","user":{"login":"ryandav","id":22416807,"avatar_url":"https://avatars3.githubusercontent.com/u/22416807?v=4","gravatar_id":"","url":"https://api.github.com/users/ryandav","html_url":"https://github.com/ryandav","followers_url":"https://api.github.com/users/ryandav/followers","following_url":"https://api.github.com/users/ryandav/following{/other_user}","gists_url":"https://api.github.com/users/ryandav/gists{/gist_id}","starred_url":"https://api.github.com/users/ryandav/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ryandav/subscriptions","organizations_url":"https://api.github.com/users/ryandav/orgs","repos_url":"https://api.github.com/users/ryandav/repos","events_url":"https://api.github.com/users/ryandav/events{/privacy}","received_events_url":"https://api.github.com/users/ryandav/received_events","type":"User","site_admin":false},"labels":[{"id":664533972,"url":"https://api.github.com/repos/rails/rails/labels/activestorage","name":"activestorage","color":"bfd4f2","default":false}],"state":"open","locked":false,"assignee":{"login":"georgeclaghorn","id":94129,"avatar_url":"https://avatars1.githubusercontent.com/u/94129?v=4","gravatar_id":"","url":"https://api.github.com/users/georgeclaghorn","html_url":"https://github.com/georgeclaghorn","followers_url":"https://api.github.com/users/georgeclaghorn/followers","following_url":"https://api.github.com/users/georgeclaghorn/following{/other_user}","gists_url":"https://api.github.com/users/georgeclaghorn/gists{/gist_id}","starred_url":"https://api.github.com/users/georgeclaghorn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/georgeclaghorn/subscriptions","organizations_url":"https://api.github.com/users/georgeclaghorn/orgs","repos_url":"https://api.github.com/users/georgeclaghorn/repos","events_url":"https://api.github.com/users/georgeclaghorn/events{/privacy}","received_events_url":"https://api.github.com/users/georgeclaghorn/received_events","type":"User","site_admin":false},"assignees":[{"login":"georgeclaghorn","id":94129,"avatar_url":"https://avatars1.githubusercontent.com/u/94129?v=4","gravatar_id":"","url":"https://api.github.com/users/georgeclaghorn","html_url":"https://github.com/georgeclaghorn","followers_url":"https://api.github.com/users/georgeclaghorn/followers","following_url":"https://api.github.com/users/georgeclaghorn/following{/other_user}","gists_url":"https://api.github.com/users/georgeclaghorn/gists{/gist_id}","starred_url":"https://api.github.com/users/georgeclaghorn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/georgeclaghorn/subscriptions","organizations_url":"https://api.github.com/users/georgeclaghorn/orgs","repos_url":"https://api.github.com/users/georgeclaghorn/repos","events_url":"https://api.github.com/users/georgeclaghorn/events{/privacy}","received_events_url":"https://api.github.com/users/georgeclaghorn/received_events","type":"User","site_admin":false}],"milestone":null,"comments":2,"created_at":"2018-05-06T17:24:39Z","updated_at":"2018-05-08T21:11:48Z","closed_at":null,"author_association":"NONE","pull_request":{"url":"https://api.github.com/repos/rails/rails/pulls/32833","html_url":"https://github.com/rails/rails/pull/32833","diff_url":"https://github.com/rails/rails/pull/32833.diff","patch_url":"https://github.com/rails/rails/pull/32833.patch"},"body":"### activestorage CHANGELOG.md addition\r\n\r\n*   Use `extract_content_type_from_io: false` as an argument in\r\n    `ActiveStorage::Blob.create_after_upload` to manually override the\r\n    automatic extraction of content type from the io.\r\n\r\n    This address the issue where the user defines a content type as an argument\r\n    but the automatic MimeType inference from the io is not what is expected.\r\n    It means a user avoids needing force the correct content type by\r\n    patching `ActiveStorage::Blob.extract_content_type`.\r\n\r\n    *Ryan Davidson*\r\n\r\n### Summary\r\n\r\nThis adds a boolean extract_content_type_from_io to ActiveStorage::Blob\r\nmethods #create_after_upload, #build_after_upload and #upload. It\r\nallows a user to manually override the automatic MimeType extraction from\r\nthe io. This provides a patch for when Marcel::MimeType.for returns an\r\nincorrect content type when #extract_content_type is called from the #upload method.\r\n\r\nThis patch aims to address:\r\n- https://github.com/rails/rails/issues/32632 Provide a way to deactivate ActiveStorage MIME type inference\r\n\r\nIt fixes bugs where a content_type is automatically extracted from the input and gives an inaccurate result. This is due to a bug in the Marcel::MimeType gem that is called in the extract_content_type method (which was called by default in the #upload method, which is in turn called by #build_after_upload and #create_after_upload)\r\n\r\n```\r\n2.5.0 Marcel::MimeType.for(StringIO.new(\"1895 1\"), name: 'text.csv', declared_type: 'text/csv')\r\n=> \"text/csv\"\r\n2.5.0 Marcel::MimeType.for(StringIO.new(\"Article dates analysis\"), name: 'text.csv', declared_type: 'text/csv')\r\n=> \"message/news\"\r\n2.5.0 Marcel::MimeType.for(StringIO.new(\"dates analysis\"), name: 'text.csv', declared_type: 'text/csv')\r\n=> \"text/csv\"\r\n2.5.0 Marcel::MimeType.for(StringIO.new(\"Dates analysis\"), name: 'text.csv', declared_type: 'text/csv')\r\n=> \"text/csv\"\r\n2.5.0 Marcel::MimeType.for(StringIO.new(\"article\"), name: 'text.csv', declared_type: 'text/csv')\r\n=> \"text/csv\"\r\n2.5.0 Marcel::MimeType.for(StringIO.new(\"Article\"), name: 'text.csv', declared_type: 'text/csv')\r\n=> \"message/news\"\r\n```\r\n\r\n### Other Information\r\n\r\nAdded document comments to `activestorage/app/models/active_storage/blob.rb`\r\n\r\nFinally, if your pull request affects documentation or any non-code\r\nchanges, guidelines for those changes are [available\r\nhere](http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#contributing-to-the-rails-documentation)\r\n\r\nThanks for contributing to Rails!"},"comment":{"url":"https://api.github.com/repos/rails/rails/issues/comments/387543861","html_url":"https://github.com/rails/rails/pull/32833#issuecomment-387543861","issue_url":"https://api.github.com/repos/rails/rails/issues/32833","id":387543861,"user":{"login":"ryandav","id":22416807,"avatar_url":"https://avatars3.githubusercontent.com/u/22416807?v=4","gravatar_id":"","url":"https://api.github.com/users/ryandav","html_url":"https://github.com/ryandav","followers_url":"https://api.github.com/users/ryandav/followers","following_url":"https://api.github.com/users/ryandav/following{/other_user}","gists_url":"https://api.github.com/users/ryandav/gists{/gist_id}","starred_url":"https://api.github.com/users/ryandav/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ryandav/subscriptions","organizations_url":"https://api.github.com/users/ryandav/orgs","repos_url":"https://api.github.com/users/ryandav/repos","events_url":"https://api.github.com/users/ryandav/events{/privacy}","received_events_url":"https://api.github.com/users/ryandav/received_events","type":"User","site_admin":false},"created_at":"2018-05-08T21:11:48Z","updated_at":"2018-05-08T21:11:48Z","author_association":"NONE","body":"@georgeclaghorn \r\n\r\nLooks like this change would affect the Rails Guides too:\r\n\r\nhttp://edgeguides.rubyonrails.org/active_storage_overview.html#attaching-file-io-objects in the section 3.3 Attaching File/IO Objects\r\n\r\nI can get going on that after these changes are done."}}
{"actor":{"display_login":"ryandav"}}