Skip to content

Commit 0655c82

Browse files
omit accept-encoding from upload
1 parent 65dec3b commit 0655c82

6 files changed

Lines changed: 63 additions & 21 deletions

File tree

google-cloud-storage/acceptance/storage/bucket_test.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,19 @@
267267
_(bucket.lifecycle.count).must_equal original_count
268268
end
269269

270+
it "omits Accept-Encoding: gzip header for file uploads" do
271+
# Verify the service's global headers do not contain the gzip encoding
272+
global_headers = storage.service.service.request_options.header || {}
273+
_(global_headers["Accept-Encoding"]).wont_equal "gzip"
274+
275+
# By uploading a JSON file, we simulate the bug condition.
276+
# If the header were sent globally, the server might return gzipped JSON metadata, causing a parse error.
277+
uploaded = bucket.create_file StringIO.new('{"metadata":"test"}'), "test-upload-metadata.json", content_type: "application/json"
278+
279+
_(uploaded.name).must_equal "test-upload-metadata.json"
280+
uploaded.delete
281+
end
282+
270283
it "does not error when getting a file that does not exist" do
271284
random_bucket = storage.bucket "#{bucket_name}_does_not_exist"
272285
_(random_bucket).must_be :nil?

google-cloud-storage/acceptance/storage/file_test.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@
4242
bucket.files(versions: true).all { |f| f.delete generation: true rescue nil }
4343
end
4444

45+
it "does not send Accept-Encoding: gzip globally during file uploads" do
46+
# Verify the service's global headers do not contain the gzip encoding
47+
global_headers = storage.service.service.request_options.header || {}
48+
_(global_headers["Accept-Encoding"]).wont_equal "gzip"
49+
50+
# By uploading a JSON file, we simulate the bug condition.
51+
# If the header was sent, the server might return gzipped JSON metadata,
52+
# which the upload method wouldn't know how to parse, causing an error.
53+
uploaded = bucket.create_file StringIO.new('{"metadata":"test"}'), "upload-metadata.json", content_type: "application/json"
54+
_(uploaded.name).must_equal "upload-metadata.json"
55+
uploaded.delete
56+
end
57+
4558
it "should upload and download a file" do
4659
original = File.new files[:logo][:path]
4760
uploaded = bucket.create_file original, "CloudLogo.png",

google-cloud-storage/lib/google/cloud/storage/file.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ def update generation: nil,
985985
# @param [Boolean] skip_decompress Optional. If `true`, the data for a
986986
# Storage object returning a `Content-Encoding: gzip` response header
987987
# will *not* be automatically decompressed by this client library. The
988-
# default is `nil`. Note that all requests by this client library send
988+
# default is `nil`. Note that download requests by this client library send
989989
# the `Accept-Encoding: gzip` header, so decompressive transcoding is
990990
# not performed in the Storage service. (See [Transcoding of
991991
# gzip-compressed files](https://cloud.google.com/storage/docs/transcoding))

google-cloud-storage/lib/google/cloud/storage/service.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ def initialize project, credentials, retries: nil,
6464
@service.request_options.header ||= {}
6565
@service.request_options.header["x-goog-api-client"] =
6666
"gl-ruby/#{RUBY_VERSION} gccl/#{Google::Cloud::Storage::VERSION}"
67-
@service.request_options.header["Accept-Encoding"] = "gzip"
6867
@service.request_options.quota_project = quota_project if quota_project
6968
@service.request_options.max_elapsed_time = max_elapsed_time if max_elapsed_time
7069
@service.request_options.base_interval = base_interval if base_interval
@@ -586,6 +585,8 @@ def download_file bucket_name, file_path, target_path, generation: nil,
586585
key: nil, range: nil, user_project: nil, options: {}
587586
options = key_options(key).merge(options)
588587
options = range_header options, range
588+
options[:header] ||= {}
589+
options[:header]["Accept-Encoding"] = "gzip"
589590

590591
execute do
591592
service.get_object \

google-cloud-storage/test/google/cloud/storage/bucket_test.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,21 @@
694694
mock.verify
695695
end
696696

697+
it "omits Accept-Encoding: gzip header for file uploads" do
698+
new_file_name = random_file_path
699+
new_file_contents = StringIO.new "Hello world"
700+
701+
mock = Minitest::Mock.new
702+
mock.expect :insert_object, create_file_gapi(bucket.name, new_file_name) do |b_name, file_obj, **kwargs|
703+
headers = (kwargs[:options] && kwargs[:options][:header]) || {}
704+
b_name == bucket.name && headers["Accept-Encoding"] != "gzip"
705+
end
706+
707+
bucket.service.mocked_service = mock
708+
bucket.create_file new_file_contents, new_file_name
709+
mock.verify
710+
end
711+
697712
it "raises when given a file that does not exist" do
698713
bad_file_path = "/this/file/does/not/exist.ext"
699714

google-cloud-storage/test/google/cloud/storage/file_test.rb

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ def file.md5
221221

222222
mock = Minitest::Mock.new
223223
mock.expect :get_object, [tmpfile, download_http_resp],
224-
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: {}
224+
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
225225

226226
bucket.service.mocked_service = mock
227227

@@ -247,7 +247,7 @@ def file.md5
247247

248248
mock = Minitest::Mock.new
249249
mock.expect :get_object, [tmpfile, download_http_resp(gzip: true)],
250-
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: {}
250+
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
251251

252252
bucket.service.mocked_service = mock
253253

@@ -273,7 +273,7 @@ def file.md5
273273

274274
mock = Minitest::Mock.new
275275
mock.expect :get_object, [tmpfile, download_http_resp(gzip: true)],
276-
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: {}
276+
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
277277

278278
bucket.service.mocked_service = mock
279279

@@ -297,7 +297,7 @@ def file.md5
297297

298298
mock = Minitest::Mock.new
299299
mock.expect :get_object, [tmpfile, download_http_resp],
300-
[bucket.name, file.name], download_dest: tmpfile.path, generation: generation, user_project: nil, options: {}
300+
[bucket.name, file.name], download_dest: tmpfile.path, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
301301

302302
bucket.service.mocked_service = mock
303303

@@ -320,7 +320,7 @@ def file_user_project.md5
320320

321321
mock = Minitest::Mock.new
322322
mock.expect :get_object, [tmpfile, download_http_resp],
323-
[bucket.name, file_user_project.name], download_dest: tmpfile, generation: generation, user_project: "test", options: {}
323+
[bucket.name, file_user_project.name], download_dest: tmpfile, generation: generation, user_project: "test", options: { header: { "Accept-Encoding" => "gzip" } }
324324

325325
bucket.service.mocked_service = mock
326326

@@ -341,7 +341,7 @@ def file.md5
341341
downloadio = StringIO.new
342342
mock = Minitest::Mock.new
343343
mock.expect :get_object, [StringIO.new(data), download_http_resp],
344-
[bucket.name, file.name], download_dest: downloadio, generation: generation, user_project: nil, options: {}
344+
[bucket.name, file.name], download_dest: downloadio, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
345345

346346
bucket.service.mocked_service = mock
347347

@@ -362,7 +362,7 @@ def file.md5
362362

363363
mock = Minitest::Mock.new
364364
mock.expect :get_object, [StringIO.new(gzipped_data), download_http_resp(gzip: true)],
365-
[bucket.name, file.name], download_dest: downloadio, generation: generation, user_project: nil, options: {}
365+
[bucket.name, file.name], download_dest: downloadio, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
366366

367367
bucket.service.mocked_service = mock
368368

@@ -383,7 +383,7 @@ def file.md5
383383

384384
mock = Minitest::Mock.new
385385
mock.expect :get_object, [StringIO.new(gzipped_data), download_http_resp(gzip: true)],
386-
[bucket.name, file.name], download_dest: downloadio, generation: generation, user_project: nil, options: {}
386+
[bucket.name, file.name], download_dest: downloadio, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
387387

388388
bucket.service.mocked_service = mock
389389

@@ -404,7 +404,7 @@ def file.md5
404404

405405
mock = Minitest::Mock.new
406406
mock.expect :get_object, [StringIO.new("yay!"), download_http_resp],
407-
[bucket.name, file.name], download_dest: downloadio, generation: generation, user_project: nil, options: {}
407+
[bucket.name, file.name], download_dest: downloadio, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
408408

409409
bucket.service.mocked_service = mock
410410

@@ -427,7 +427,7 @@ def file.md5
427427

428428
mock = Minitest::Mock.new
429429
mock.expect :get_object, [nil, download_http_resp], # using encryption keys seems to return nil
430-
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: key_options
430+
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: key_headers.merge("Accept-Encoding" => "gzip") }
431431

432432
bucket.service.mocked_service = mock
433433

@@ -442,7 +442,7 @@ def file.md5
442442
Tempfile.open "google-cloud" do |tmpfile|
443443
mock = Minitest::Mock.new
444444
mock.expect :get_object, [tmpfile, download_http_resp],
445-
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: { 'Range' => 'bytes=3-6' }}
445+
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: { "Range" => "bytes=3-6", "Accept-Encoding" => "gzip" } }
446446

447447
bucket.service.mocked_service = mock
448448

@@ -457,7 +457,7 @@ def file.md5
457457
Tempfile.open "google-cloud" do |tmpfile|
458458
mock = Minitest::Mock.new
459459
mock.expect :get_object, [tmpfile, download_http_resp],
460-
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: { 'Range' => 'bytes=-6' }}
460+
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: { "Range" => "bytes=-6", "Accept-Encoding" => "gzip" } }
461461

462462
bucket.service.mocked_service = mock
463463

@@ -477,7 +477,7 @@ def file.crc32c; "crc32c="; end
477477
Tempfile.open "google-cloud" do |tmpfile|
478478
mock = Minitest::Mock.new
479479
mock.expect :get_object, [tmpfile, download_http_resp],
480-
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: {}
480+
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
481481

482482
bucket.service.mocked_service = mock
483483

@@ -504,7 +504,7 @@ def file.crc32c; "crc32c="; end
504504
Tempfile.open "google-cloud" do |tmpfile|
505505
mock = Minitest::Mock.new
506506
mock.expect :get_object, [tmpfile, download_http_resp],
507-
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: {}
507+
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
508508

509509
bucket.service.mocked_service = mock
510510

@@ -531,7 +531,7 @@ def file.crc32c; "crc32c="; end
531531
Tempfile.open "google-cloud" do |tmpfile|
532532
mock = Minitest::Mock.new
533533
mock.expect :get_object, [tmpfile, download_http_resp],
534-
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: {}
534+
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
535535

536536
bucket.service.mocked_service = mock
537537

@@ -558,7 +558,7 @@ def file.crc32c; "crc32c="; end
558558

559559
mock = Minitest::Mock.new
560560
mock.expect :get_object, [StringIO.new(data), download_http_resp],
561-
[bucket.name, file.name], download_dest: path, generation: 1234567890, user_project: nil, options: {}
561+
[bucket.name, file.name], download_dest: path, generation: 1234567890, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
562562

563563
bucket.service.mocked_service = mock
564564

@@ -577,7 +577,7 @@ def file.crc32c; "crc32c="; end
577577
Tempfile.open "google-cloud" do |tmpfile|
578578
mock = Minitest::Mock.new
579579
mock.expect :get_object, [tmpfile, download_http_resp],
580-
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: {}
580+
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
581581

582582
bucket.service.mocked_service = mock
583583

@@ -608,7 +608,7 @@ def file.crc32c; "crc32c="; end
608608
Tempfile.open "google-cloud" do |tmpfile|
609609
mock = Minitest::Mock.new
610610
mock.expect :get_object, [tmpfile, download_http_resp],
611-
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: {}
611+
[bucket.name, file.name], download_dest: tmpfile, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
612612

613613
bucket.service.mocked_service = mock
614614

@@ -633,7 +633,7 @@ def file.crc32c; "crc32c="; end
633633
Tempfile.open "google-cloud" do |tmpfile|
634634
mock = Minitest::Mock.new
635635
mock.expect :get_object, [tmpfile, download_http_resp],
636-
[bucket.name, file.name], download_dest: tmpfile.path, generation: generation, user_project: nil, options: {}
636+
[bucket.name, file.name], download_dest: tmpfile.path, generation: generation, user_project: nil, options: { header: { "Accept-Encoding" => "gzip" } }
637637

638638
bucket.service.mocked_service = mock
639639

0 commit comments

Comments
 (0)