Describe the bug
Related to this issue on Azurite:
https://github.com/Azure/Azurite/issues/379
If a host name is used (instead of localhost or 172.0.0.1) to emulate a blob store locally, the client SDK strips off the account name in the URL's to the storage, and the account name specified in the connection string is ignored.
Exception or Stack Trace
System.Xml.XmlException : Root element is missing.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options)
at System.Xml.Linq.XDocument.Load(Stream stream, LoadOptions options)
at Azure.Storage.Blobs.BlobRestClient.Container.CreateAsync_CreateResponse(Response response)
at Azure.Storage.Blobs.BlobRestClient.Container.CreateAsync(ClientDiagnostics clientDiagnostics, HttpPipeline pipeline, Uri resourceUri, PublicAccessType access, Nullable`1 timeout, IDictionary`2 metadata, String requestId, Boolean async, String operationName, CancellationToken cancellationToken)
at Azure.Storage.Blobs.BlobContainerClient.CreateInternal(PublicAccessType publicAccessType, IDictionary`2 metadata, Boolean async, CancellationToken cancellationToken, String operationName)
at Azure.Storage.Blobs.BlobContainerClient.CreateIfNotExistsInternal(PublicAccessType publicAccessType, IDictionary`2 metadata, Boolean async, CancellationToken cancellationToken)
at Azure.Storage.Blobs.BlobContainerClient.CreateIfNotExistsAsync(PublicAccessType publicAccessType, IDictionary`2 metadata, CancellationToken cancellationToken)
If I change the connection string from azurite to 127.0.0.1 it all works fine.
To Reproduce
When connection string looks like this: (127.0.0.1 is the host):
AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://azurite:10000/devstoreaccount1;
The generated requests look like this, which is correct:
"PUT /devstoreaccount1/images?restype=container" HTTP/1.1 201
When connection string looks like this (azurite is the host name):
AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://azurite:10000/devstoreaccount1;
The generated requests look like this:
"PUT /images?restype=container HTTP/1.1" 400 -
Steps to reproduce the behavior:
Code Snippet
[Fact]
public async Task CanUploadUsingHostName()
{
var container = new BlobContainerClient(ConnectionString, "bifs");
var ifNotExistsAsync = await container.CreateIfNotExistsAsync();
await using var stream = File.OpenRead(@".\test\output\3ee9bc41-40ea-4d05-b180-e74bd5065622\images\00000000.jpg");
await container.UploadBlobAsync("test.jpg", stream);
}
Expected behavior
When AccountName is specified in the connection string, I would expect the client to behave the same (generate requests with the same URL's) regardless of the host name. Especially if it is not a host name specific to Azure Blob Storage.
Setup (please complete the following information):
Additional context
Stack Overflow question here:
https://stackoverflow.com/questions/59615330/connecting-to-azurite-using-a-hostname-fails/59651621#59651621
Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @xgithubtriage
Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @xgithubtriage
/cc @JoshLove-msft
We will need to update the BlobUriBuilder/QueueUriBuilder logic to correctly build the Uri when using a dev store account with a host name. Emulator doesn't support files.
Please triage tomorrow.
@amishra-dev @seanmcc-msft Sorry to bother you two but has there been any progress in this issue? I've run into the same thing trying to dockerize multiple azurite instances to test some code that I'm working on.
Hi, having the same issue here trying to test a dockerized .NET Core app in a Compose file with Azurite. Seems like a pretty big problem.
Ha! if @markrendle thinks it's a big problem, it should be fixed pretty quickly, right @JoshLove-msft? ;p
There is an open PR looking at fixing this - https://github.com/Azure/azure-sdk-for-net/pull/10564
Azure Blob Storage on IoT Edge is also affected by this. Clients should refer to storage by its container name and right now this is not working as expected.
var connection1 = "BlobEndpoint=http://modulename:11002/myaccount;AccountName=myaccount;AccountKey=notimportant; DefaultEndpointsProtocol=http";
var client = new BlobServiceClient(connection1);
var container1 = client.GetBlobContainerClient("containername");
var container2 = new BlobContainerClient(connection1, "containername");
container1.Uri is correct: http://modulename:11002/myaccount/containername
container2.Uri is not correct: http://modulename:11002/containername
If we use an IP address instead of “modulename” both URIs are formed correctly.
We did some testing trying to work around this. We found that with Azure.Storage.Blobs release 12.0.0 we could not reproduce this issue. When we upgraded Azure.Storage.Blobs to 12.4.4, the failure occurred. Not sure if this is helpful or not, but hoping it will make crafting a fix easier!
PR #13124 should fix this. Is there anything I can do to help get that reviewed and merged?
@mattschoutends, we’ll take a look at the PR
This is still an issue for Queue's - only blobs where resolved in the PR.
Created issue #16542 and will hopefully submit a PR 🤞🏻
Most helpful comment
There is an open PR looking at fixing this - https://github.com/Azure/azure-sdk-for-net/pull/10564