-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor proxy into own package, implement middleware pattern
- Loading branch information
Showing
42 changed files
with
1,387 additions
and
804 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,76 @@ | ||
const _ = require('lodash') | ||
const url = require('url') | ||
const uri = require('./uri') | ||
const debug = require('debug')('cypress:server:cors') | ||
const parseDomain = require('parse-domain') | ||
import _ from 'lodash' | ||
import * as uri from './uri' | ||
import debugModule from 'debug' | ||
import parseDomain, { ParsedDomain } from 'parse-domain' | ||
|
||
const debug = debugModule('cypress:network:cors') | ||
|
||
const ipAddressRe = /^[\d\.]+$/ | ||
|
||
module.exports = { | ||
parseUrlIntoDomainTldPort (str) { | ||
let { hostname, port, protocol } = url.parse(str) | ||
type ParsedHost = { | ||
port?: string | ||
tld?: string | ||
domain?: string | ||
} | ||
|
||
if (port == null) { | ||
port = protocol === 'https:' ? '443' : '80' | ||
} | ||
export function parseUrlIntoDomainTldPort (str) { | ||
let { hostname, port, protocol } = uri.parse(str) | ||
|
||
if (!hostname) { | ||
hostname = '' | ||
} | ||
|
||
if (!port) { | ||
port = protocol === 'https:' ? '443' : '80' | ||
} | ||
|
||
let parsed = parseDomain(hostname, { | ||
privateTlds: true, // use the public suffix | ||
customTlds: ipAddressRe, | ||
}) | ||
|
||
// if we couldn't get a parsed domain | ||
if (!parsed) { | ||
// then just fall back to a dumb check | ||
// based on assumptions that the tld | ||
// is the last segment after the final | ||
// '.' and that the domain is the segment | ||
// before that | ||
const segments = hostname.split('.') | ||
|
||
parsed = { | ||
tld: segments[segments.length - 1] || '', | ||
domain: segments[segments.length - 2] || '', | ||
} | ||
let parsed : Partial<ParsedDomain> | null = parseDomain(hostname, { | ||
privateTlds: true, // use the public suffix | ||
customTlds: ipAddressRe, | ||
}) | ||
|
||
// if we couldn't get a parsed domain | ||
if (!parsed) { | ||
// then just fall back to a dumb check | ||
// based on assumptions that the tld | ||
// is the last segment after the final | ||
// '.' and that the domain is the segment | ||
// before that | ||
const segments = hostname.split('.') | ||
|
||
parsed = { | ||
tld: segments[segments.length - 1] || '', | ||
domain: segments[segments.length - 2] || '', | ||
} | ||
} | ||
|
||
const obj = {} | ||
const obj: ParsedHost = {} | ||
|
||
obj.port = port | ||
obj.tld = parsed.tld | ||
obj.domain = parsed.domain | ||
// obj.protocol = protocol | ||
obj.port = port | ||
obj.tld = parsed.tld | ||
obj.domain = parsed.domain | ||
|
||
debug('Parsed URL %o', obj) | ||
debug('Parsed URL %o', obj) | ||
|
||
return obj | ||
}, | ||
return obj | ||
} | ||
|
||
urlMatchesOriginPolicyProps (urlStr, props) { | ||
// take a shortcut here in the case | ||
// where remoteHostAndPort is null | ||
if (!props) { | ||
return false | ||
} | ||
export function urlMatchesOriginPolicyProps (urlStr, props) { | ||
// take a shortcut here in the case | ||
// where remoteHostAndPort is null | ||
if (!props) { | ||
return false | ||
} | ||
|
||
const parsedUrl = this.parseUrlIntoDomainTldPort(urlStr) | ||
const parsedUrl = parseUrlIntoDomainTldPort(urlStr) | ||
|
||
// does the parsedUrl match the parsedHost? | ||
return _.isEqual(parsedUrl, props) | ||
}, | ||
// does the parsedUrl match the parsedHost? | ||
return _.isEqual(parsedUrl, props) | ||
} | ||
|
||
urlMatchesOriginProtectionSpace (urlStr, origin) { | ||
const normalizedUrl = uri.addDefaultPort(urlStr).format() | ||
const normalizedOrigin = uri.addDefaultPort(origin).format() | ||
export function urlMatchesOriginProtectionSpace (urlStr, origin) { | ||
const normalizedUrl = uri.addDefaultPort(urlStr).format() | ||
const normalizedOrigin = uri.addDefaultPort(origin).format() | ||
|
||
return _.startsWith(normalizedUrl, normalizedOrigin) | ||
}, | ||
return _.startsWith(normalizedUrl, normalizedOrigin) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,15 @@ | ||
import agent from './agent' | ||
import * as connect from './connect' | ||
import { allowDestroy } from './allow-destroy' | ||
import * as blacklist from './blacklist' | ||
import * as connect from './connect' | ||
import * as cors from './cors' | ||
import * as uri from './uri' | ||
|
||
export { | ||
agent, | ||
allowDestroy, | ||
blacklist, | ||
connect, | ||
cors, | ||
uri, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
test/unit | ||
test/integration | ||
--compilers ts:@packages/ts/register | ||
--compilers coffee:@packages/coffee/register,ts:@packages/ts/register | ||
--timeout 10000 | ||
--recursive |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 3 additions & 4 deletions
7
packages/server/test/unit/cors_spec.coffee → packages/network/test/unit/cors_spec.coffee
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
if (process.env.CYPRESS_ENV !== 'production') { | ||
require('@packages/ts/register') | ||
} | ||
|
||
module.exports = require('./lib') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import _ from 'lodash' | ||
import debugModule from 'debug' | ||
import { HttpMiddleware } from '.' | ||
import { Readable } from 'stream' | ||
import { Request } from 'request' | ||
|
||
const debug = debugModule('cypress:proxy:http:error-middleware') | ||
|
||
type ErrorMiddleware = HttpMiddleware<{ | ||
error: Error | ||
incomingResStream?: Readable | ||
outgoingReq?: Request | ||
}> | ||
|
||
const LogError : ErrorMiddleware = function () { | ||
debug('error proxying request %o', _.pick(this, 'error', 'req', 'res', 'incomingRes', 'outgoingReq', 'incomingResStream')) | ||
this.next() | ||
} | ||
|
||
export const AbortRequest : ErrorMiddleware = function () { | ||
if (this.outgoingReq) { | ||
debug('aborting outgoingReq') | ||
this.outgoingReq.abort() | ||
} | ||
|
||
this.next() | ||
} | ||
|
||
export const UnpipeResponse : ErrorMiddleware = function () { | ||
if (this.incomingResStream) { | ||
debug('unpiping resStream from response') | ||
this.incomingResStream.unpipe() | ||
} | ||
|
||
this.next() | ||
} | ||
|
||
export const DestroyResponse : ErrorMiddleware = function () { | ||
this.res.destroy() | ||
this.end() | ||
} | ||
|
||
export default { | ||
LogError, | ||
AbortRequest, | ||
UnpipeResponse, | ||
DestroyResponse, | ||
} |
Oops, something went wrong.