Skip to content

Commit

Permalink
feat(http-client): Expose buildRequest helper API
Browse files Browse the repository at this point in the history
buildRequest was a private method. This commit makes it a public method that developers can use to build a `Request` object. This is particularly useful when returning a `Request` from a response interceptor.
  • Loading branch information
davismj committed Apr 28, 2018
1 parent cc91034 commit 33d364d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 38 deletions.
71 changes: 35 additions & 36 deletions src/http-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export class HttpClient {
fetch(input: Request|string, init?: RequestInit): Promise<Response> {
this::trackRequestStart();

let request = this::buildRequest(input, init, this.defaults);
let request = this.buildRequest(input, init);
return processRequest(request, this.interceptors)
.then(result => {
let response = null;
Expand All @@ -122,13 +122,46 @@ export class HttpClient {
})
.then(result => {
if (Request.prototype.isPrototypeOf(result)) {
debugger;
return this.fetch(result);
}
this::trackRequestEnd();
return result;
});
}

buildRequest(input: string, init: RequestInit): Request {
let defaults = this.defaults || {};
let request;
let body;
let requestContentType;

let parsedDefaultHeaders = parseHeaderValues(defaults.headers);
if (Request.prototype.isPrototypeOf(input)) {
request = input;
requestContentType = new Headers(request.headers).get('Content-Type');
} else {
init || (init = {});
body = init.body;
let bodyObj = body ? { body } : null;
let requestInit = Object.assign({}, defaults, { headers: {} }, init, bodyObj);
requestContentType = new Headers(requestInit.headers).get('Content-Type');
request = new Request(getRequestUrl(this.baseUrl, input), requestInit);
}
if (!requestContentType) {
if (new Headers(parsedDefaultHeaders).has('content-type')) {
request.headers.set('Content-Type', new Headers(parsedDefaultHeaders).get('content-type'));
} else if (body && isJSON(body)) {
request.headers.set('Content-Type', 'application/json');
}
}
setDefaultHeaders(request.headers, parsedDefaultHeaders);
if (body && Blob.prototype.isPrototypeOf(body) && body.type) {
// work around bug in IE & Edge where the Blob type is ignored in the request
// https://connect.microsoft.com/IE/feedback/details/2136163
request.headers.set('Content-Type', body.type);
}
return request;
}
}

const absoluteUrlRegexp = /^([a-z][a-z0-9+\-.]*:)?\/\//i;
Expand Down Expand Up @@ -157,40 +190,6 @@ function parseHeaderValues(headers) {
return parsedHeaders;
}

function buildRequest(input, init) {
let defaults = this.defaults || {};
let request;
let body;
let requestContentType;

let parsedDefaultHeaders = parseHeaderValues(defaults.headers);
if (Request.prototype.isPrototypeOf(input)) {
request = input;
requestContentType = new Headers(request.headers).get('Content-Type');
} else {
init || (init = {});
body = init.body;
let bodyObj = body ? { body } : null;
let requestInit = Object.assign({}, defaults, { headers: {} }, init, bodyObj);
requestContentType = new Headers(requestInit.headers).get('Content-Type');
request = new Request(getRequestUrl(this.baseUrl, input), requestInit);
}
if (!requestContentType) {
if (new Headers(parsedDefaultHeaders).has('content-type')) {
request.headers.set('Content-Type', new Headers(parsedDefaultHeaders).get('content-type'));
} else if (body && isJSON(body)) {
request.headers.set('Content-Type', 'application/json');
}
}
setDefaultHeaders(request.headers, parsedDefaultHeaders);
if (body && Blob.prototype.isPrototypeOf(body) && body.type) {
// work around bug in IE & Edge where the Blob type is ignored in the request
// https://connect.microsoft.com/IE/feedback/details/2136163
request.headers.set('Content-Type', body.type);
}
return request;
}

function getRequestUrl(baseUrl, url) {
if (absoluteUrlRegexp.test(url)) {
return url;
Expand Down
14 changes: 12 additions & 2 deletions test/http-client.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'aurelia-polyfills';
import {json} from '../src/util';
import {HttpClient} from '../src/http-client';
import {HttpClient, buildRequest} from '../src/http-client';
import {HttpClientConfiguration} from '../src/http-client-configuration';

describe('HttpClient', () => {
Expand Down Expand Up @@ -274,7 +274,17 @@ describe('HttpClient', () => {
const path = 'retry';
let retry = 3;
fetch.and.returnValue(Promise.reject(new Response(null, { status: 500 })));
let interceptor = { response(r) { return r; }, responseError(r) { if (retry--) { return new Request(path) } else { throw r; } } };
let interceptor = {
response(r) { return r; },
responseError(r) {
if (retry--) {
let request = client.buildRequest(path);
return request;
} else {
throw r;
}
}
};
spyOn(interceptor, 'response').and.callThrough();
spyOn(interceptor, 'responseError').and.callThrough();

Expand Down

0 comments on commit 33d364d

Please sign in to comment.