Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UploadStreamToBlockBlob: blob access conditions are ignored #17152

Closed
ItalyPaleAle opened this issue Feb 23, 2022 · 3 comments
Closed

UploadStreamToBlockBlob: blob access conditions are ignored #17152

ItalyPaleAle opened this issue Feb 23, 2022 · 3 comments
Assignees
Labels
bug Client Storage

Comments

@ItalyPaleAle
Copy link
Member

@ItalyPaleAle ItalyPaleAle commented Feb 23, 2022

Bug Report

  • import path of package in question: github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0
  • output of go version: go version go1.17.5 linux/arm64

(This is a spin-off from #17131 which identified the error as something different than I originally thought)

You can repro with the code below (fill the constants at the top):

package main

import (
	"context"
	"fmt"
	"io"
	"math/rand"
	"os"
	"time"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

// Set these
const account = "***"
const accessKey = "***"

// For these tests, I used 2 random images from Unsplash (because those are relatively large files and are free)
// Feel free to use any other file name here
const testFile1 = "dave-goudreau--W_vDl5Ll8M-unsplash.jpg"
const testFile2 = "katharina-bill-dSc2aoQmaZk-unsplash.jpg"

func main() {
	rand.Seed(time.Now().UnixNano())

	containerClient, err := setupContainer("c" + RandString(5))
	if err != nil {
		panic(err)
	}

	in := openFile(testFile1)
	defer in.Close()

	err = uploadToAzure(
		containerClient,
		"testblob",
		in,
		nil,
	)
	if err != nil {
		panic(err)
	}

	// Upload again: this should return an error
	in = openFile(testFile2)
	defer in.Close()
	err = uploadToAzure(
		containerClient,
		"testblob",
		in,
		nil,
	)
	if err == nil {
		panic("Expected error, got nil")
	}
	fmt.Println(err)
}

const letters = "abcdefghijklmnopqrstuvwxyz0123456789"

func RandString(n int) string {
	b := make([]byte, n)
	for i := range b {
		b[i] = letters[rand.Intn(len(letters))]
	}
	return string(b)
}

func openFile(name string) io.ReadCloser {
	in, err := os.Open(name)
	if err != nil {
		panic(err)
	}
	return in
}

func setupContainer(container string) (*azblob.ContainerClient, error) {
	storageURL := fmt.Sprintf("https://%s.blob.core.windows.net", account)
	cred, err := azblob.NewSharedKeyCredential(account, accessKey)
	if err != nil {
		return nil, err
	}
	service, err := azblob.NewServiceClientWithSharedKey(storageURL, cred, &azblob.ClientOptions{
		Telemetry: policy.TelemetryOptions{
			Disabled: true,
		},
	})
	if err != nil {
		return nil, err
	}
	containerClient := service.NewContainerClient(container)
	_, err = containerClient.Create(context.Background(), &azblob.CreateContainerOptions{
		Access: nil,
	})
	if err != nil {
		return nil, err
	}
	return &containerClient, nil
}

func uploadToAzure(containerClient *azblob.ContainerClient, name string, in io.Reader, metadata map[string]string) error {
	blob := containerClient.NewBlockBlobClient(name)
	ifNoneMatch := "*"
	opts := azblob.UploadStreamToBlockBlobOptions{
		BufferSize: 5 * 1024 * 1024,
		MaxBuffers: 2,
		BlobAccessConditions: &azblob.BlobAccessConditions{
			ModifiedAccessConditions: &azblob.ModifiedAccessConditions{
				IfNoneMatch: &ifNoneMatch,
			},
		},
		Metadata: metadata,
	}
	res, err := blob.UploadStreamToBlockBlob(context.Background(), in, opts)
	if err != nil {
		return err
	}
	fmt.Println(res.RawResponse.StatusCode)

	return nil
}

Expected result:

  • First file should be uploaded correctly
  • Second file should fail to be uploaded because of the ifNoneMatch condition set to "*"
  • Second invocation of uploadToAzure should return an error, and the status code shown from the second method should not be 2xx

Actual result:

  • First file is uploaded then overwritten by the second file
  • uploadToAzure never returns an error, and status code is always 2xx

CC: @zezha-msft

@msftbot msftbot bot added the needs-triage label Feb 23, 2022
@zezha-msft zezha-msft added bug and removed needs-triage labels Feb 23, 2022
@RickWinter RickWinter added Storage Client labels Mar 31, 2022
@mohsha-msft
Copy link
Member

@mohsha-msft mohsha-msft commented Apr 8, 2022

Hey @ItalyPaleAle ,

Thanks for reaching out!
I have fixed this issue and will be releasing it in the next release.

@ItalyPaleAle
Copy link
Member Author

@ItalyPaleAle ItalyPaleAle commented Apr 8, 2022

Thanks for the update! This is great news

@mohsha-msft
Copy link
Member

@mohsha-msft mohsha-msft commented Apr 20, 2022

Hey @ItalyPaleAle ,
azblob v0.4.0 is now publically available. I have fixed the issue here and here.

Please reach out and reopen the issue if it still persists.

Thanks a lot for your feedbacks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Client Storage
Projects
None yet
Development

No branches or pull requests

4 participants