{"action":"created","issue":{"url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-ruby/issues/2068","repository_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-ruby","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-ruby/issues/2068/labels{/name}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-ruby/issues/2068/comments","events_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-ruby/issues/2068/events","html_url":"https://github.com/GoogleCloudPlatform/google-cloud-ruby/pull/2068","id":318688189,"number":2068,"title":"Facilitate partial file downloads","user":{"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},"labels":[{"id":172905756,"url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-ruby/labels/api:%20storage","name":"api: storage","color":"f8f8f8","default":false},{"id":166382179,"url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-ruby/labels/cla:%20yes","name":"cla: yes","color":"c2e0c6","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2018-04-29T04:06:22Z","updated_at":"2018-04-29T23:49:39Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-ruby/pulls/2068","html_url":"https://github.com/GoogleCloudPlatform/google-cloud-ruby/pull/2068","diff_url":"https://github.com/GoogleCloudPlatform/google-cloud-ruby/pull/2068.diff","patch_url":"https://github.com/GoogleCloudPlatform/google-cloud-ruby/pull/2068.patch"},"body":"[Active Storage](https://github.com/rails/rails/tree/master/activestorage) requires partial download support from each of the clients it uses in order to:\r\n* Peek at objects for content type identification purposes without downloading them in full\r\n* Stream objects from cloud storage to tempfiles on disk in a consistent manner across all services\r\n\r\nThe Google Cloud Storage client, unlike the other clients Active Storage uses, does not provide this support. We currently work around the lack of partial download support by [manually](https://github.com/rails/rails/blob/3e8c660c11df5f650109fb44d060ea7eb0c7ea26/activestorage/lib/active_storage/service/gcs_service.rb#L51-L56) issuing a GET request with a `Range` header to a signed URL:\r\n\r\n```ruby\r\nfile = file_for(key)\r\nuri  = URI(file.signed_url(expires: 30.seconds))\r\n\r\nNet::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == \"https\") do |client|\r\n  client.get(uri, \"Range\" => \"bytes=#{range.begin}-#{range.exclude_end? ? range.end - 1 : range.end}\").body\r\nend\r\n```\r\n\r\nBecause we bypass the GCS client, we miss out on authenticated downloading, connection reuse, error handling, and more. This PR adds partial download support to the client, reducing the code above to the following:\r\n\r\n```ruby\r\nfile_for(key).download(range: range).string\r\n```"},"comment":{"url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-ruby/issues/comments/385291286","html_url":"https://github.com/GoogleCloudPlatform/google-cloud-ruby/pull/2068#issuecomment-385291286","issue_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-ruby/issues/2068","id":385291286,"user":{"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},"created_at":"2018-04-29T23:49:39Z","updated_at":"2018-04-29T23:49:39Z","author_association":"CONTRIBUTOR","body":"@frankyn, I added an acceptance test for partially downloading an encrypted file in 278f377 and confirmed that the acceptance tests pass locally."}}
{"actor":{"display_login":"georgeclaghorn"}}