Skip to content

Commit

Permalink
Merge pull request Azure#164 from Azure/Xhr-Cors
Browse files Browse the repository at this point in the history
Allow withCredentials: true
  • Loading branch information
RikkiGibson authored Jul 9, 2018
2 parents c072b42 + 0ace305 commit 8748897
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 17 deletions.
20 changes: 10 additions & 10 deletions lib/serviceClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ import { RequestPrepareOptions, WebResource } from "./webResource";
* Options to be provided while creating the client.
*/
export interface ServiceClientOptions {
/**
* @property {RequestInit} [requestOptions] The request options. Detailed info can be found
* here https://github.github.io/fetch/#Request
*/
requestOptions?: RequestInit;
/**
* @property {Array<RequestPolicyCreator>} [requestPolicyCreators] An array of functions that will be
* invoked to create the RequestPolicy pipeline that will be used to send a HTTP request on the
Expand Down Expand Up @@ -63,6 +58,11 @@ export interface ServiceClientOptions {
* Whether or not to generate a client request ID header for each HTTP request.
*/
generateClientRequestIdHeader?: boolean;
/**
* Whether to include credentials in CORS requests in the browser.
* See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials for more information.
*/
withCredentials?: boolean;
/**
* If specified, a GenerateRequestIdPolicy will be added to the HTTP pipeline that will add a
* header to all outgoing requests with this header name and a random UUID as the request ID.
Expand Down Expand Up @@ -95,6 +95,7 @@ export class ServiceClient {
private readonly _requestPolicyOptions: RequestPolicyOptions;

private readonly _requestPolicyCreators: RequestPolicyCreator[];
private readonly _withCredentials: boolean;

/**
* The ServiceClient constructor
Expand All @@ -108,10 +109,6 @@ export class ServiceClient {
options = {};
}

if (!options.requestOptions) {
options.requestOptions = {};
}

this.userAgentInfo = { value: [] };

if (credentials && !credentials.signRequest) {
Expand All @@ -126,6 +123,7 @@ export class ServiceClient {
// do nothing
}

this._withCredentials = options.withCredentials || false;
this._httpClient = options.httpClient || new DefaultHttpClient();
this._requestPolicyOptions = new RequestPolicyOptions(options.httpPipelineLogger);

Expand Down Expand Up @@ -281,6 +279,8 @@ export class ServiceClient {
httpRequest.onDownloadProgress = operationArguments.onDownloadProgress;
}

httpRequest.withCredentials = this._withCredentials;

serializeRequestBody(httpRequest, operationArguments, operationSpec);

if (operationSpec.responses) {
Expand Down Expand Up @@ -430,4 +430,4 @@ function getOperationArgumentValueFromParameterPath(operationArguments: Operatio
}
}
return value;
}
}
4 changes: 4 additions & 0 deletions lib/webResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export class WebResource {
formData?: any;
query?: { [key: string]: any; };
operationSpec?: OperationSpec;
withCredentials: boolean;

abortSignal?: AbortSignalLike;

Expand All @@ -68,6 +69,7 @@ export class WebResource {
query?: { [key: string]: any; },
headers?: { [key: string]: any; } | HttpHeaders,
rawResponse = false,
withCredentials = false,
abortSignal?: AbortSignalLike,
onUploadProgress?: (progress: TransferProgressEvent) => void,
onDownloadProgress?: (progress: TransferProgressEvent) => void) {
Expand All @@ -79,6 +81,7 @@ export class WebResource {
this.body = body;
this.query = query;
this.formData = undefined;
this.withCredentials = withCredentials;
this.abortSignal = abortSignal;
this.onUploadProgress = onUploadProgress;
this.onDownloadProgress = onDownloadProgress;
Expand Down Expand Up @@ -285,6 +288,7 @@ export class WebResource {
this.query,
this.headers && this.headers.clone(),
this.rawResponse,
this.withCredentials,
this.abortSignal,
this.onUploadProgress,
this.onDownloadProgress);
Expand Down
1 change: 1 addition & 0 deletions lib/xhrHttpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export class XhrHttpClient implements HttpClient {
}
}

xhr.withCredentials = request.withCredentials;
xhr.open(request.method, request.url);
for (const header of request.headers.headersArray()) {
xhr.setRequestHeader(header.name, header.value);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"email": "azsdkteam@microsoft.com",
"url": "https://github.com/Azure/ms-rest-js"
},
"version": "0.14.0",
"version": "0.15.0",
"description": "Isomorphic client Runtime for Typescript/node.js/browser javascript client libraries generated using AutoRest",
"tags": [
"isomorphic",
Expand Down
8 changes: 4 additions & 4 deletions test/shared/defaultHttpClientTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ describe("defaultHttpClient", () => {

it("should allow canceling requests", async function () {
const controller = getAbortController();
const request = new WebResource(`${baseURL}/fileupload`, "POST", new Uint8Array(1024 * 1024 * 10), undefined, undefined, true, controller.signal);
const request = new WebResource(`${baseURL}/fileupload`, "POST", new Uint8Array(1024 * 1024 * 10), undefined, undefined, true, undefined, controller.signal);
const client = new DefaultHttpClient();
const promise = client.sendRequest(request);
controller.abort();
Expand Down Expand Up @@ -134,8 +134,8 @@ describe("defaultHttpClient", () => {
const controller = getAbortController();
const buf = new Uint8Array(1024 * 1024 * 1);
const requests = [
new WebResource(`${baseURL}/fileupload`, "POST", buf, undefined, undefined, true, controller.signal),
new WebResource(`${baseURL}/fileupload`, "POST", buf, undefined, undefined, true, controller.signal)
new WebResource(`${baseURL}/fileupload`, "POST", buf, undefined, undefined, true, undefined, controller.signal),
new WebResource(`${baseURL}/fileupload`, "POST", buf, undefined, undefined, true, undefined, controller.signal)
];
const client = new DefaultHttpClient();
const promises = requests.map(r => client.sendRequest(r));
Expand All @@ -160,7 +160,7 @@ describe("defaultHttpClient", () => {
let downloadNotified = false;

const buf = new Uint8Array(1024 * 1024 * 1);
const request = new WebResource(`${baseURL}/fileupload`, "POST", buf, undefined, undefined, true, undefined,
const request = new WebResource(`${baseURL}/fileupload`, "POST", buf, undefined, undefined, true, undefined, undefined,
ev => {
uploadNotified = true;
ev.should.not.be.instanceof(ProgressEvent);
Expand Down
3 changes: 2 additions & 1 deletion test/shared/logFilterTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ describe("Log filter", () => {
},
"body": {
"a": 1
}
},
"withCredentials": false
}
>> Response status code: 200
>> Body: null
Expand Down
41 changes: 40 additions & 1 deletion test/shared/serviceClientTests.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ServiceClient, WebResource, Serializer, HttpOperationResponse, DictionaryMapper, QueryCollectionFormat, SequenceMapper } from "../../lib/msRest";
import { ServiceClient, WebResource, Serializer, HttpOperationResponse, DictionaryMapper, QueryCollectionFormat, SequenceMapper, HttpClient } from "../../lib/msRest";
import * as assert from "assert";

describe("ServiceClient", function () {
Expand Down Expand Up @@ -66,6 +66,7 @@ describe("ServiceClient", function () {
assert(request!);
assert.deepStrictEqual(request!.headers.toJson(), expected);
});

it("Should serialize collection:multi query parameters", async function () {
const expected = "?q=1&q=2&q=3";

Expand Down Expand Up @@ -117,4 +118,42 @@ describe("ServiceClient", function () {
assert(request!);
assert(request!.url.endsWith(expected), `"${request!.url}" does not end with "${expected}"`);
});

it("should apply withCredentials to requests", async function() {
let request: WebResource;
const httpClient: HttpClient = {
sendRequest: req => {
request = req;
return Promise.resolve({} as HttpOperationResponse);
}
};

const client1 = new ServiceClient(undefined, {
httpClient,
requestPolicyCreators: []
});
await client1.sendOperationRequest({ arguments: {} },
{
serializer: new Serializer(),
httpMethod: "GET",
baseUrl: "httpbin.org",
responses: { 200: {} }
});

assert.strictEqual(request!.withCredentials, false);

const client2 = new ServiceClient(undefined, {
httpClient,
requestPolicyCreators: [],
withCredentials: true
});
await client2.sendOperationRequest({ arguments: {} },
{
serializer: new Serializer(),
httpMethod: "GET",
baseUrl: "httpbin.org",
responses: { 200: {} }
});
assert.strictEqual(request!.withCredentials, true);
});
});

0 comments on commit 8748897

Please sign in to comment.