Azure / Azurite

A lightweight server clone of Azure Storage that simulates most of the commands supported by it with minimal dependencies
MIT License
1.83k stars 324 forks source link

Azurite vs. Blob storage Range header inconsistency #1682

Open quinnj opened 2 years ago

quinnj commented 2 years ago

Which service(blob, file, queue, table) does this issue concern?

blob

Which version of the Azurite was used?

3.18

Where do you get Azurite? (npm, DockerHub, NuGet, Visual Studio Code Extension)

In the Julia ecosystem, we have a system for packaging cross-platform "binary artifacts"; so the azurite_jll repo is a Julia package that provides a node runtime & azurite javascript files that can run on supported platforms.

What's the Node.js version?

16.15 (as provided here)

What problem was encountered?

When I make a signed request with the Range header like:

GET /devstoreaccount1/jl-azurite-23624/test6.csv HTTP/1.1
│ Range: bytes=0-8388607
│ Host: 127.0.0.1:41606
│ Accept: */*
│ User-Agent: HTTP.jl/1.8.0-rc3
│ Content-Length: 0
│ Accept-Encoding: gzip
│ x-ms-date: Wed, 14 Sep 2022 18:54:51 GMT
│ x-ms-version: 2020-04-08
│ Authorization: SharedKey devstoreaccount1:/2uZrhkeWUF+uyIURjrg7PKCTImDK+3J2kVEFy51QVA=

I get a successful 206 response back, like:

HTTP/1.1 206 Partial Content
│ Server: Azurite-Blob/3.18.0
│ last-modified: Wed, 14 Sep 2022 18:45:09 GMT
│ x-ms-creation-time: Wed, 14 Sep 2022 18:45:09 GMT
│ content-length: 0
│ content-type: application/octet-stream
│ content-range: bytes 0--1/0
│ etag: "0x23A7EC871C26440"
│ content-md5: 1B2M2Y8AsgTpgAmY7PhCfg==
│ x-ms-blob-type: BlockBlob
│ x-ms-lease-state: available
│ x-ms-lease-status: unlocked
│ x-ms-request-id: 8cb500af-903f-45a5-b9e7-636bc342cf50
│ x-ms-version: 2021-08-06
│ accept-ranges: bytes
│ date: Wed, 14 Sep 2022 18:54:51 GMT
│ x-ms-server-encrypted: true
│ x-ms-blob-content-md5: 1B2M2Y8AsgTpgAmY7PhCfg==
│ Connection: keep-alive
│ Keep-Alive: timeout=5

But issuing the same kind of "Range" request against actual blob storage results in a response like:

HTTP/1.1 416 Requested Range Not Satisfiable
│ Content-Length: 249
│ Content-Type: application/xml
│ Content-Range: bytes */0
│ Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
│ x-ms-request-id: xxxxxxx
│ x-ms-version: 2020-04-08
│ x-ms-error-code: InvalidRange
│ Date: Wed, 14 Sep 2022 18:56:17 GMT
│
│ <?xml version="1.0" encoding="utf-8"?><Error><Code>InvalidRange</Code><Message>The range specified is invalid for the current size of the resource.
│ RequestId:xxxxxxxx
│ Time:2022-09-14T18:56:18.1411730Z</Message></Error>"""
blueww commented 2 years ago

@quinnj

I can't repro this issue on real Azure server. When I send following request to Azure server to a blob with only 512B length, server returns 206. (I use "x-ms-range", per rest API doc, "Range" and "x-ms-range" should have same functionality in this API.)

There might be other reason caused your request fail on server. Would you please share your failed request trace on server (especially the request ID), hide credential if any, then we might can help to look why it fails?

GET https://[accountName].blob.core.windows.net/sparkconnectortests1/test.txt HTTP/1.1
x-ms-range: bytes=0-8388607
x-ms-client-request-id: 1b2dff67-ab29-4cbe-a02c-5405f551f112
User-Agent: Azure-Storage/11.2.2 (.NET Core; Win32NT 10.0.19044.0)
x-ms-version: 2019-07-07
x-ms-date: Thu, 15 Sep 2022 08:19:25 GMT
Authorization: SharedKey [accountName]:***
Host: [accountName].blob.core.windows.net
Connection: Keep-Alive

HTTP/1.1 206 Partial Content
Content-Length: 512
Content-Type: application/octet-stream
Content-Range: bytes 0-511/512
Last-Modified: Thu, 15 Sep 2022 08:17:09 GMT
Accept-Ranges: bytes
ETag: "0x8DA96F2AF643FF6"
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: ab49821a-a01e-0084-45dc-c8a8c3000000
x-ms-client-request-id: 1b2dff67-ab29-4cbe-a02c-5405f551f112
x-ms-version: 2019-07-07
x-ms-meta-tag2: value22
x-ms-meta-tag1: value1
x-ms-creation-time: Thu, 15 Sep 2022 08:17:09 GMT
x-ms-blob-content-md5: xymujwc2zDd6l2emYOqgTg==
x-ms-lease-status: unlocked
x-ms-lease-state: available
x-ms-blob-type: BlockBlob
x-ms-server-encrypted: true
Date: Thu, 15 Sep 2022 08:20:30 GMT

***
quinnj commented 2 years ago

Oof, so sorry. I totally forgot to add the most important detail. The discrepancy is only manifest on 0-byte objects. I.e. if I upload an empty object, then try to do a Range request on the empty object: azurite says that's ok and returns, but real azure blob storage returns 416.

blueww commented 2 years ago

@quinnj I can repro this error with a 0 size blob.

We can fix this by check the blob properties ContentLength and return error then contentlenth is 0, in https://github.com/Azure/Azurite/blob/aeba39deac9205abae2e3dc421147809fd39ff74/src/blob/handlers/BlobHandler.ts#L102.

Azurite welcome contribution! It would be great if you can raise a PR to fix this issue.