Skip to content

Commit

Permalink
implement follow redirects for server requests
Browse files Browse the repository at this point in the history
  • Loading branch information
udivankin committed Jul 13, 2017
1 parent b9dec25 commit 63befd8
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 42 deletions.
13 changes: 12 additions & 1 deletion examples/basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,16 @@
</head>
<body>
<div id="root" style="height: 100%"></div>
</body>
<script src="./../../dist/index.js"></script>
<script type="text/javascript">
// Perform simple get request
PicoAjax.get(`${host}/get?foo=bar`)
.then(result => {
console.log('GET request response: ', result);
})
.catch(error => {
console.error(error);
});
</script>
</body
</html>
10 changes: 10 additions & 0 deletions examples/basic/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const { get, post } = require('../../dist/index.js');

const host = 'https://httpbin.org';
const redirectCount = 3;

// Perform simple get request
get(`${host}/get?foo=bar`)
Expand All @@ -22,3 +23,12 @@ post(`${host}/post`, {
.catch(error => {
console.error(error);
});

// Perform get request with redirects
get(`${host}//redirect/${redirectCount}`)
.then(result => {
console.log('GET request response: ', result);
})
.catch(error => {
console.error(error);
});
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
"babel-preset-latest": "^6.24.1",
"jasmine": "^2.6.0",
"jasmine-ajax": "^3.3.1",
"rollup": "^0.41.6",
"rollup": "^0.45.2",
"rollup-plugin-babel": "^2.7.1",
"rollup-plugin-node-resolve": "^3.0.0",
"rollup-plugin-uglify": "^2.0.1",
"rollup-watch": "^4.0.0"
"rollup-watch": "^4.3.1"
},
"scripts": {
"build": "rollup -c -w",
Expand Down
3 changes: 2 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import uglify from 'rollup-plugin-uglify';
export default {
entry: 'src/index.js',
format: 'umd',
moduleName: "pico-ajax",
moduleName: 'pico-ajax',
footer: 'if (typeof window !== "undefined") { window.PicoAjax = window["pico-ajax"]; }',
plugins: [
resolve({
jsnext: true,
Expand Down
7 changes: 7 additions & 0 deletions src/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@

import { parseJson } from './helpers';

/**
* Known HTTP request response types
*/
const XHR_RESPONSE_TYPES = [
'arraybuffer', 'blob', 'document', 'json', 'text',
];

/**
* Try to parse response
*
Expand Down
69 changes: 38 additions & 31 deletions src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

import http from 'http';
import https from 'https';
import { parse as nodeParseUrl } from 'url';
import { parse as nodeParseUrl, resolve as nodeResolveUrl } from 'url';
import zlib from 'zlib';

const MAX_REDIRECTS = 21;

/**
* Try to parse json
*
Expand All @@ -33,14 +35,16 @@ export function parseJson(json) {
* @param {string} requestUrl
* @returns {Object}
*/
export function parseUrl(requestUrl) {
export function parseUrl(requestUrl, baseUrl) {
// Modern browsers and Node v7+
if (typeof URL !== 'undefined') {
return new URL(requestUrl);
return baseUrl ? new URL(requestUrl, baseUrl) : new URL(baseUrl);
}
// Node up to v6
if (typeof global !== 'undefined') {
return nodeParseUrl(requestUrl);
return baseUrl
? nodeParseUrl(nodeResolveUrl(baseUrl, requestUrl))
: nodeParseUrl(requestUrl);
}

return {};
Expand Down Expand Up @@ -68,27 +72,14 @@ export function decompress(response, responseBuffer) {
}

/**
* Response wrapper for redirects
* Request method getter
*
* @param {string} requestOptions
* @returns {function}
*/
class WrappedResponse {
constructor(response) {
this.response = response;
}
on(eventName, callback) {
console.log('on', eventName, callback);

if (eventName === 'data') {
this.response.on(eventName, callback);
}

if (eventName === 'end') {
this.headers = this.response.headers;
this.statusCode = this.response.statusCode;
this.statusText = this.response.statusText;
this.response.on(eventName, callback);
}
};
};
export function getRequestMethod(requestOptions) {
return /^https/.test(requestOptions.href) ? https.request : http.request;
}

/**
* Request wrapper for redirects
Expand All @@ -115,14 +106,30 @@ class WrappedRequest {
* @param {function} originalResponseHandler
* @returns {Object}
*/
export function followRedirects(originalRequestOptions, originalResponseHandler) {
const requestMethod = /^https/.test(originalRequestOptions.href) ? https.request : http.request;

export function followRedirects(originalRequestOptions, originalResponseHandler, redirectCount = 0) {
const wrappedResponseHandler = (response) => {
originalResponseHandler(new WrappedResponse(response));
}
const { headers, statusCode, statusText } = response;

// Follow redirects until we get non-redirect response code
if (statusCode >= 300 && statusCode < 400) {
if (redirectCount >= MAX_REDIRECTS) {
response.statusText = 'Too many redirects';
originalResponseHandler(response);
} else {
const requestOptions = Object.assign(
originalRequestOptions,
parseUrl(headers.location, `${originalRequestOptions.protocol}//${originalRequestOptions.host}`)
);
followRedirects(requestOptions, originalResponseHandler, redirectCount + 1).end();
}

return;
}

const request = requestMethod(originalRequestOptions, wrappedResponseHandler);
originalResponseHandler(response);
}

return new WrappedRequest(request);
return new WrappedRequest(
getRequestMethod(originalRequestOptions)(originalRequestOptions, wrappedResponseHandler)
);
}
7 changes: 0 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,6 @@ const REQUEST_METHODS = [
'CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT',
];

/**
* Known HTTP request response types
*/
const XHR_RESPONSE_TYPES = [
'arraybuffer', 'blob', 'document', 'json', 'text',
];

/**
* Default request options
*/
Expand Down

0 comments on commit 63befd8

Please sign in to comment.