Browse Source

Bug 1602: Set Content Type of files uploaded to S3

https://winscp.net/tracker/1602

Source commit: 325c637fbb3be8a48fca6861d07d9b4ce5cbee4b
Martin Prikryl 7 years ago
parent
commit
414bd6a439
4 changed files with 32 additions and 13 deletions
  1. 12 0
      source/core/Common.cpp
  2. 1 0
      source/core/Common.h
  3. 18 3
      source/core/S3FileSystem.cpp
  4. 1 10
      source/core/WebDAVFileSystem.cpp

+ 12 - 0
source/core/Common.cpp

@@ -3686,3 +3686,15 @@ UnicodeString __fastcall StripEllipsis(const UnicodeString & S)
   }
   return Result;
 }
+//---------------------------------------------------------------------------
+UnicodeString __fastcall GetFileMimeType(const UnicodeString & FileName)
+{
+  wchar_t * MimeOut = NULL;
+  UnicodeString Result;
+  if (FindMimeFromData(NULL, FileName.c_str(), NULL, 0, NULL, FMFD_URLASFILENAME, &MimeOut, 0) == S_OK)
+  {
+    Result = MimeOut;
+    CoTaskMemFree(MimeOut);
+  }
+  return Result;
+}

+ 1 - 0
source/core/Common.h

@@ -163,6 +163,7 @@ bool __fastcall IsHttpOrHttpsUrl(const UnicodeString & S);
 UnicodeString __fastcall ChangeUrlProtocol(const UnicodeString & S, const UnicodeString & Protocol);
 void __fastcall LoadScriptFromFile(UnicodeString FileName, TStrings * Lines);
 UnicodeString __fastcall StripEllipsis(const UnicodeString & S);
+UnicodeString __fastcall GetFileMimeType(const UnicodeString & FileName);
 //---------------------------------------------------------------------------
 typedef void __fastcall (__closure* TProcessLocalFileEvent)
   (const UnicodeString FileName, const TSearchRec Rec, void * Param);

+ 18 - 3
source/core/S3FileSystem.cpp

@@ -1314,6 +1314,21 @@ void __fastcall TS3FileSystem::Source(
 
   TLibS3BucketContext BucketContext = GetBucketContext(BucketName);
 
+  UTF8String ContentType = UTF8String(GetFileMimeType(Handle.FileName));
+  S3PutProperties PutProperties =
+    {
+      (ContentType.IsEmpty() ? NULL : ContentType.c_str()),
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      -1,
+      S3CannedAclPrivate,
+      0,
+      NULL,
+      0
+    };
+
   int Parts = std::max(1, static_cast<int>((Handle.Size + S3MultiPartChunkSize - 1) / S3MultiPartChunkSize));
   bool Multipart = (Parts > 1);
 
@@ -1331,7 +1346,7 @@ void __fastcall TS3FileSystem::Source(
 
       S3MultipartInitialHandler Handler = { CreateResponseHandler(), &LibS3MultipartInitialCallback };
 
-      S3_initiate_multipart(&BucketContext, StrToS3(Key), 0, &Handler, FRequestContext, FTimeout, &Data);
+      S3_initiate_multipart(&BucketContext, StrToS3(Key), &PutProperties, &Handler, FRequestContext, FTimeout, &Data);
 
       CheckLibS3Error(Data, true);
 
@@ -1378,13 +1393,13 @@ void __fastcall TS3FileSystem::Source(
           int PartLength = std::min(S3MultiPartChunkSize, static_cast<int>(Stream->Size - Stream->Position));
           FTerminal->LogEvent(FORMAT(L"Uploading part %d [%s]", (Part, IntToStr(PartLength))));
           S3_upload_part(
-            &BucketContext, StrToS3(Key), NULL, &UploadPartHandler, Part, MultipartUploadId.c_str(),
+            &BucketContext, StrToS3(Key), &PutProperties, &UploadPartHandler, Part, MultipartUploadId.c_str(),
             PartLength, FRequestContext, FTimeout, &Data);
         }
         else
         {
           S3PutObjectHandler PutObjectHandler = { CreateResponseHandler(), LibS3PutObjectDataCallback };
-          S3_put_object(&BucketContext, StrToS3(Key), Handle.Size, NULL, FRequestContext, FTimeout, &PutObjectHandler, &Data);
+          S3_put_object(&BucketContext, StrToS3(Key), Handle.Size, &PutProperties, FRequestContext, FTimeout, &PutObjectHandler, &Data);
         }
 
         // The "exception" was already seen by the user, its presence mean an accepted abort of the operation.

+ 1 - 10
source/core/WebDAVFileSystem.cpp

@@ -1272,16 +1272,7 @@ void __fastcall TWebDAVFileSystem::Source(
     // (not really true as we do not support changing file name on overwrite dialog)
     Action.Destination(DestFullName);
 
-    wchar_t * MimeOut = NULL;
-    if (FindMimeFromData(NULL, DestFileName.c_str(), NULL, 0, NULL, FMFD_URLASFILENAME, &MimeOut, 0) == S_OK)
-    {
-      FUploadMimeType = MimeOut;
-      CoTaskMemFree(MimeOut);
-    }
-    else
-    {
-      FUploadMimeType = L"";
-    }
+    FUploadMimeType = GetFileMimeType(DestFileName);
 
     FILE_OPERATION_LOOP_BEGIN
     {