Files
Superalgos/node_modules/@octokit/rest/lib/request/request.js
T

117 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict'
module.exports = httpRequest
const url = require('url')
const http = require('http')
const https = require('https')
const _ = require('lodash')
const debug = require('debug')('octokit:rest')
const isArrayBuffer = require('is-array-buffer')
const isStream = require('is-stream')
const HttpError = require('./http-error')
function httpRequest (requestOptions) {
requestOptions = Object.assign(
url.parse(requestOptions.url),
_.pick(requestOptions, 'method', 'body', 'headers', 'ca', 'family', 'proxy', 'rejectUnauthorized', 'timeout')
)
debug('REQUEST:', requestOptions)
// calculate content length unless body is a stream, in which case the
// content length is already set per option
if (requestOptions.body && !isStream(requestOptions.body)) {
// stringify body unless it’s an ArrayBuffer
if (!isArrayBuffer(requestOptions.body) && !Buffer.isBuffer(requestOptions.body) && typeof requestOptions.body !== 'string') {
requestOptions.body = JSON.stringify(requestOptions.body)
}
_.defaults(requestOptions.headers, {
'content-type': 'application/json; charset=utf-8',
'content-length': Buffer.byteLength(requestOptions.body, 'utf8')
})
}
// GitHub expects "content-length: 0" header for PUT/PATCH requests without body
if (['patch', 'put'].indexOf(requestOptions.method) >= 0 &&
!requestOptions.headers['content-length']) {
requestOptions.headers['content-length'] = 0
}
if ('content-length' in requestOptions.headers) {
requestOptions.headers['content-length'] = parseInt(requestOptions.headers['content-length'], 10)
}
const reqModule = requestOptions.protocol === 'http:' ? http : https
delete requestOptions.protocol
return new Promise((resolve, reject) => {
const request = reqModule.request(requestOptions, (response) => {
debug('STATUS: ' + response.statusCode)
debug('HEADERS: ' + JSON.stringify(response.headers))
response.setEncoding('utf8')
let data = ''
response.on('data', (chunk) => {
data += chunk
})
/* istanbul ignore next */
response.on('error', (error) => {
reject(new HttpError(error.message, 500))
})
response.on('end', () => {
if (response.statusCode !== 304 && response.statusCode >= 301 && response.statusCode <= 307) {
requestOptions.url = response.headers.location
httpRequest(requestOptions).then(resolve, reject)
return
}
if (response.statusCode === 304 || response.statusCode >= 400 || response.statusCode < 10) {
reject(new HttpError(data, response.statusCode, response.headers))
return
}
const contentType = response.headers['content-type']
if (contentType && contentType.indexOf('application/json') !== -1) {
data = data && JSON.parse(data)
}
resolve({
meta: response.headers,
data
})
})
})
let aborted
request.on('error', (error) => {
if (aborted) return
debug('REQUEST ERROR: ' + error.message)
reject(new HttpError(error.message, 500))
})
if (requestOptions.timeout) {
request.setTimeout(requestOptions.timeout)
}
request.on('timeout', () => {
debug('REQUEST ERROR: timed out')
request.abort()
aborted = true
reject(new HttpError('Request timeout', 504))
})
if (requestOptions.body) {
if (isStream(requestOptions.body)) {
return requestOptions.body.pipe(request)
}
request.write(Buffer.from(requestOptions.body))
}
request.end()
})
}