Description
PresignedPutObjectArgs args = new PresignedPutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithExpiry(60 * 60 * 24)
.WithHeaders(new Dictionary<string,string>()
{
{ "Content-Type", "text/plain" },
{ "Content-Length","343434"},
{ "AAAA","BBBB"}
});
var url = await _minioClient.PresignedPutObjectAsync(args);
Using the above code I have generated this presigned put url: http://localhost:9000/landingimages/1b9cdab7-60b8-4314-8faf-3edc78ee8ae5?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=UPLOADERUPLOADER%2F20240802%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240802T165608Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&aaaa=BBBB&content-length=343434&content-type=Minio.DataModel.Args.PresignedPutObjectArgs&X-Amz-Signature=1973fcfb6346941f8f848ed10a8919f39338be4febc7717cbf335e4967e87131
Upon checking the content-type param in the signed URL, I have noticed that content-type header has a rather unusual value.
To create the url PresignedPutObjectAsync
method calls CreateRequest
extension method located in RequestExtensions.cs
file:
public async Task<string> PresignedPutObjectAsync(PresignedPutObjectArgs args)
{
...
var requestMessageBuilder = await this.CreateRequest(HttpMethod.Put, args.BucketName,
args.ObjectName,
args.Headers, // contentType
Convert.ToString(args.GetType(), CultureInfo.InvariantCulture), // metaData
Utils.ObjectToByteArray(args.RequestBody)).ConfigureAwait(false);
....
}
Below is the implementation of the CreateRequest
:
internal static async Task<HttpRequestMessageBuilder> CreateRequest(this IMinioClient minioClient,
HttpMethod method,
string bucketName = null,
string objectName = null,
IDictionary<string, string> headerMap = null,
string contentType = "application/octet-stream",
ReadOnlyMemory<byte> body = default,
string resourcePath = null,
bool isBucketCreationRequest = false)
{
.....
if (headerMap is not null)
{
if (headerMap.TryGetValue(messageBuilder.ContentTypeKey, out var value) && !string.IsNullOrEmpty(value))
headerMap[messageBuilder.ContentTypeKey] = contentType;
foreach (var entry in headerMap) messageBuilder.AddOrUpdateHeaderParameter(entry.Key, entry.Value);
}
return messageBuilder;
}
My best guess is that Convert.ToString(args.GetType(), CultureInfo.InvariantCulture)
is wrongly passed for the argument string contentType
.
Also I didn't get why CreateRequest
method has contentType
as a parameter. Why not try to get it from headerMap
and set to default value if not found? Also, it seems like contentType
overrides headerMap
's Content-Type when headerMap
has Content-Type set, which should be the opposite?
If maintainers agree, I can open PR