forked from Azure/azure-sdk-for-js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[core-http] support disabling decompression in node-fetch client (Azu…
…re#7878) Azure Blob Storage allows setting content encoding of a blob that stores compressed data. Browsers or other web clients can decompress accordingly when consuming the content of the blob. For NodeJS our node-fetch http client supports gzip/defalte content encoding by default thus de-compress the data in `download()` and similar methods. This causes problems, mainly, - upload and download using storage sdk clients are inconsistent. - retry for partial response wouldn't work in the decompressed stream. This change adds support to set the `compress` option to false using a request policy. Related to Azure#6411.
- Loading branch information
1 parent
aa8d4eb
commit 78917a5
Showing
10 changed files
with
240 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
sdk/core/core-http/src/policies/disableResponseDecompressionPolicy.browser.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
/* | ||
* NOTE: When moving this file, please update "browser" section in package.json | ||
*/ | ||
import { BaseRequestPolicy, RequestPolicy, RequestPolicyOptions } from './requestPolicy'; | ||
import { WebResource } from '../webResource'; | ||
import { HttpOperationResponse } from '../httpOperationResponse'; | ||
|
||
const DisbleResponseDecompressionNotSupportedInBrowser = new Error("DisableResponseDecompressionPolicy is not supported in browser environment"); | ||
|
||
/** | ||
* {@link DisableResponseDecompressionPolicy} is not supported in browser and attempting | ||
* to use it will results in error being thrown. | ||
*/ | ||
export function disableResponseDecompressionPolicy() { | ||
return { | ||
create: (_nextPolicy: RequestPolicy, _options: RequestPolicyOptions) => { | ||
throw DisbleResponseDecompressionNotSupportedInBrowser; | ||
} | ||
}; | ||
} | ||
|
||
export class DisableResponseDecompressionPolicy extends BaseRequestPolicy { | ||
constructor( | ||
nextPolicy: RequestPolicy, | ||
options: RequestPolicyOptions, | ||
) { | ||
super(nextPolicy, options); | ||
throw DisbleResponseDecompressionNotSupportedInBrowser; | ||
} | ||
|
||
public async sendRequest(_request: WebResource): Promise<HttpOperationResponse> { | ||
throw DisbleResponseDecompressionNotSupportedInBrowser; | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
sdk/core/core-http/src/policies/disableResponseDecompressionPolicy.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
import { BaseRequestPolicy, RequestPolicy, RequestPolicyOptions } from './requestPolicy'; | ||
import { WebResource } from '../webResource'; | ||
import { HttpOperationResponse } from '../httpOperationResponse'; | ||
|
||
/** | ||
* Returns a request policy factory that can be used to create an instance of | ||
* {@link DisableResponseDecompressionPolicy}. | ||
*/ | ||
export function disableResponseDecompressionPolicy() { | ||
return { | ||
create: (nextPolicy: RequestPolicy, options: RequestPolicyOptions) => { | ||
return new DisableResponseDecompressionPolicy(nextPolicy, options); | ||
} | ||
}; | ||
} | ||
|
||
/** | ||
* A policy to disable response decompression according to Accept-Encoding header | ||
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding | ||
*/ | ||
export class DisableResponseDecompressionPolicy extends BaseRequestPolicy { | ||
/** | ||
* Creates an instance of DisableResponseDecompressionPolicy. | ||
* | ||
* @param {RequestPolicy} nextPolicy | ||
* @param {RequestPolicyOptions} options | ||
*/ | ||
constructor( | ||
nextPolicy: RequestPolicy, | ||
options: RequestPolicyOptions | ||
) { | ||
super(nextPolicy, options); | ||
} | ||
|
||
/** | ||
* Sends out request. | ||
* | ||
* @param {WebResource} request | ||
* @returns {Promise<HttpOperationResponse>} | ||
*/ | ||
public async sendRequest(request: WebResource): Promise<HttpOperationResponse> { | ||
request.decompressResponse = false; | ||
return this._nextPolicy.sendRequest(request); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
sdk/core/core-http/test/policies/disableResponseDecompressionPolicy.browser.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
import "chai/register-should"; | ||
import { RequestPolicyOptions } from "../../src/policies/requestPolicy"; | ||
import { WebResource } from "../../src/webResource"; | ||
import { HttpHeaders } from "../../src/httpHeaders"; | ||
import { disableResponseDecompressionPolicy, DisableResponseDecompressionPolicy } from "../../src/policies/disableResponseDecompressionPolicy"; | ||
import { HttpClient, ServiceClient, Serializer } from '../../src/coreHttp'; | ||
|
||
describe("DisableResponseDecompressionPolicy (browser)", function() { | ||
const emptyRequestPolicy = { | ||
sendRequest: (_: WebResource) => | ||
Promise.resolve({ | ||
request: new WebResource(), | ||
status: 404, | ||
headers: new HttpHeaders(undefined) | ||
}) | ||
}; | ||
|
||
const emptyPolicyOptions = new RequestPolicyOptions(); | ||
|
||
describe("for browser", () => { | ||
it("should throw an Error while constructing object", () => { | ||
const construct = () => | ||
new DisableResponseDecompressionPolicy(emptyRequestPolicy, emptyPolicyOptions); | ||
construct.should.throw(); | ||
}); | ||
|
||
it("should throw an Error while using the factory method", async () => { | ||
let request: WebResource; | ||
const httpClient: HttpClient = { | ||
sendRequest: (req) => { | ||
request = req; | ||
return Promise.resolve({ | ||
request, | ||
status: 200, | ||
headers: new HttpHeaders(), | ||
bodyAsText: "[1,2,3]" | ||
}); | ||
} | ||
}; | ||
|
||
const client1 = new ServiceClient(undefined, { | ||
httpClient, | ||
requestPolicyFactories: [disableResponseDecompressionPolicy()] | ||
}); | ||
|
||
try { | ||
await client1.sendOperationRequest( | ||
{}, | ||
{ | ||
serializer: new Serializer(), | ||
httpMethod: "GET", | ||
baseUrl: "httpbin.org", | ||
responses: { | ||
200: { | ||
bodyMapper: { | ||
type: { | ||
name: "Sequence", | ||
element: { | ||
type: { | ||
name: "Number" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
); | ||
throw new Error("Error should have been thrown already.") | ||
} catch (err) { | ||
err.should.be.an("Error"); | ||
(err as Error).message.should.equal("DisableResponseDecompressionPolicy is not supported in browser environment") | ||
} | ||
}); | ||
}); | ||
}); |
48 changes: 48 additions & 0 deletions
48
sdk/core/core-http/test/policies/disableResponseDecompressionPolicy.node.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
import "chai/register-should"; | ||
import { RequestPolicyOptions } from "../../src/policies/requestPolicy"; | ||
import { WebResource } from "../../src/webResource"; | ||
import { HttpHeaders } from "../../src/httpHeaders"; | ||
import { disableResponseDecompressionPolicy, DisableResponseDecompressionPolicy } from "../../src/policies/disableResponseDecompressionPolicy"; | ||
import { HttpOperationResponse } from '../../src/coreHttp'; | ||
|
||
describe("DisableResponseDecompressionPolicy (node)", function() { | ||
|
||
function responseOf(r: WebResource): HttpOperationResponse { | ||
return { | ||
request: r, | ||
status: 404, | ||
headers: new HttpHeaders(undefined) | ||
} | ||
} | ||
const verifyDecompressionDisabledPolicy = { | ||
sendRequest: async(request: WebResource) => { | ||
request.decompressResponse!.should.equal(false); | ||
return Promise.resolve(responseOf(request)) | ||
} | ||
}; | ||
|
||
const emptyPolicyOptions = new RequestPolicyOptions(); | ||
|
||
describe("for Node.js", function() { | ||
it("factory passes correct option", async function() { | ||
const factory = disableResponseDecompressionPolicy(); | ||
const policy = factory.create(verifyDecompressionDisabledPolicy, emptyPolicyOptions) as DisableResponseDecompressionPolicy; | ||
const request = new WebResource(); | ||
await policy.sendRequest(request); | ||
}); | ||
it("sets correct option through constructor", async function() { | ||
const policy = new DisableResponseDecompressionPolicy(verifyDecompressionDisabledPolicy, emptyPolicyOptions); | ||
const request = new WebResource(); | ||
await policy.sendRequest(request); | ||
}); | ||
|
||
it("should assign option to the web request", async () => { | ||
const policy = new DisableResponseDecompressionPolicy(verifyDecompressionDisabledPolicy, emptyPolicyOptions); | ||
const request = new WebResource(); | ||
await policy.sendRequest(request); | ||
}); | ||
}); | ||
}); |