Skip to content

Commit

Permalink
Replace header parsing with get-headers module
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeembrey committed Aug 5, 2015
1 parent 37f548e commit 2a4656e
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 119 deletions.
29 changes: 2 additions & 27 deletions lib/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Request from './request'
import Response from './response'
import { defaults, Popsicle } from './common'
import { defaults as use } from './plugins/index'
import { parse as getHeaders } from 'get-headers'

/**
* Export default instance with browser transportation layer.
Expand All @@ -11,32 +12,6 @@ export = defaults({
transport: { open, abort, use }
})

/**
* Parse XHR for raw headers.
*/
function parseRawHeaders (xhr: XMLHttpRequest) {
const headers: Headers = {}
const lines = xhr.getAllResponseHeaders().split(/\r?\n/)

lines.pop()

lines.forEach(function (header) {
const indexOf = header.indexOf(':')
const name = header.substr(0, indexOf)
const value = header.substr(indexOf + 1).trim()

if (!headers.hasOwnProperty(name)) {
headers[name] = value
} else if (typeof headers[name] === 'string') {
headers[name] = [<string> headers[name], value]
} else {
(<string[]> headers[name]).push(value)
}
})

return headers
}

function open (request: Request) {
return new Promise(function (resolve, reject) {
const url = request.fullUrl()
Expand All @@ -52,7 +27,7 @@ function open (request: Request) {
xhr.onload = function () {
return resolve({
status: xhr.status === 1223 ? 204 : xhr.status,
headers: parseRawHeaders(xhr),
headers: getHeaders(xhr.getAllResponseHeaders()),
body: xhr.responseText,
url: xhr.responseURL
})
Expand Down
49 changes: 7 additions & 42 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import http = require('http')
import https = require('https')
import { request as httpRequest, IncomingMessage } from 'http'
import { request as httpsRequest } from 'https'
import agent = require('infinity-agent')
import through2 = require('through2')
import urlLib = require('url')
import extend = require('xtend')
import { http as getHeaders } from 'get-headers'
import { Headers } from './base'
import Request from './request'
import Response from './response'
Expand Down Expand Up @@ -39,42 +40,6 @@ const REDIRECT_STATUS: { [status: number]: number } = {
'308': REDIRECT_TYPE.FOLLOW_WITH_CONFIRMATION
}

/**
* Parse headers from node response object.
*/
function parseRawHeaders (response: any) {
var headers: Headers = {}

if (!response.rawHeaders) {
Object.keys(response.headers).forEach(function (key) {
var value = response.headers[key]

// Need to normalize `Set-Cookie` header under node 0.10 which
// always comes back as an array.
if (Array.isArray(value) && value.length === 1) {
value = value[0]
}

headers[key] = value
})
} else {
for (var i = 0; i < response.rawHeaders.length; i = i + 2) {
var name = response.rawHeaders[i]
var value = response.rawHeaders[i + 1]

if (!headers.hasOwnProperty(name)) {
headers[name] = value
} else if (typeof headers[name] === 'string') {
headers[name] = [<string> headers[name], value]
} else {
(<string[]> headers[name]).push(value)
}
}
}

return headers
}

/**
* Open a HTTP request with node.
*/
Expand Down Expand Up @@ -119,15 +84,15 @@ function open (request: Request) {

const arg: any = extend(urlLib.parse(url), opts)
const isHttp = arg.protocol !== 'https:'
const engine = isHttp ? http : https
const engine: typeof httpRequest = isHttp ? httpRequest : httpsRequest

// Always attach certain options.
arg.agent = request.options.agent || (isHttp ? agent.http.globalAgent : agent.https.globalAgent)
arg.rejectUnauthorized = request.options.rejectUnauthorized !== false

const req = engine.request(arg)
const req = engine(arg)

req.once('response', function (res: http.IncomingMessage) {
req.once('response', function (res: IncomingMessage) {
const status = res.statusCode
const redirect = REDIRECT_STATUS[status]

Expand Down Expand Up @@ -165,7 +130,7 @@ function open (request: Request) {
return resolve({
body: responseProxy,
status: status,
headers: parseRawHeaders(res),
headers: getHeaders(res),
url: url
})
})
Expand Down
8 changes: 8 additions & 0 deletions lib/typings/get-headers.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare module 'get-headers' {
export interface Headers {
[headerName: string]: string | string[]
}

export function http (res: any): Headers
export function parse (value: string): Headers
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"arrify": "^1.0.0",
"concat-stream": "^1.4.7",
"form-data": "^0.2.0",
"get-headers": "^1.0.0",
"infinity-agent": "^2.0.3",
"methods": "^1.1.1",
"through2": "^2.0.0",
Expand Down
113 changes: 63 additions & 50 deletions popsicle.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ var Base = (function () {
})();
exports.default = Base;

},{"arrify":11,"querystring":16,"xtend":18}],2:[function(require,module,exports){
},{"arrify":11,"querystring":16,"xtend":19}],2:[function(require,module,exports){
module.exports = FormData;

},{}],3:[function(require,module,exports){
Expand Down Expand Up @@ -157,7 +157,7 @@ function defaults(defaultsOptions) {
exports.defaults = defaults;

}).call(this,require('_process'))
},{"./form":5,"./jar":6,"./plugins/index":7,"./request":9,"./response":10,"_process":13,"methods":17,"xtend":18}],5:[function(require,module,exports){
},{"./form":5,"./jar":6,"./plugins/index":7,"./request":9,"./response":10,"_process":13,"methods":18,"xtend":19}],5:[function(require,module,exports){
var FormData = require('form-data');
function form(obj) {
var form = new FormData();
Expand Down Expand Up @@ -253,6 +253,9 @@ function stringifyRequest(request) {
}
function parseResponse(response) {
var body = response.body;
if (typeof body !== 'string') {
return;
}
if (body === '') {
response.body = null;
return;
Expand Down Expand Up @@ -547,7 +550,7 @@ function emitProgress(request) {
}

}).call(this,require('_process'))
},{"./base":1,"./response":10,"_process":13,"arrify":11,"xtend":18}],10:[function(require,module,exports){
},{"./base":1,"./response":10,"_process":13,"arrify":11,"xtend":19}],10:[function(require,module,exports){
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
Expand Down Expand Up @@ -864,6 +867,57 @@ exports.decode = exports.parse = require('./decode');
exports.encode = exports.stringify = require('./encode');

},{"./decode":14,"./encode":15}],17:[function(require,module,exports){
function parse(value) {
var headers = {};
var lines = value.replace(/\r?\n$/, '').split(/\r?\n/);
lines.forEach(function (header) {
var indexOf = header.indexOf(':');
var name = header.substr(0, indexOf);
var value = header.substr(indexOf + 1).trim();
if (!headers.hasOwnProperty(name)) {
headers[name] = value;
}
else if (typeof headers[name] === 'string') {
headers[name] = [headers[name], value];
}
else {
headers[name].push(value);
}
});
return headers;
}
exports.parse = parse;
function http(response) {
var headers = {};
if (!response.rawHeaders) {
Object.keys(response.headers).forEach(function (key) {
var value = response.headers[key];
if (Array.isArray(value) && value.length === 1) {
value = value[0];
}
headers[key] = value;
});
}
else {
for (var i = 0; i < response.rawHeaders.length; i = i + 2) {
var name = response.rawHeaders[i];
var value = response.rawHeaders[i + 1];
if (!headers.hasOwnProperty(name)) {
headers[name] = value;
}
else if (typeof headers[name] === 'string') {
headers[name] = [headers[name], value];
}
else {
headers[name].push(value);
}
}
}
return headers;
}
exports.http = http;

},{}],18:[function(require,module,exports){

var http = require('http');

Expand Down Expand Up @@ -907,7 +961,7 @@ if (http.METHODS) {

}

},{"http":12}],18:[function(require,module,exports){
},{"http":12}],19:[function(require,module,exports){
module.exports = extend

function extend() {
Expand All @@ -926,63 +980,22 @@ function extend() {
return target
}

},{}],19:[function(require,module,exports){
},{}],20:[function(require,module,exports){
var common_1 = require('./common');
var index_1 = require('./plugins/index');
function getXHR() {
if (XMLHttpRequest) {
return new XMLHttpRequest();
}
try {
return new ActiveXObject('Microsoft.XMLHTTP');
}
catch (e) { }
try {
return new ActiveXObject('Msxml2.XMLHTTP.6.0');
}
catch (e) { }
try {
return new ActiveXObject('Msxml2.XMLHTTP.3.0');
}
catch (e) { }
try {
return new ActiveXObject('Msxml2.XMLHTTP');
}
catch (e) { }
throw new TypeError('XMLHttpRequest is not available');
}
function parseRawHeaders(xhr) {
var headers = {};
var lines = xhr.getAllResponseHeaders().split(/\r?\n/);
lines.pop();
lines.forEach(function (header) {
var indexOf = header.indexOf(':');
var name = header.substr(0, indexOf);
var value = header.substr(indexOf + 1).trim();
if (!headers.hasOwnProperty(name)) {
headers[name] = value;
}
else if (typeof headers[name] === 'string') {
headers[name] = [headers[name], value];
}
else {
headers[name].push(value);
}
});
return headers;
}
var get_headers_1 = require('get-headers');
function open(request) {
return new Promise(function (resolve, reject) {
var url = request.fullUrl();
var method = request.method;
if (window.location.protocol === 'https:' && /^http\:/.test(url)) {
return reject(request.error("The request to \"" + url + "\" was blocked", 'EBLOCKED'));
}
var xhr = request.raw = getXHR();
var xhr = request.raw = new XMLHttpRequest();
xhr.onload = function () {
return resolve({
status: xhr.status === 1223 ? 204 : xhr.status,
headers: parseRawHeaders(xhr),
headers: get_headers_1.parse(xhr.getAllResponseHeaders()),
body: xhr.responseText,
url: xhr.responseURL
});
Expand Down Expand Up @@ -1033,5 +1046,5 @@ module.exports = common_1.defaults({
transport: { open: open, abort: abort, use: index_1.defaults }
});

},{"./common":4,"./plugins/index":7}]},{},[19])(19)
},{"./common":4,"./plugins/index":7,"get-headers":17}]},{},[20])(20)
});
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"lib/typings/blue-tape.d.ts",
"lib/typings/es6-promise.d.ts",
"lib/typings/methods.d.ts",
"lib/typings/get-headers.d.ts",
"typings/tsd.d.ts",
"test/index.ts"
]
Expand Down

0 comments on commit 2a4656e

Please sign in to comment.