scireum/s3ninja

Exception: No such host is known when using s3 .NET API PutObjectAsync

lesscodedotnet opened this issue · 2 comments

I'm not sure if what I'm trying is actually supposed to work with s3ninja:

using System;
using System.Threading.Tasks;
using Amazon.Runtime;
using Amazon.S3;
using Amazon.S3.Model;

namespace s3demo
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var key = "...";
            var secret = "...";
            var creds = new BasicAWSCredentials(key, secret);
            var config = new AmazonS3Config {
                ServiceURL = "http://localhost:9444"
            };
            var client = new AmazonS3Client(creds, config);
            var buckets = await client.ListBucketsAsync();
            foreach (var bucket in buckets.Buckets) {
                Console.WriteLine(bucket.BucketName);
            }
            var putObjectRequest = new PutObjectRequest {
                    BucketName = "mybucket",
                    Key = "blah",
                    ContentBody = "sample text"
            };
            var response = await client.PutObjectAsync(putObjectRequest);
            Console.WriteLine(response.HttpStatusCode);
        }
    }
}

This code works fine against a real s3 account in the us-east-1 region.
The exact same code, when run against an s3ninja instance running locally gives the following after about 30 seconds:

Unhandled exception. System.Net.Http.HttpRequestException: No such host is known.
 ---> System.Net.Sockets.SocketException (11001): No such host is known.
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken
cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cance
llationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellati
onToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, Cancellat
ionToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationToke
nSource cts, Boolean disposeCts)
   at Amazon.Runtime.HttpWebRequestMessage.GetResponseAsync(CancellationToken cancellationToken)
   at Amazon.Runtime.Internal.HttpHandler`1.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RedirectHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.Unmarshaller.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.S3.Internal.AmazonS3ResponseHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.ErrorHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CredentialsRetriever.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.S3.Internal.AmazonS3ExceptionHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.MetricsHandler.InvokeAsync[T](IExecutionContext executionContext)
   at s3demo.Program.Main(String[] args) in s3demo\Program.cs:line 30
   at s3demo.Program.<Main>(String[] args)

The MetricsHandler holding up the show here is clearly trying to talk to something that doesn't exist, but after tinkering with a bunch of options on AmazonS3Config I can't make it work.

Any ideas?

Hello @lesscodedotnet 👋 Thanks for getting in touch. Looks to me like a problem relating to subdomain-style access, i.e. <bucket>.<host>/<key>. Can you enable path-style access somehow, i.e. <host>/<bucket>/<key>? (I am not set up to check .NET samples myself 😔) To make subdomain-style access work, you may need to edit your hosts file to route traffic to your local S3 Ninja server.

Ah, thank you! I had to use ForcePathStyle = true on the AmazonS3Config. Seems so obvious to me now.