@@ -230,7 +230,8 @@ Future<void> StorageReferenceInternal::DeleteLastResult() {
230230// Handy utility function, since REST calls have similar setup and teardown.
231231void StorageReferenceInternal::PrepareRequest (rest::Request* request,
232232 const char * url,
233- const char * method) {
233+ const char * method,
234+ const char * content_type) {
234235 request->set_url (url);
235236 request->set_method (method);
236237
@@ -240,6 +241,10 @@ void StorageReferenceInternal::PrepareRequest(rest::Request* request,
240241 std::string auth_header = " Bearer " + token;
241242 request->add_header (" Authorization" , auth_header.c_str ());
242243 }
244+ // if content_type was specified, add a header.
245+ if (content_type != nullptr && *content_type != ' \0 ' ) {
246+ request->add_header (" Content-Type" , content_type);
247+ }
243248 // Unfortunately the storage backend rejects requests with the complete
244249 // user agent specified by the x-goog-api-client header so we only use
245250 // the X-Firebase-Storage-Version header to attribute the client.
@@ -404,10 +409,12 @@ Future<Metadata> StorageReferenceInternal::PutBytes(
404409
405410Future<Metadata> StorageReferenceInternal::PutBytesInternal (
406411 const void * buffer, size_t buffer_size, Listener* listener,
407- Controller* controller_out) {
412+ Controller* controller_out, const char * content_type ) {
408413 auto * future_api = future ();
409414 auto handle = future_api->SafeAlloc <Metadata>(kStorageReferenceFnPutBytes );
410- auto send_request_funct{[&, buffer, buffer_size, listener,
415+
416+ std::string content_type_str = content_type ? content_type : " " ;
417+ auto send_request_funct{[&, content_type_str, buffer, buffer_size, listener,
411418 controller_out]() -> BlockingResponse* {
412419 auto * future_api = future ();
413420 auto handle =
@@ -416,7 +423,8 @@ Future<Metadata> StorageReferenceInternal::PutBytesInternal(
416423 storage::internal::RequestBinary* request =
417424 new storage::internal::RequestBinary (static_cast <const char *>(buffer),
418425 buffer_size);
419- PrepareRequest (request, storageUri_.AsHttpUrl ().c_str (), rest::util::kPost );
426+ PrepareRequest (request, storageUri_.AsHttpUrl ().c_str (), rest::util::kPost ,
427+ content_type_str.c_str ());
420428 ReturnedMetadataResponse* response =
421429 new ReturnedMetadataResponse (handle, future_api, AsStorageReference ());
422430 RestCall (request, request->notifier (), response, handle.get (), listener,
@@ -442,8 +450,9 @@ Future<Metadata> StorageReferenceInternal::PutBytes(
442450 // different storage reference than the original, so the caller of this
443451 // function can't access it via PutFileLastResult.
444452 Future<Metadata> putbytes_internal =
445- data->storage_ref .internal_ ->PutBytesInternal (buffer, buffer_size,
446- listener, controller_out);
453+ data->storage_ref .internal_ ->PutBytesInternal (
454+ buffer, buffer_size, listener, controller_out,
455+ metadata ? metadata->content_type () : nullptr );
447456
448457 SetupMetadataChain (putbytes_internal, data);
449458
@@ -466,36 +475,38 @@ Future<Metadata> StorageReferenceInternal::PutFile(const char* path,
466475}
467476
468477Future<Metadata> StorageReferenceInternal::PutFileInternal (
469- const char * path, Listener* listener, Controller* controller_out) {
478+ const char * path, Listener* listener, Controller* controller_out,
479+ const char * content_type) {
470480 auto * future_api = future ();
471481 auto handle = future_api->SafeAlloc <Metadata>(kStorageReferenceFnPutFile );
472482
473483 std::string final_path = StripProtocol (path);
474- auto send_request_funct{
475- [&, final_path, listener, controller_out]() -> BlockingResponse* {
476- auto * future_api = future ();
477- auto handle =
478- future_api->SafeAlloc <Metadata>(kStorageReferenceFnPutFileInternal );
479-
480- // Open the file, calculate the length.
481- storage::internal::RequestFile* request (
482- new storage::internal::RequestFile (final_path.c_str (), 0 ));
483- if (!request->IsFileOpen ()) {
484- delete request;
485- future_api->Complete (handle, kErrorUnknown , " Could not read file." );
486- return nullptr ;
487- } else {
488- // Everything is good. Fire off the request.
489- ReturnedMetadataResponse* response = new ReturnedMetadataResponse (
490- handle, future_api, AsStorageReference ());
491-
492- PrepareRequest (request, storageUri_.AsHttpUrl ().c_str (),
493- rest::util::kPost );
494- RestCall (request, request->notifier (), response, handle.get (),
495- listener, controller_out);
496- return response;
497- }
498- }};
484+ std::string content_type_str = content_type ? content_type : " " ;
485+ auto send_request_funct{[&, final_path, content_type_str, listener,
486+ controller_out]() -> BlockingResponse* {
487+ auto * future_api = future ();
488+ auto handle =
489+ future_api->SafeAlloc <Metadata>(kStorageReferenceFnPutFileInternal );
490+
491+ // Open the file, calculate the length.
492+ storage::internal::RequestFile* request (
493+ new storage::internal::RequestFile (final_path.c_str (), 0 ));
494+ if (!request->IsFileOpen ()) {
495+ delete request;
496+ future_api->Complete (handle, kErrorUnknown , " Could not read file." );
497+ return nullptr ;
498+ } else {
499+ // Everything is good. Fire off the request.
500+ ReturnedMetadataResponse* response = new ReturnedMetadataResponse (
501+ handle, future_api, AsStorageReference ());
502+
503+ PrepareRequest (request, storageUri_.AsHttpUrl ().c_str (),
504+ rest::util::kPost , content_type_str.c_str ());
505+ RestCall (request, request->notifier (), response, handle.get (), listener,
506+ controller_out);
507+ return response;
508+ }
509+ }};
499510 SendRequestWithRetry (kStorageReferenceFnPutFileInternal , send_request_funct,
500511 handle, storage_->max_upload_retry_time ());
501512 return PutFileLastResult ();
@@ -516,8 +527,9 @@ Future<Metadata> StorageReferenceInternal::PutFile(const char* path,
516527 // different storage reference than the original, so the caller of this
517528 // function can't access it via PutFileLastResult.
518529 Future<Metadata> putfile_internal =
519- data->storage_ref .internal_ ->PutFileInternal (path, listener,
520- controller_out);
530+ data->storage_ref .internal_ ->PutFileInternal (
531+ path, listener, controller_out,
532+ metadata ? metadata->content_type () : nullptr );
521533
522534 SetupMetadataChain (putfile_internal, data);
523535
@@ -579,11 +591,11 @@ Future<Metadata> StorageReferenceInternal::UpdateMetadata(
579591 new ReturnedMetadataResponse (handle, future_api, AsStorageReference ());
580592
581593 storage::internal::Request* request = new storage::internal::Request ();
582- PrepareRequest (request, storageUri_.AsHttpUrl ().c_str (), " PATCH" );
594+ PrepareRequest (request, storageUri_.AsHttpUrl ().c_str (), " PATCH" ,
595+ " application/json" );
583596
584597 std::string metadata_json = metadata->internal_ ->ExportAsJson ();
585598 request->set_post_fields (metadata_json.c_str (), metadata_json.length ());
586- request->add_header (" Content-Type" , " application/json" );
587599
588600 RestCall (request, request->notifier (), response, handle.get (), nullptr ,
589601 nullptr );
0 commit comments