This repository has been archived on 2024-07-27. You can view files and clone it, but cannot push or open issues or pull requests.
keksAccountGUI/node_modulesOLD/@vue/cli-service/lib/util/prepareProxy.js
2019-08-11 20:48:02 +02:00

201 lines
6.1 KiB
JavaScript
Raw Permalink 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.

/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file at
* https://github.com/facebookincubator/create-react-app/blob/master/LICENSE
*/
const fs = require('fs')
const url = require('url')
const path = require('path')
const chalk = require('chalk')
const address = require('address')
const defaultConfig = {
logLevel: 'silent',
secure: false,
changeOrigin: true,
ws: true,
xfwd: true
}
module.exports = function prepareProxy (proxy, appPublicFolder) {
// `proxy` lets you specify alternate servers for specific requests.
// It can either be a string or an object conforming to the Webpack dev server proxy configuration
// https://webpack.github.io/docs/webpack-dev-server.html
if (!proxy) {
return undefined
}
if (Array.isArray(proxy) || (typeof proxy !== 'object' && typeof proxy !== 'string')) {
console.log(
chalk.red(
'When specified, "proxy" in package.json must be a string or an object.'
)
)
console.log(
chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".')
)
console.log(
chalk.red(
'Either remove "proxy" from package.json, or make it an object.'
)
)
process.exit(1)
}
// Otherwise, if proxy is specified, we will let it handle any request except for files in the public folder.
function mayProxy (pathname) {
const maybePublicPath = path.resolve(appPublicFolder, pathname.slice(1))
return !fs.existsSync(maybePublicPath)
}
function createProxyEntry (target, usersOnProxyReq, context) {
// #2478
// There're a little-known use case that the `target` field is an object rather than a string
// https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/https.md
if (typeof target === 'string' && process.platform === 'win32') {
target = resolveLoopback(target)
}
return {
target,
context (pathname, req) {
// is a static asset
if (!mayProxy(pathname)) {
return false
}
if (context) {
// Explicit context, e.g. /api
return pathname.match(context)
} else {
// not a static request
if (req.method !== 'GET') {
return true
}
// Heuristics: if request `accept`s text/html, we pick /index.html.
// Modern browsers include text/html into `accept` header when navigating.
// However API calls like `fetch()` wont generally accept text/html.
// If this heuristic doesnt work well for you, use a custom `proxy` object.
return (
req.headers.accept &&
req.headers.accept.indexOf('text/html') === -1
)
}
},
onProxyReq (proxyReq, req, res) {
if (usersOnProxyReq) {
usersOnProxyReq(proxyReq, req, res)
}
// Browsers may send Origin headers even with same-origin
// requests. To prevent CORS issues, we have to change
// the Origin to match the target URL.
if (!proxyReq.agent && proxyReq.getHeader('origin')) {
proxyReq.setHeader('origin', target)
}
},
onError: onProxyError(target)
}
}
// Support proxy as a string for those who are using the simple proxy option
if (typeof proxy === 'string') {
if (!/^http(s)?:\/\//.test(proxy)) {
console.log(
chalk.red(
'When "proxy" is specified in package.json it must start with either http:// or https://'
)
)
process.exit(1)
}
return [
Object.assign({}, defaultConfig, createProxyEntry(proxy))
]
}
// Otherwise, proxy is an object so create an array of proxies to pass to webpackDevServer
return Object.keys(proxy).map(context => {
const config = proxy[context]
if (!config.hasOwnProperty('target')) {
console.log(
chalk.red(
'When `proxy` in package.json is an object, each `context` object must have a ' +
'`target` property specified as a url string'
)
)
process.exit(1)
}
const entry = createProxyEntry(config.target, config.onProxyReq, context)
return Object.assign({}, defaultConfig, config, entry)
})
}
function resolveLoopback (proxy) {
const o = url.parse(proxy)
o.host = undefined
if (o.hostname !== 'localhost') {
return proxy
}
// Unfortunately, many languages (unlike node) do not yet support IPv6.
// This means even though localhost resolves to ::1, the application
// must fall back to IPv4 (on 127.0.0.1).
// We can re-enable this in a few years.
/* try {
o.hostname = address.ipv6() ? '::1' : '127.0.0.1';
} catch (_ignored) {
o.hostname = '127.0.0.1';
}*/
try {
// Check if we're on a network; if we are, chances are we can resolve
// localhost. Otherwise, we can just be safe and assume localhost is
// IPv4 for maximum compatibility.
if (!address.ip()) {
o.hostname = '127.0.0.1'
}
} catch (_ignored) {
o.hostname = '127.0.0.1'
}
return url.format(o)
}
// We need to provide a custom onError function for httpProxyMiddleware.
// It allows us to log custom error messages on the console.
function onProxyError (proxy) {
return (err, req, res) => {
const host = req.headers && req.headers.host
console.log(
chalk.red('Proxy error:') +
' Could not proxy request ' +
chalk.cyan(req.url) +
' from ' +
chalk.cyan(host) +
' to ' +
chalk.cyan(proxy) +
'.'
)
console.log(
'See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (' +
chalk.cyan(err.code) +
').'
)
console.log()
// And immediately send the proper error response to the client.
// Otherwise, the request will eventually timeout with ERR_EMPTY_RESPONSE on the client side.
if (res.writeHead && !res.headersSent) {
res.writeHead(500)
}
res.end(
'Proxy error: Could not proxy request ' +
req.url +
' from ' +
host +
' to ' +
proxy +
' (' +
err.code +
').'
)
}
}