Revert "server, launcher, ts: typescript"

This reverts commit d3f8b8bbb6.
This commit is contained in:
Zach Bloomquist
2019-03-26 17:14:21 -04:00
parent d3f8b8bbb6
commit 818dfdfd00
10 changed files with 164 additions and 210 deletions

View File

@@ -67,16 +67,6 @@
"@cypress/env-or-json-file": "2.0.0",
"@cypress/npm-run-all": "4.0.5",
"@cypress/questions-remain": "1.0.1",
"@types/bluebird": "3.5.21",
"@types/chai": "3.5.2",
"@types/debug": "0.0.31",
"@types/execa": "0.7.2",
"@types/fs-extra": "3.0.0",
"@types/lodash": "4.14.122",
"@types/mocha": "2.2.48",
"@types/node": "7.10.3",
"@types/ramda": "0.25.47",
"@types/request-promise": "4.1.42",
"ansi-styles": "3.2.1",
"ascii-table": "0.0.9",
"babel-eslint": "10.0.1",

View File

@@ -25,6 +25,15 @@
"lib"
],
"devDependencies": {
"@types/bluebird": "3.5.21",
"@types/chai": "3.5.2",
"@types/debug": "0.0.31",
"@types/execa": "0.7.2",
"@types/fs-extra": "3.0.0",
"@types/lodash": "4.14.122",
"@types/mocha": "2.2.48",
"@types/node": "7.10.3",
"@types/ramda": "0.25.47",
"bin-up": "1.1.0",
"chai": "3.5.0",
"prettier": "1.16.4",

View File

@@ -6,14 +6,10 @@ import * as url from 'url'
import * as debugModule from 'debug'
import { getProxyForUrl } from 'proxy-from-env'
import * as Promise from 'bluebird'
import { getAddress } from './connect'
import * as connect from './connect'
const debug = debugModule('cypress:server:agent')
interface RequestOptionsWithProxy extends http.RequestOptions {
proxy: string
}
function createProxySock (proxy: url.Url) {
if (proxy.protocol === 'http:') {
return net.connect(Number(proxy.port || 80), proxy.hostname)
@@ -28,21 +24,21 @@ function createProxySock (proxy: url.Url) {
throw new Error(`Unsupported proxy protocol: ${proxy.protocol}`)
}
function regenerateRequestHead(req: http.ClientRequest) {
delete req._header
req._implicitHeader()
function regenerateRequestHead(req) {
req._header = null;
req._implicitHeader();
if (req.output && req.output.length > 0) {
// the _header has already been queued to be written to the socket
var first = req.output[0]
var endOfHeaders = first.indexOf('\r\n\r\n') + 4
req.output[0] = req._header + first.substring(endOfHeaders)
var first = req.output[0];
var endOfHeaders = first.indexOf('\r\n\r\n') + 4;
req.output[0] = req._header + first.substring(endOfHeaders);
}
}
export class CombinedAgent {
httpAgent: HttpAgent
httpsAgent: HttpsAgent
familyCache: { [host: string] : 4 | 6 } = {}
familyCache = {}
constructor(httpOpts: http.AgentOptions = {}, httpsOpts: https.AgentOptions = {}) {
this.httpAgent = new HttpAgent(httpOpts)
@@ -73,7 +69,7 @@ export class CombinedAgent {
debug(`addRequest called for ${options.href}`)
this._getFirstWorkingFamily(options)
.then((family: Optional<Number>) => {
.then(family => {
options.family = family
if (isHttps) {
@@ -84,7 +80,7 @@ export class CombinedAgent {
})
}
_getFirstWorkingFamily({ port, host }: http.RequestOptions) {
_getFirstWorkingFamily({ port, host }) {
// this is a workaround for localhost (and potentially others) having invalid
// A records but valid AAAA records. here, we just cache the family of the first
// returned A/AAAA record for a host that we can establish a connection to.
@@ -105,8 +101,8 @@ export class CombinedAgent {
return Promise.resolve(this.familyCache[host])
}
return getAddress(port, host)
.then((firstWorkingAddress: net.Address) => {
return connect.getAddress(port, host)
.then(firstWorkingAddress => {
this.familyCache[host] = firstWorkingAddress.family
return firstWorkingAddress.family
})
@@ -124,21 +120,21 @@ class HttpAgent extends http.Agent {
this.httpsAgent = new https.Agent({ keepAlive: true })
}
createSocket (req: http.ClientRequest, options: http.RequestOptions, cb: http.SocketCallback) {
createSocket (req, options, cb) {
if (process.env.HTTP_PROXY) {
const proxy = getProxyForUrl(options.href)
if (proxy) {
options.proxy = proxy
return this._createProxiedSocket(req, <RequestOptionsWithProxy>options, cb)
return this._createProxiedSocket(req, options, cb)
}
}
super.createSocket(req, options, cb)
}
_createProxiedSocket (req: http.ClientRequest, options: RequestOptionsWithProxy, cb: http.SocketCallback) {
_createProxiedSocket (req, options, cb) {
debug(`Creating proxied socket for ${options.href} through ${options.proxy}`)
const proxy = url.parse(options.proxy)
@@ -158,8 +154,8 @@ class HttpAgent extends http.Agent {
// https://github.com/TooTallNate/node-http-proxy-agent/blob/master/index.js#L93
regenerateRequestHead(req)
options.port = Number(proxy.port || 80)
options.host = proxy.hostname || 'localhost'
options.port = proxy.port
options.host = proxy.hostname
delete options.path // so the underlying net.connect doesn't default to IPC
if (proxy.protocol === 'https:') {
@@ -179,14 +175,14 @@ class HttpsAgent extends https.Agent {
super(opts)
}
createConnection (options: http.RequestOptions, cb: http.SocketCallback) {
createConnection (options, cb) {
if (process.env.HTTPS_PROXY) {
const proxy = getProxyForUrl(options.href)
if (typeof proxy === "string") {
options.proxy = <string>proxy
if (proxy) {
options.proxy = proxy
return this.createProxiedConnection(<RequestOptionsWithProxy>options, cb)
return this.createProxiedConnection(options, cb)
}
}
@@ -194,7 +190,7 @@ class HttpsAgent extends https.Agent {
cb(null, super.createConnection(options))
}
createProxiedConnection (options: RequestOptionsWithProxy, cb: http.SocketCallback) {
createProxiedConnection (options, cb) {
// heavily inspired by
// https://github.com/mknj/node-keepalive-proxy-agent/blob/master/index.js
debug(`Creating proxied socket for ${options.href} through ${options.proxy}`)
@@ -205,14 +201,14 @@ class HttpsAgent extends https.Agent {
const proxySocket = createProxySock(proxy)
const onError = (err: Error) => {
const onError = (err) => {
proxySocket.destroy()
cb(err, undefined)
cb(err)
}
let buffer = ''
const onData = (data: Buffer) => {
const onData = (data) => {
debug(`Proxy socket for ${options.href} established`)
buffer += data.toString()
@@ -227,18 +223,19 @@ class HttpsAgent extends https.Agent {
// read status code from proxy's response
const matches = buffer.match(/^HTTP\/1.1 (\d*)/)
if (!matches || matches[1] !== '200') {
return onError(new Error(`Error establishing proxy connection: ${matches ? matches[0] : buffer}`))
if (matches[1] !== '200') {
return onError(new Error(`Error establishing proxy connection: ${matches[0]}`))
}
if (options._agentKey) {
// https.Agent will upgrade and reuse this socket now
options.socket = proxySocket
options.servername = hostname
return cb(undefined, super.createConnection(options, undefined))
// @ts-ignore
return cb(null, super.createConnection(options))
}
cb(undefined, proxySocket)
cb(null, proxySocket)
}
proxySocket.once('error', onError)

View File

@@ -0,0 +1,62 @@
const net = require('net')
const dns = require('dns')
const url = require('url')
const rp = require('request-promise')
const Promise = require('bluebird')
module.exports = {
byPortAndAddress (port, address) {
// https://nodejs.org/api/net.html#net_net_connect_port_host_connectlistener
return new Promise((resolve, reject) => {
const client = net.connect(port, address.address)
client.on('connect', () => {
client.end()
resolve(address)
})
client.on('error', reject)
})
},
getAddress (port, hostname) {
const fn = this.byPortAndAddress.bind(this, port)
// promisify at the very last second which enables us to
// modify dns lookup function (via hosts overrides)
const lookupAsync = Promise.promisify(dns.lookup, { context: dns })
// this does not go out to the network to figure
// out the addresess. in fact it respects the /etc/hosts file
// https://github.com/nodejs/node/blob/dbdbdd4998e163deecefbb1d34cda84f749844a4/lib/dns.js#L108
// https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback
return lookupAsync(hostname, { all: true })
.then((addresses) => {
// convert to an array if string
return [].concat(addresses).map(fn)
})
.any()
},
ensureUrl (urlStr) {
// takes a urlStr and verifies the hostname + port
let { hostname, protocol, port } = url.parse(urlStr)
if (port == null) {
port = protocol === 'https:' ? '443' : '80'
}
if (process.env.HTTP_PROXY) {
// cannot make arbitrary connections behind a proxy, attempt HTTP/HTTPS
return rp({
url: urlStr,
agent: require('./agent'),
proxy: null,
})
.catch({ name: 'StatusCodeError' }, () => {}) // we just care if it can connect, not if it's a valid resource
}
return this.getAddress(port, hostname)
},
}

View File

@@ -1,58 +0,0 @@
import * as net from 'net'
import * as dns from 'dns'
import * as url from 'url'
import * as rp from 'request-promise'
import * as Promise from 'bluebird'
export function byPortAndAddress (port: number, address: net.Address) {
// https://nodejs.org/api/net.html#net_net_connect_port_host_connectlistener
return new Promise((resolve, reject) => {
const client = net.connect(port, address.address, () => {
client.end()
resolve(address)
})
client.on('error', reject)
})
}
export function getAddress (port: number, hostname: string) {
const fn = byPortAndAddress.bind({}, port)
// promisify at the very last second which enables us to
// modify dns lookup function (via hosts overrides)
const lookupAsync = Promise.promisify(dns.lookup, { context: dns })
// this does not go out to the network to figure
// out the addresess. in fact it respects the /etc/hosts file
// https://github.com/nodejs/node/blob/dbdbdd4998e163deecefbb1d34cda84f749844a4/lib/dns.js#L108
// https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback
// @ts-ignore
return lookupAsync(hostname, { all: true })
.then((addresses: net.Address[]) => {
// convert to an array if string
return Array.prototype.concat.call(addresses).map(fn)
})
.any()
}
export function ensureUrl (urlStr: string) {
// takes a urlStr and verifies the hostname + port
let { hostname, protocol, port } = url.parse(urlStr)
if (port == null) {
port = protocol === 'https:' ? '443' : '80'
}
if (process.env.HTTP_PROXY) {
// cannot make arbitrary connections behind a proxy, attempt HTTP/HTTPS
return rp({
url: urlStr,
agent: require('./agent'),
proxy: null,
})
.catch({ name: 'StatusCodeError' }, () => {}) // we just care if it can connect, not if it's a valid resource
}
return getAddress(Number(port), String(hostname))
}

View File

@@ -0,0 +1,42 @@
const os = require('os')
const getWindowsProxy = require('@cypress/get-windows-proxy')
module.exports = {
_getWindowsProxy () {
return getWindowsProxy()
},
_normalizeEnvironmentProxy () {
if (!process.env.HTTPS_PROXY) {
// request library will use HTTP_PROXY as a fallback for HTTPS urls, but
// proxy-from-env will not, so let's just force it to fall back like this
process.env.HTTPS_PROXY = process.env.HTTP_PROXY
}
if (!process.env.NO_PROXY) {
// don't proxy localhost, to match Chrome's default behavior and user expectation
process.env.NO_PROXY = 'localhost'
}
},
loadSystemProxySettings () {
if (process.env.HTTP_PROXY !== undefined) {
this._normalizeEnvironmentProxy()
return
}
if (os.platform() === 'win32') {
const windowsProxy = this._getWindowsProxy()
if (windowsProxy) {
process.env.HTTP_PROXY = process.env.HTTPS_PROXY = windowsProxy.httpProxy
process.env.NO_PROXY = process.env.NO_PROXY || windowsProxy.noProxy
}
this._normalizeEnvironmentProxy()
return 'win32'
}
},
}

View File

@@ -1,41 +0,0 @@
import * as os from 'os'
import getWindowsProxy = require('@cypress/get-windows-proxy')
export function _getWindowsProxy () {
return getWindowsProxy()
}
export function _normalizeEnvironmentProxy () {
if (!process.env.HTTPS_PROXY) {
// request library will use HTTP_PROXY as a fallback for HTTPS urls, but
// proxy-from-env will not, so let's just force it to fall back like this
process.env.HTTPS_PROXY = process.env.HTTP_PROXY
}
if (!process.env.NO_PROXY) {
// don't proxy localhost, to match Chrome's default behavior and user expectation
process.env.NO_PROXY = 'localhost'
}
}
// @ts-ignore: Not all code paths return a value
export function loadSystemProxySettings () {
if (process.env.HTTP_PROXY !== undefined) {
_normalizeEnvironmentProxy()
return
}
if (os.platform() === 'win32') {
const windowsProxy = _getWindowsProxy()
if (windowsProxy) {
process.env.HTTP_PROXY = process.env.HTTPS_PROXY = windowsProxy.httpProxy
process.env.NO_PROXY = process.env.NO_PROXY || windowsProxy.noProxy
}
_normalizeEnvironmentProxy()
return 'win32'
}
}

View File

@@ -1,10 +0,0 @@
{
"extends": "./../ts/tsconfig.json",
"include": [
"lib/*.ts",
"lib/**/*.ts"
],
"files": [
"./../ts/index.d.ts"
]
}

View File

@@ -1,62 +1,6 @@
// missing type definitions for libraries
// https://glebbahmutov.com/blog/trying-typescript/#manual-types-for-3rd-party-libraries
declare module '@cypress/get-windows-proxy' {
type ProxyConfig = {
httpProxy: string,
noProxy: string
}
function getWindowsProxy(): Optional<ProxyConfig>
export = getWindowsProxy
}
declare module 'http' {
import { Socket } from 'net'
import { Url } from 'url'
type SocketCallback = (err: Optional<Error>, sock: Optional<Socket>) => void
interface Agent {
addRequest(req: ClientRequest, options: RequestOptions): void
createSocket(req: ClientRequest, options: RequestOptions, cb: SocketCallback): void
createConnection(options: RequestOptions, cb: Optional<SocketCallback>): void
}
interface ClientRequest {
_header: { [key: string]:string }
_implicitHeader: () => void
output: string[]
path: string
agent: Agent
}
interface RequestOptions {
_agentKey: Optional<symbol>
host: string
href: string
path: Optional<string>
port: number
proxy: Optional<string>
servername: Optional<string>
socket: Optional<Socket>
uri: Url
}
}
declare module 'net' {
interface Address {
address: string
family: 4 | 6
}
}
declare interface Object {
assign(...obj: any[]): any
}
declare type Optional<T> = T | void
declare module 'plist' {
interface Plist {
parse: (s:string) => any
@@ -69,6 +13,25 @@ declare module 'proxy-from-env' {
const getProxyForUrl: (url: string) => string
}
declare module 'http' {
import { Socket } from 'net'
export interface Agent {
addRequest(req: ClientRequest, options: any): void
createSocket(req: ClientRequest, options: any, cb: (err: Error | undefined, sock: Socket) => void): void
}
export interface ClientRequest {
_header: { [key: string]:string }
_implicitHeader: () => void
output: string[]
}
}
declare interface Object {
assign(...obj: any[]): any
}
declare interface SymbolConstructor {
for(str: string): SymbolConstructor
}

View File

@@ -36,8 +36,8 @@
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
//"typeRoots": [], /* List of folders to include type definitions from. */
"types": ["mocha", "node"] /* Type declaration files to be included in compilation. */
// "typeRoots": [], /* List of folders to include type definitions from. */
"types": ["mocha"] /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
/* Source Map Options */