diff --git a/CORS-proxy/Procfile b/CORS-proxy/Procfile new file mode 100644 index 0000000..489b270 --- /dev/null +++ b/CORS-proxy/Procfile @@ -0,0 +1 @@ +web: node server.js diff --git a/CORS-proxy/README.md b/CORS-proxy/README.md new file mode 100644 index 0000000..dc2e9c4 --- /dev/null +++ b/CORS-proxy/README.md @@ -0,0 +1,21 @@ +1. Установить [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli#download-and-install) и [залогиниться](https://devcenter.heroku.com/articles/heroku-cli#getting-started). +2. В папке с прокси в консноли выполнить: + ``` + heroku create [*название приложения] + ``` + *если не указывать, сгенерируется случайно + ``` + git init + heroku git:remote -a [*название приложения] + ``` + *сгенерированное будет тут + + ![img1](img.png) + ``` + git add . + git commit -m "init" + git push heroku master + ``` +3. Вставить урл приложения **(без слеша на конце!)** в `src/Constants.ts` в `CORS_PROXY` + + ![img2](img_1.png) diff --git a/CORS-proxy/img.png b/CORS-proxy/img.png new file mode 100644 index 0000000..fbe1bf6 Binary files /dev/null and b/CORS-proxy/img.png differ diff --git a/CORS-proxy/img_1.png b/CORS-proxy/img_1.png new file mode 100644 index 0000000..3d4f4ad Binary files /dev/null and b/CORS-proxy/img_1.png differ diff --git a/CORS-proxy/lib/cors-anywhere.js b/CORS-proxy/lib/cors-anywhere.js new file mode 100644 index 0000000..15b72c5 --- /dev/null +++ b/CORS-proxy/lib/cors-anywhere.js @@ -0,0 +1,461 @@ +// © 2013 - 2016 Rob Wu +// Released under the MIT license + +'use strict'; + +var httpProxy = require('http-proxy'); +var net = require('net'); +var url = require('url'); +var regexp_tld = require('./regexp-top-level-domain'); +var getProxyForUrl = require('proxy-from-env').getProxyForUrl; + +var help_text = {}; + +function showUsage(help_file, headers, response) { + var isHtml = /\.html$/.test(help_file); + headers['content-type'] = isHtml ? 'text/html' : 'text/plain'; + if (help_text[help_file] != null) { + response.writeHead(200, headers); + response.end(help_text[help_file]); + } else { + require('fs').readFile(help_file, 'utf8', function (err, data) { + if (err) { + console.error(err); + response.writeHead(500, headers); + response.end(); + } else { + help_text[help_file] = data; + showUsage(help_file, headers, response); // Recursive call, but since data is a string, the recursion will end + } + }); + } +} + +/** + * Check whether the specified hostname is valid. + * + * @param hostname {string} Host name (excluding port) of requested resource. + * @return {boolean} Whether the requested resource can be accessed. + */ +function isValidHostName(hostname) { + return !!( + regexp_tld.test(hostname) || + net.isIPv4(hostname) || + net.isIPv6(hostname) + ); +} + +/** + * Adds CORS headers to the response headers. + * + * @param headers {object} Response headers + * @param request {ServerRequest} + */ +function withCORS(headers, request) { + headers['access-control-allow-origin'] = '*'; + var corsMaxAge = request.corsAnywhereRequestState.corsMaxAge; + if (request.method === 'OPTIONS' && corsMaxAge) { + headers['access-control-max-age'] = corsMaxAge; + } + if (request.headers['access-control-request-method']) { + headers['access-control-allow-methods'] = request.headers['access-control-request-method']; + delete request.headers['access-control-request-method']; + } + if (request.headers['access-control-request-headers']) { + headers['access-control-allow-headers'] = request.headers['access-control-request-headers']; + delete request.headers['access-control-request-headers']; + } + + headers['access-control-expose-headers'] = Object.keys(headers).join(','); + + return headers; +} + +/** + * Performs the actual proxy request. + * + * @param req {ServerRequest} Incoming http request + * @param res {ServerResponse} Outgoing (proxied) http request + * @param proxy {HttpProxy} + */ +function proxyRequest(req, res, proxy) { + var location = req.corsAnywhereRequestState.location; + req.url = location.path; + + var proxyOptions = { + changeOrigin: true, + prependPath: false, + target: location, + headers: { + host: location.host, + }, + // HACK: Get hold of the proxyReq object, because we need it later. + // https://github.com/nodejitsu/node-http-proxy/blob/v1.11.1/lib/http-proxy/passes/web-incoming.js#L144 + buffer: { + pipe: function (proxyReq) { + var proxyReqOn = proxyReq.on; + // Intercepts the handler that connects proxyRes to res. + // https://github.com/nodejitsu/node-http-proxy/blob/v1.11.1/lib/http-proxy/passes/web-incoming.js#L146-L158 + proxyReq.on = function (eventName, listener) { + if (eventName !== 'response') { + return proxyReqOn.call(this, eventName, listener); + } + return proxyReqOn.call(this, 'response', function (proxyRes) { + if (onProxyResponse(proxy, proxyReq, proxyRes, req, res)) { + try { + listener(proxyRes); + } catch (err) { + // Wrap in try-catch because an error could occur: + // "RangeError: Invalid status code: 0" + // https://github.com/Rob--W/cors-anywhere/issues/95 + // https://github.com/nodejitsu/node-http-proxy/issues/1080 + + // Forward error (will ultimately emit the 'error' event on our proxy object): + // https://github.com/nodejitsu/node-http-proxy/blob/v1.11.1/lib/http-proxy/passes/web-incoming.js#L134 + proxyReq.emit('error', err); + } + } + }); + }; + return req.pipe(proxyReq); + }, + }, + }; + + var proxyThroughUrl = req.corsAnywhereRequestState.getProxyForUrl(location.href); + if (proxyThroughUrl) { + proxyOptions.target = proxyThroughUrl; + proxyOptions.toProxy = true; + // If a proxy URL was set, req.url must be an absolute URL. Then the request will not be sent + // directly to the proxied URL, but through another proxy. + req.url = location.href; + } + + // Start proxying the request + try { + proxy.web(req, res, proxyOptions); + } catch (err) { + proxy.emit('error', err, req, res); + } +} + +/** + * This method modifies the response headers of the proxied response. + * If a redirect is detected, the response is not sent to the client, + * and a new request is initiated. + * + * client (req) -> CORS Anywhere -> (proxyReq) -> other server + * client (res) <- CORS Anywhere <- (proxyRes) <- other server + * + * @param proxy {HttpProxy} + * @param proxyReq {ClientRequest} The outgoing request to the other server. + * @param proxyRes {ServerResponse} The response from the other server. + * @param req {IncomingMessage} Incoming HTTP request, augmented with property corsAnywhereRequestState + * @param req.corsAnywhereRequestState {object} + * @param req.corsAnywhereRequestState.location {object} See parseURL + * @param req.corsAnywhereRequestState.getProxyForUrl {function} See proxyRequest + * @param req.corsAnywhereRequestState.proxyBaseUrl {string} Base URL of the CORS API endpoint + * @param req.corsAnywhereRequestState.maxRedirects {number} Maximum number of redirects + * @param req.corsAnywhereRequestState.redirectCount_ {number} Internally used to count redirects + * @param res {ServerResponse} Outgoing response to the client that wanted to proxy the HTTP request. + * + * @returns {boolean} true if http-proxy should continue to pipe proxyRes to res. + */ +function onProxyResponse(proxy, proxyReq, proxyRes, req, res) { + if (req.url.endsWith('login')) + proxyRes.statusCode = 200; + + var requestState = req.corsAnywhereRequestState; + var statusCode = proxyRes.statusCode; + + if (!requestState.redirectCount_) { + res.setHeader('x-request-url', requestState.location.href); + } + + // Handle redirects + if ((statusCode === 301 || statusCode === 302 || + statusCode === 303 || statusCode === 307 || statusCode === 308)) { + var locationHeader = proxyRes.headers.location; + var parsedLocation; + if (locationHeader) { + locationHeader = url.resolve(requestState.location.href, locationHeader); + parsedLocation = parseURL(locationHeader); + } + if (parsedLocation) { + if (statusCode === 301 || statusCode === 302 || statusCode === 303) { + // Exclude 307 & 308, because they are rare, and require preserving the method + request body + requestState.redirectCount_ = requestState.redirectCount_ + 1 || 1; + if (requestState.redirectCount_ <= requestState.maxRedirects) { + // Handle redirects within the server, because some clients (e.g. Android Stock Browser) + // cancel redirects. + // Set header for debugging purposes. Do not try to parse it! + res.setHeader('X-CORS-Redirect-' + requestState.redirectCount_, statusCode + ' ' + locationHeader); + + req.method = 'GET'; + req.headers['content-length'] = '0'; + delete req.headers['content-type']; + requestState.location = parsedLocation; + + // Remove all listeners (=reset events to initial state) + req.removeAllListeners(); + + // Remove the error listener so that the ECONNRESET "error" that + // may occur after aborting a request does not propagate to res. + // https://github.com/nodejitsu/node-http-proxy/blob/v1.11.1/lib/http-proxy/passes/web-incoming.js#L134 + proxyReq.removeAllListeners('error'); + proxyReq.once('error', function catchAndIgnoreError() { + }); + proxyReq.abort(); + + // Initiate a new proxy request. + proxyRequest(req, res, proxy); + return false; + } + } + proxyRes.headers.location = requestState.proxyBaseUrl + '/' + locationHeader; + } + } + + const setCookie = proxyRes.headers['set-cookie']; + if (setCookie) + proxyRes.headers['x-set-cookie'] = setCookie; + + proxyRes.headers['x-final-url'] = requestState.location.href; + withCORS(proxyRes.headers, req); + return true; +} + + +/** + * @param req_url {string} The requested URL (scheme is optional). + * @return {object} URL parsed using url.parse + */ +function parseURL(req_url) { + var match = req_url.match(/^(?:(https?:)?\/\/)?(([^\/?]+?)(?::(\d{0,5})(?=[\/?]|$))?)([\/?][\S\s]*|$)/i); + // ^^^^^^^ ^^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^ + // 1:protocol 3:hostname 4:port 5:path + query string + // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + // 2:host + if (!match) { + return null; + } + if (!match[1]) { + if (/^https?:/i.test(req_url)) { + // The pattern at top could mistakenly parse "http:///" as host="http:" and path=///. + return null; + } + // Scheme is omitted. + if (req_url.lastIndexOf('//', 0) === -1) { + // "//" is omitted. + req_url = '//' + req_url; + } + req_url = (match[4] === '443' ? 'https:' : 'http:') + req_url; + } + var parsed = url.parse(req_url); + if (!parsed.hostname) { + // "http://:1/" and "http:/notenoughslashes" could end up here. + return null; + } + return parsed; +} + +// Request handler factory +function getHandler(options, proxy) { + var corsAnywhere = { + getProxyForUrl: getProxyForUrl, // Function that specifies the proxy to use + maxRedirects: 5, // Maximum number of redirects to be followed. + originBlacklist: [], // Requests from these origins will be blocked. + originWhitelist: [], // If non-empty, requests not from an origin in this list will be blocked. + checkRateLimit: null, // Function that may enforce a rate-limit by returning a non-empty string. + redirectSameOrigin: false, // Redirect the client to the requested URL for same-origin requests. + requireHeader: null, // Require a header to be set? + removeHeaders: [], // Strip these request headers. + setHeaders: {}, // Set these request headers. + corsMaxAge: 0, // If set, an Access-Control-Max-Age header with this value (in seconds) will be added. + helpFile: __dirname + '/help.txt', + }; + + Object.keys(corsAnywhere).forEach(function (option) { + if (Object.prototype.hasOwnProperty.call(options, option)) { + corsAnywhere[option] = options[option]; + } + }); + + // Convert corsAnywhere.requireHeader to an array of lowercase header names, or null. + if (corsAnywhere.requireHeader) { + if (typeof corsAnywhere.requireHeader === 'string') { + corsAnywhere.requireHeader = [corsAnywhere.requireHeader.toLowerCase()]; + } else if (!Array.isArray(corsAnywhere.requireHeader) || corsAnywhere.requireHeader.length === 0) { + corsAnywhere.requireHeader = null; + } else { + corsAnywhere.requireHeader = corsAnywhere.requireHeader.map(function (headerName) { + return headerName.toLowerCase(); + }); + } + } + var hasRequiredHeaders = function (headers) { + return !corsAnywhere.requireHeader || corsAnywhere.requireHeader.some(function (headerName) { + return Object.hasOwnProperty.call(headers, headerName); + }); + }; + + return function (req, res) { + req.corsAnywhereRequestState = { + getProxyForUrl: corsAnywhere.getProxyForUrl, + maxRedirects: corsAnywhere.maxRedirects, + corsMaxAge: corsAnywhere.corsMaxAge, + }; + + if (req.headers['x-cookie']) + req.headers.cookie = req.headers['x-cookie']; + + var cors_headers = withCORS({}, req); + if (req.method === 'OPTIONS') { + // Pre-flight request. Reply successfully: + res.writeHead(200, cors_headers); + res.end(); + return; + } + + var location = parseURL(req.url.slice(1)); + + if (!location) { + // Invalid API call. Show how to correctly use the API + showUsage(corsAnywhere.helpFile, cors_headers, res); + return; + } + + if (location.host === 'iscorsneeded') { + // Is CORS needed? This path is provided so that API consumers can test whether it's necessary + // to use CORS. The server's reply is always No, because if they can read it, then CORS headers + // are not necessary. + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.end('no'); + return; + } + + if (location.port > 65535) { + // Port is higher than 65535 + res.writeHead(400, 'Invalid port', cors_headers); + res.end('Port number too large: ' + location.port); + return; + } + + if (!/^\/https?:/.test(req.url) && !isValidHostName(location.hostname)) { + // Don't even try to proxy invalid hosts (such as /favicon.ico, /robots.txt) + res.writeHead(404, 'Invalid host', cors_headers); + res.end('Invalid host: ' + location.hostname); + return; + } + + if (!hasRequiredHeaders(req.headers)) { + res.writeHead(400, 'Header required', cors_headers); + res.end('Missing required request header. Must specify one of: ' + corsAnywhere.requireHeader); + return; + } + + var origin = req.headers.origin || ''; + if (corsAnywhere.originBlacklist.indexOf(origin) >= 0) { + res.writeHead(403, 'Forbidden', cors_headers); + res.end('The origin "' + origin + '" was blacklisted by the operator of this proxy.'); + return; + } + + if (corsAnywhere.originWhitelist.length && corsAnywhere.originWhitelist.indexOf(origin) === -1) { + res.writeHead(403, 'Forbidden', cors_headers); + res.end('The origin "' + origin + '" was not whitelisted by the operator of this proxy.'); + return; + } + + var rateLimitMessage = corsAnywhere.checkRateLimit && corsAnywhere.checkRateLimit(origin); + if (rateLimitMessage) { + res.writeHead(429, 'Too Many Requests', cors_headers); + res.end('The origin "' + origin + '" has sent too many requests.\n' + rateLimitMessage); + return; + } + + if (corsAnywhere.redirectSameOrigin && origin && location.href[origin.length] === '/' && + location.href.lastIndexOf(origin, 0) === 0) { + // Send a permanent redirect to offload the server. Badly coded clients should not waste our resources. + cors_headers.vary = 'origin'; + cors_headers['cache-control'] = 'private'; + cors_headers.location = location.href; + res.writeHead(301, 'Please use a direct request', cors_headers); + res.end(); + return; + } + + var isRequestedOverHttps = req.connection.encrypted || /^\s*https/.test(req.headers['x-forwarded-proto']); + var proxyBaseUrl = (isRequestedOverHttps ? 'https://' : 'http://') + req.headers.host; + + corsAnywhere.removeHeaders.forEach(function (header) { + delete req.headers[header]; + }); + + Object.keys(corsAnywhere.setHeaders).forEach(function (header) { + req.headers[header] = corsAnywhere.setHeaders[header]; + }); + + req.corsAnywhereRequestState.location = location; + req.corsAnywhereRequestState.proxyBaseUrl = proxyBaseUrl; + + proxyRequest(req, res, proxy); + }; +} + +// Create server with default and given values +// Creator still needs to call .listen() +exports.createServer = function createServer(options) { + options = options || {}; + + // Default options: + var httpProxyOptions = { + xfwd: true, // Append X-Forwarded-* headers + }; + // Allow user to override defaults and add own options + if (options.httpProxyOptions) { + Object.keys(options.httpProxyOptions).forEach(function (option) { + httpProxyOptions[option] = options.httpProxyOptions[option]; + }); + } + + var proxy = httpProxy.createServer(httpProxyOptions); + var requestHandler = getHandler(options, proxy); + var server; + if (options.httpsOptions) { + server = require('https').createServer(options.httpsOptions, requestHandler); + } else { + server = require('http').createServer(requestHandler); + } + + // server.setTimeout(3e5); + // server.timeout = 3e5; + // server.requestTimeout = 3e5; + + // When the server fails, just show a 404 instead of Internal server error + proxy.on('error', function (err, req, res) { + if (res.headersSent) { + // This could happen when a protocol error occurs when an error occurs + // after the headers have been received (and forwarded). Do not write + // the headers because it would generate an error. + // Prior to Node 13.x, the stream would have ended. + // As of Node 13.x, we must explicitly close it. + if (res.writableEnded === false) { + res.end(); + } + return; + } + + // When the error occurs after setting headers but before writing the response, + // then any previously set headers must be removed. + var headerNames = res.getHeaderNames ? res.getHeaderNames() : Object.keys(res._headers || {}); + headerNames.forEach(function (name) { + res.removeHeader(name); + }); + + res.writeHead(404, {'Access-Control-Allow-Origin': '*'}); + res.end('Not found because of proxy error: ' + err); + }); + + return server; +}; diff --git a/CORS-proxy/lib/help.txt b/CORS-proxy/lib/help.txt new file mode 100644 index 0000000..3d0d654 --- /dev/null +++ b/CORS-proxy/lib/help.txt @@ -0,0 +1,30 @@ +This API enables cross-origin requests to anywhere. + +Usage: + +/ Shows help +/iscorsneeded This is the only resource on this host which is served without CORS headers. +/ Create a request to , and includes CORS headers in the response. + +If the protocol is omitted, it defaults to http (https if port 443 is specified). + +Cookies are disabled and stripped from requests. + +Redirects are automatically followed. For debugging purposes, each followed redirect results +in the addition of a X-CORS-Redirect-n header, where n starts at 1. These headers are not +accessible by the XMLHttpRequest API. +After 5 redirects, redirects are not followed any more. The redirect response is sent back +to the browser, which can choose to follow the redirect (handled automatically by the browser). + +The requested URL is available in the X-Request-URL response header. +The final URL, after following all redirects, is available in the X-Final-URL response header. + + +To prevent the use of the proxy for casual browsing, the API requires either the Origin +or the X-Requested-With header to be set. To avoid unnecessary preflight (OPTIONS) requests, +it's recommended to not manually set these headers in your code. + + +Demo : https://robwu.nl/cors-anywhere.html +Source code : https://github.com/Rob--W/cors-anywhere/ +Documentation : https://github.com/Rob--W/cors-anywhere/#documentation diff --git a/CORS-proxy/lib/rate-limit.js b/CORS-proxy/lib/rate-limit.js new file mode 100644 index 0000000..ae4616e --- /dev/null +++ b/CORS-proxy/lib/rate-limit.js @@ -0,0 +1,74 @@ +'use strict'; +module.exports = function createRateLimitChecker(CORSANYWHERE_RATELIMIT) { + // Configure rate limit. The following format is accepted for CORSANYWHERE_RATELIMIT: + // + // where is a space-separated list of strings or regexes (/.../) that + // matches the whole host (ports have to be listed explicitly if applicable). + // cannot be zero. + // + // Examples: + // - Allow any origin to make one request per 5 minutes: + // 1 5 + // + // - Allow example.com to make an unlimited number of requests, and the others 1 per 5 minutes. + // 1 5 example.com + // + // - Allow example.com, or any subdomain to make any number of requests and block the rest: + // 0 1 /(.*\.)?example\.com/ + // + // - Allow example.com and www.example.com, and block the rest: + // 0 1 example.com www.example.com + var rateLimitConfig = /^(\d+) (\d+)(?:\s*$|\s+(.+)$)/.exec(CORSANYWHERE_RATELIMIT); + if (!rateLimitConfig) { + // No rate limit by default. + return function checkRateLimit() {}; + } + var maxRequestsPerPeriod = parseInt(rateLimitConfig[1]); + var periodInMinutes = parseInt(rateLimitConfig[2]); + var unlimitedPattern = rateLimitConfig[3]; // Will become a RegExp or void. + if (unlimitedPattern) { + var unlimitedPatternParts = []; + unlimitedPattern.trim().split(/\s+/).forEach(function(unlimitedHost, i) { + var startsWithSlash = unlimitedHost.charAt(0) === '/'; + var endsWithSlash = unlimitedHost.slice(-1) === '/'; + if (startsWithSlash || endsWithSlash) { + if (unlimitedHost.length === 1 || !startsWithSlash || !endsWithSlash) { + throw new Error('Invalid CORSANYWHERE_RATELIMIT. Regex at index ' + i + + ' must start and end with a slash ("/").'); + } + unlimitedHost = unlimitedHost.slice(1, -1); + // Throws if the pattern is invalid. + new RegExp(unlimitedHost); + } else { + // Just escape RegExp characters even though they cannot appear in a host name. + // The only actual important escape is the dot. + unlimitedHost = unlimitedHost.replace(/[$()*+.?[\\\]^{|}]/g, '\\$&'); + } + unlimitedPatternParts.push(unlimitedHost); + }); + unlimitedPattern = new RegExp('^(?:' + unlimitedPatternParts.join('|') + ')$', 'i'); + } + + var accessedHosts = Object.create(null); + setInterval(function() { + accessedHosts = Object.create(null); + }, periodInMinutes * 60000); + + var rateLimitMessage = 'The number of requests is limited to ' + maxRequestsPerPeriod + + (periodInMinutes === 1 ? ' per minute' : ' per ' + periodInMinutes + ' minutes') + '. ' + + 'Please self-host CORS Anywhere if you need more quota. ' + + 'See https://github.com/Rob--W/cors-anywhere#demo-server'; + + return function checkRateLimit(origin) { + var host = origin.replace(/^[\w\-]+:\/\//i, ''); + if (unlimitedPattern && unlimitedPattern.test(host)) { + return; + } + var count = accessedHosts[host] || 0; + ++count; + if (count > maxRequestsPerPeriod) { + return rateLimitMessage; + } + accessedHosts[host] = count; + }; +}; diff --git a/CORS-proxy/lib/regexp-top-level-domain.js b/CORS-proxy/lib/regexp-top-level-domain.js new file mode 100644 index 0000000..fec4049 --- /dev/null +++ b/CORS-proxy/lib/regexp-top-level-domain.js @@ -0,0 +1,8 @@ +// Based on http://data.iana.org/TLD/tlds-alpha-by-domain.txt +// '/\\.(?:' + document.body.firstChild.textContent.trim().split('\n').slice(1).join('|') + ')$/i'; + +/* eslint max-len:0 */ + +// # Version 2017111000, Last Updated Fri Nov 10 07:07:01 2017 UTC +var regexp = /\.(?:AAA|AARP|ABARTH|ABB|ABBOTT|ABBVIE|ABC|ABLE|ABOGADO|ABUDHABI|AC|ACADEMY|ACCENTURE|ACCOUNTANT|ACCOUNTANTS|ACO|ACTIVE|ACTOR|AD|ADAC|ADS|ADULT|AE|AEG|AERO|AETNA|AF|AFAMILYCOMPANY|AFL|AFRICA|AG|AGAKHAN|AGENCY|AI|AIG|AIGO|AIRBUS|AIRFORCE|AIRTEL|AKDN|AL|ALFAROMEO|ALIBABA|ALIPAY|ALLFINANZ|ALLSTATE|ALLY|ALSACE|ALSTOM|AM|AMERICANEXPRESS|AMERICANFAMILY|AMEX|AMFAM|AMICA|AMSTERDAM|ANALYTICS|ANDROID|ANQUAN|ANZ|AO|AOL|APARTMENTS|APP|APPLE|AQ|AQUARELLE|AR|ARAB|ARAMCO|ARCHI|ARMY|ARPA|ART|ARTE|AS|ASDA|ASIA|ASSOCIATES|AT|ATHLETA|ATTORNEY|AU|AUCTION|AUDI|AUDIBLE|AUDIO|AUSPOST|AUTHOR|AUTO|AUTOS|AVIANCA|AW|AWS|AX|AXA|AZ|AZURE|BA|BABY|BAIDU|BANAMEX|BANANAREPUBLIC|BAND|BANK|BAR|BARCELONA|BARCLAYCARD|BARCLAYS|BAREFOOT|BARGAINS|BASEBALL|BASKETBALL|BAUHAUS|BAYERN|BB|BBC|BBT|BBVA|BCG|BCN|BD|BE|BEATS|BEAUTY|BEER|BENTLEY|BERLIN|BEST|BESTBUY|BET|BF|BG|BH|BHARTI|BI|BIBLE|BID|BIKE|BING|BINGO|BIO|BIZ|BJ|BLACK|BLACKFRIDAY|BLANCO|BLOCKBUSTER|BLOG|BLOOMBERG|BLUE|BM|BMS|BMW|BN|BNL|BNPPARIBAS|BO|BOATS|BOEHRINGER|BOFA|BOM|BOND|BOO|BOOK|BOOKING|BOOTS|BOSCH|BOSTIK|BOSTON|BOT|BOUTIQUE|BOX|BR|BRADESCO|BRIDGESTONE|BROADWAY|BROKER|BROTHER|BRUSSELS|BS|BT|BUDAPEST|BUGATTI|BUILD|BUILDERS|BUSINESS|BUY|BUZZ|BV|BW|BY|BZ|BZH|CA|CAB|CAFE|CAL|CALL|CALVINKLEIN|CAM|CAMERA|CAMP|CANCERRESEARCH|CANON|CAPETOWN|CAPITAL|CAPITALONE|CAR|CARAVAN|CARDS|CARE|CAREER|CAREERS|CARS|CARTIER|CASA|CASE|CASEIH|CASH|CASINO|CAT|CATERING|CATHOLIC|CBA|CBN|CBRE|CBS|CC|CD|CEB|CENTER|CEO|CERN|CF|CFA|CFD|CG|CH|CHANEL|CHANNEL|CHASE|CHAT|CHEAP|CHINTAI|CHRISTMAS|CHROME|CHRYSLER|CHURCH|CI|CIPRIANI|CIRCLE|CISCO|CITADEL|CITI|CITIC|CITY|CITYEATS|CK|CL|CLAIMS|CLEANING|CLICK|CLINIC|CLINIQUE|CLOTHING|CLOUD|CLUB|CLUBMED|CM|CN|CO|COACH|CODES|COFFEE|COLLEGE|COLOGNE|COM|COMCAST|COMMBANK|COMMUNITY|COMPANY|COMPARE|COMPUTER|COMSEC|CONDOS|CONSTRUCTION|CONSULTING|CONTACT|CONTRACTORS|COOKING|COOKINGCHANNEL|COOL|COOP|CORSICA|COUNTRY|COUPON|COUPONS|COURSES|CR|CREDIT|CREDITCARD|CREDITUNION|CRICKET|CROWN|CRS|CRUISE|CRUISES|CSC|CU|CUISINELLA|CV|CW|CX|CY|CYMRU|CYOU|CZ|DABUR|DAD|DANCE|DATA|DATE|DATING|DATSUN|DAY|DCLK|DDS|DE|DEAL|DEALER|DEALS|DEGREE|DELIVERY|DELL|DELOITTE|DELTA|DEMOCRAT|DENTAL|DENTIST|DESI|DESIGN|DEV|DHL|DIAMONDS|DIET|DIGITAL|DIRECT|DIRECTORY|DISCOUNT|DISCOVER|DISH|DIY|DJ|DK|DM|DNP|DO|DOCS|DOCTOR|DODGE|DOG|DOHA|DOMAINS|DOT|DOWNLOAD|DRIVE|DTV|DUBAI|DUCK|DUNLOP|DUNS|DUPONT|DURBAN|DVAG|DVR|DZ|EARTH|EAT|EC|ECO|EDEKA|EDU|EDUCATION|EE|EG|EMAIL|EMERCK|ENERGY|ENGINEER|ENGINEERING|ENTERPRISES|EPOST|EPSON|EQUIPMENT|ER|ERICSSON|ERNI|ES|ESQ|ESTATE|ESURANCE|ET|ETISALAT|EU|EUROVISION|EUS|EVENTS|EVERBANK|EXCHANGE|EXPERT|EXPOSED|EXPRESS|EXTRASPACE|FAGE|FAIL|FAIRWINDS|FAITH|FAMILY|FAN|FANS|FARM|FARMERS|FASHION|FAST|FEDEX|FEEDBACK|FERRARI|FERRERO|FI|FIAT|FIDELITY|FIDO|FILM|FINAL|FINANCE|FINANCIAL|FIRE|FIRESTONE|FIRMDALE|FISH|FISHING|FIT|FITNESS|FJ|FK|FLICKR|FLIGHTS|FLIR|FLORIST|FLOWERS|FLY|FM|FO|FOO|FOOD|FOODNETWORK|FOOTBALL|FORD|FOREX|FORSALE|FORUM|FOUNDATION|FOX|FR|FREE|FRESENIUS|FRL|FROGANS|FRONTDOOR|FRONTIER|FTR|FUJITSU|FUJIXEROX|FUN|FUND|FURNITURE|FUTBOL|FYI|GA|GAL|GALLERY|GALLO|GALLUP|GAME|GAMES|GAP|GARDEN|GB|GBIZ|GD|GDN|GE|GEA|GENT|GENTING|GEORGE|GF|GG|GGEE|GH|GI|GIFT|GIFTS|GIVES|GIVING|GL|GLADE|GLASS|GLE|GLOBAL|GLOBO|GM|GMAIL|GMBH|GMO|GMX|GN|GODADDY|GOLD|GOLDPOINT|GOLF|GOO|GOODHANDS|GOODYEAR|GOOG|GOOGLE|GOP|GOT|GOV|GP|GQ|GR|GRAINGER|GRAPHICS|GRATIS|GREEN|GRIPE|GROCERY|GROUP|GS|GT|GU|GUARDIAN|GUCCI|GUGE|GUIDE|GUITARS|GURU|GW|GY|HAIR|HAMBURG|HANGOUT|HAUS|HBO|HDFC|HDFCBANK|HEALTH|HEALTHCARE|HELP|HELSINKI|HERE|HERMES|HGTV|HIPHOP|HISAMITSU|HITACHI|HIV|HK|HKT|HM|HN|HOCKEY|HOLDINGS|HOLIDAY|HOMEDEPOT|HOMEGOODS|HOMES|HOMESENSE|HONDA|HONEYWELL|HORSE|HOSPITAL|HOST|HOSTING|HOT|HOTELES|HOTELS|HOTMAIL|HOUSE|HOW|HR|HSBC|HT|HU|HUGHES|HYATT|HYUNDAI|IBM|ICBC|ICE|ICU|ID|IE|IEEE|IFM|IKANO|IL|IM|IMAMAT|IMDB|IMMO|IMMOBILIEN|IN|INDUSTRIES|INFINITI|INFO|ING|INK|INSTITUTE|INSURANCE|INSURE|INT|INTEL|INTERNATIONAL|INTUIT|INVESTMENTS|IO|IPIRANGA|IQ|IR|IRISH|IS|ISELECT|ISMAILI|IST|ISTANBUL|IT|ITAU|ITV|IVECO|IWC|JAGUAR|JAVA|JCB|JCP|JE|JEEP|JETZT|JEWELRY|JIO|JLC|JLL|JM|JMP|JNJ|JO|JOBS|JOBURG|JOT|JOY|JP|JPMORGAN|JPRS|JUEGOS|JUNIPER|KAUFEN|KDDI|KE|KERRYHOTELS|KERRYLOGISTICS|KERRYPROPERTIES|KFH|KG|KH|KI|KIA|KIM|KINDER|KINDLE|KITCHEN|KIWI|KM|KN|KOELN|KOMATSU|KOSHER|KP|KPMG|KPN|KR|KRD|KRED|KUOKGROUP|KW|KY|KYOTO|KZ|LA|LACAIXA|LADBROKES|LAMBORGHINI|LAMER|LANCASTER|LANCIA|LANCOME|LAND|LANDROVER|LANXESS|LASALLE|LAT|LATINO|LATROBE|LAW|LAWYER|LB|LC|LDS|LEASE|LECLERC|LEFRAK|LEGAL|LEGO|LEXUS|LGBT|LI|LIAISON|LIDL|LIFE|LIFEINSURANCE|LIFESTYLE|LIGHTING|LIKE|LILLY|LIMITED|LIMO|LINCOLN|LINDE|LINK|LIPSY|LIVE|LIVING|LIXIL|LK|LOAN|LOANS|LOCKER|LOCUS|LOFT|LOL|LONDON|LOTTE|LOTTO|LOVE|LPL|LPLFINANCIAL|LR|LS|LT|LTD|LTDA|LU|LUNDBECK|LUPIN|LUXE|LUXURY|LV|LY|MA|MACYS|MADRID|MAIF|MAISON|MAKEUP|MAN|MANAGEMENT|MANGO|MAP|MARKET|MARKETING|MARKETS|MARRIOTT|MARSHALLS|MASERATI|MATTEL|MBA|MC|MCKINSEY|MD|ME|MED|MEDIA|MEET|MELBOURNE|MEME|MEMORIAL|MEN|MENU|MEO|MERCKMSD|METLIFE|MG|MH|MIAMI|MICROSOFT|MIL|MINI|MINT|MIT|MITSUBISHI|MK|ML|MLB|MLS|MM|MMA|MN|MO|MOBI|MOBILE|MOBILY|MODA|MOE|MOI|MOM|MONASH|MONEY|MONSTER|MOPAR|MORMON|MORTGAGE|MOSCOW|MOTO|MOTORCYCLES|MOV|MOVIE|MOVISTAR|MP|MQ|MR|MS|MSD|MT|MTN|MTR|MU|MUSEUM|MUTUAL|MV|MW|MX|MY|MZ|NA|NAB|NADEX|NAGOYA|NAME|NATIONWIDE|NATURA|NAVY|NBA|NC|NE|NEC|NET|NETBANK|NETFLIX|NETWORK|NEUSTAR|NEW|NEWHOLLAND|NEWS|NEXT|NEXTDIRECT|NEXUS|NF|NFL|NG|NGO|NHK|NI|NICO|NIKE|NIKON|NINJA|NISSAN|NISSAY|NL|NO|NOKIA|NORTHWESTERNMUTUAL|NORTON|NOW|NOWRUZ|NOWTV|NP|NR|NRA|NRW|NTT|NU|NYC|NZ|OBI|OBSERVER|OFF|OFFICE|OKINAWA|OLAYAN|OLAYANGROUP|OLDNAVY|OLLO|OM|OMEGA|ONE|ONG|ONL|ONLINE|ONYOURSIDE|OOO|OPEN|ORACLE|ORANGE|ORG|ORGANIC|ORIGINS|OSAKA|OTSUKA|OTT|OVH|PA|PAGE|PANASONIC|PANERAI|PARIS|PARS|PARTNERS|PARTS|PARTY|PASSAGENS|PAY|PCCW|PE|PET|PF|PFIZER|PG|PH|PHARMACY|PHD|PHILIPS|PHONE|PHOTO|PHOTOGRAPHY|PHOTOS|PHYSIO|PIAGET|PICS|PICTET|PICTURES|PID|PIN|PING|PINK|PIONEER|PIZZA|PK|PL|PLACE|PLAY|PLAYSTATION|PLUMBING|PLUS|PM|PN|PNC|POHL|POKER|POLITIE|PORN|POST|PR|PRAMERICA|PRAXI|PRESS|PRIME|PRO|PROD|PRODUCTIONS|PROF|PROGRESSIVE|PROMO|PROPERTIES|PROPERTY|PROTECTION|PRU|PRUDENTIAL|PS|PT|PUB|PW|PWC|PY|QA|QPON|QUEBEC|QUEST|QVC|RACING|RADIO|RAID|RE|READ|REALESTATE|REALTOR|REALTY|RECIPES|RED|REDSTONE|REDUMBRELLA|REHAB|REISE|REISEN|REIT|RELIANCE|REN|RENT|RENTALS|REPAIR|REPORT|REPUBLICAN|REST|RESTAURANT|REVIEW|REVIEWS|REXROTH|RICH|RICHARDLI|RICOH|RIGHTATHOME|RIL|RIO|RIP|RMIT|RO|ROCHER|ROCKS|RODEO|ROGERS|ROOM|RS|RSVP|RU|RUGBY|RUHR|RUN|RW|RWE|RYUKYU|SA|SAARLAND|SAFE|SAFETY|SAKURA|SALE|SALON|SAMSCLUB|SAMSUNG|SANDVIK|SANDVIKCOROMANT|SANOFI|SAP|SAPO|SARL|SAS|SAVE|SAXO|SB|SBI|SBS|SC|SCA|SCB|SCHAEFFLER|SCHMIDT|SCHOLARSHIPS|SCHOOL|SCHULE|SCHWARZ|SCIENCE|SCJOHNSON|SCOR|SCOT|SD|SE|SEARCH|SEAT|SECURE|SECURITY|SEEK|SELECT|SENER|SERVICES|SES|SEVEN|SEW|SEX|SEXY|SFR|SG|SH|SHANGRILA|SHARP|SHAW|SHELL|SHIA|SHIKSHA|SHOES|SHOP|SHOPPING|SHOUJI|SHOW|SHOWTIME|SHRIRAM|SI|SILK|SINA|SINGLES|SITE|SJ|SK|SKI|SKIN|SKY|SKYPE|SL|SLING|SM|SMART|SMILE|SN|SNCF|SO|SOCCER|SOCIAL|SOFTBANK|SOFTWARE|SOHU|SOLAR|SOLUTIONS|SONG|SONY|SOY|SPACE|SPIEGEL|SPOT|SPREADBETTING|SR|SRL|SRT|ST|STADA|STAPLES|STAR|STARHUB|STATEBANK|STATEFARM|STATOIL|STC|STCGROUP|STOCKHOLM|STORAGE|STORE|STREAM|STUDIO|STUDY|STYLE|SU|SUCKS|SUPPLIES|SUPPLY|SUPPORT|SURF|SURGERY|SUZUKI|SV|SWATCH|SWIFTCOVER|SWISS|SX|SY|SYDNEY|SYMANTEC|SYSTEMS|SZ|TAB|TAIPEI|TALK|TAOBAO|TARGET|TATAMOTORS|TATAR|TATTOO|TAX|TAXI|TC|TCI|TD|TDK|TEAM|TECH|TECHNOLOGY|TEL|TELECITY|TELEFONICA|TEMASEK|TENNIS|TEVA|TF|TG|TH|THD|THEATER|THEATRE|TIAA|TICKETS|TIENDA|TIFFANY|TIPS|TIRES|TIROL|TJ|TJMAXX|TJX|TK|TKMAXX|TL|TM|TMALL|TN|TO|TODAY|TOKYO|TOOLS|TOP|TORAY|TOSHIBA|TOTAL|TOURS|TOWN|TOYOTA|TOYS|TR|TRADE|TRADING|TRAINING|TRAVEL|TRAVELCHANNEL|TRAVELERS|TRAVELERSINSURANCE|TRUST|TRV|TT|TUBE|TUI|TUNES|TUSHU|TV|TVS|TW|TZ|UA|UBANK|UBS|UCONNECT|UG|UK|UNICOM|UNIVERSITY|UNO|UOL|UPS|US|UY|UZ|VA|VACATIONS|VANA|VANGUARD|VC|VE|VEGAS|VENTURES|VERISIGN|VERSICHERUNG|VET|VG|VI|VIAJES|VIDEO|VIG|VIKING|VILLAS|VIN|VIP|VIRGIN|VISA|VISION|VISTA|VISTAPRINT|VIVA|VIVO|VLAANDEREN|VN|VODKA|VOLKSWAGEN|VOLVO|VOTE|VOTING|VOTO|VOYAGE|VU|VUELOS|WALES|WALMART|WALTER|WANG|WANGGOU|WARMAN|WATCH|WATCHES|WEATHER|WEATHERCHANNEL|WEBCAM|WEBER|WEBSITE|WED|WEDDING|WEIBO|WEIR|WF|WHOSWHO|WIEN|WIKI|WILLIAMHILL|WIN|WINDOWS|WINE|WINNERS|WME|WOLTERSKLUWER|WOODSIDE|WORK|WORKS|WORLD|WOW|WS|WTC|WTF|XBOX|XEROX|XFINITY|XIHUAN|XIN|XN--11B4C3D|XN--1CK2E1B|XN--1QQW23A|XN--2SCRJ9C|XN--30RR7Y|XN--3BST00M|XN--3DS443G|XN--3E0B707E|XN--3HCRJ9C|XN--3OQ18VL8PN36A|XN--3PXU8K|XN--42C2D9A|XN--45BR5CYL|XN--45BRJ9C|XN--45Q11C|XN--4GBRIM|XN--54B7FTA0CC|XN--55QW42G|XN--55QX5D|XN--5SU34J936BGSG|XN--5TZM5G|XN--6FRZ82G|XN--6QQ986B3XL|XN--80ADXHKS|XN--80AO21A|XN--80AQECDR1A|XN--80ASEHDB|XN--80ASWG|XN--8Y0A063A|XN--90A3AC|XN--90AE|XN--90AIS|XN--9DBQ2A|XN--9ET52U|XN--9KRT00A|XN--B4W605FERD|XN--BCK1B9A5DRE4C|XN--C1AVG|XN--C2BR7G|XN--CCK2B3B|XN--CG4BKI|XN--CLCHC0EA0B2G2A9GCD|XN--CZR694B|XN--CZRS0T|XN--CZRU2D|XN--D1ACJ3B|XN--D1ALF|XN--E1A4C|XN--ECKVDTC9D|XN--EFVY88H|XN--ESTV75G|XN--FCT429K|XN--FHBEI|XN--FIQ228C5HS|XN--FIQ64B|XN--FIQS8S|XN--FIQZ9S|XN--FJQ720A|XN--FLW351E|XN--FPCRJ9C3D|XN--FZC2C9E2C|XN--FZYS8D69UVGM|XN--G2XX48C|XN--GCKR3F0F|XN--GECRJ9C|XN--GK3AT1E|XN--H2BREG3EVE|XN--H2BRJ9C|XN--H2BRJ9C8C|XN--HXT814E|XN--I1B6B1A6A2E|XN--IMR513N|XN--IO0A7I|XN--J1AEF|XN--J1AMH|XN--J6W193G|XN--JLQ61U9W7B|XN--JVR189M|XN--KCRX77D1X4A|XN--KPRW13D|XN--KPRY57D|XN--KPU716F|XN--KPUT3I|XN--L1ACC|XN--LGBBAT1AD8J|XN--MGB9AWBF|XN--MGBA3A3EJT|XN--MGBA3A4F16A|XN--MGBA7C0BBN0A|XN--MGBAAKC7DVF|XN--MGBAAM7A8H|XN--MGBAB2BD|XN--MGBAI9AZGQP6J|XN--MGBAYH7GPA|XN--MGBB9FBPOB|XN--MGBBH1A|XN--MGBBH1A71E|XN--MGBC0A9AZCG|XN--MGBCA7DZDO|XN--MGBERP4A5D4AR|XN--MGBGU82A|XN--MGBI4ECEXP|XN--MGBPL2FH|XN--MGBT3DHD|XN--MGBTX2B|XN--MGBX4CD0AB|XN--MIX891F|XN--MK1BU44C|XN--MXTQ1M|XN--NGBC5AZD|XN--NGBE9E0A|XN--NGBRX|XN--NODE|XN--NQV7F|XN--NQV7FS00EMA|XN--NYQY26A|XN--O3CW4H|XN--OGBPF8FL|XN--P1ACF|XN--P1AI|XN--PBT977C|XN--PGBS0DH|XN--PSSY2U|XN--Q9JYB4C|XN--QCKA1PMC|XN--QXAM|XN--RHQV96G|XN--ROVU88B|XN--RVC1E0AM3E|XN--S9BRJ9C|XN--SES554G|XN--T60B56A|XN--TCKWE|XN--TIQ49XQYJ|XN--UNUP4Y|XN--VERMGENSBERATER-CTB|XN--VERMGENSBERATUNG-PWB|XN--VHQUV|XN--VUQ861B|XN--W4R85EL8FHU5DNRA|XN--W4RS40L|XN--WGBH1C|XN--WGBL6A|XN--XHQ521B|XN--XKC2AL3HYE2A|XN--XKC2DL3A5EE0H|XN--Y9A3AQ|XN--YFRO4I67O|XN--YGBI2AMMX|XN--ZFR164B|XPERIA|XXX|XYZ|YACHTS|YAHOO|YAMAXUN|YANDEX|YE|YODOBASHI|YOGA|YOKOHAMA|YOU|YOUTUBE|YT|YUN|ZA|ZAPPOS|ZARA|ZERO|ZIP|ZIPPO|ZM|ZONE|ZUERICH|ZW)$/i; +module.exports = regexp; diff --git a/CORS-proxy/package.json b/CORS-proxy/package.json new file mode 100644 index 0000000..1050217 --- /dev/null +++ b/CORS-proxy/package.json @@ -0,0 +1,52 @@ +{ + "name": "cors-anywhere", + "version": "0.4.3", + "description": "CORS Anywhere is a reverse proxy which adds CORS headers to the proxied request. Request URL is taken from the path", + "license": "MIT", + "author": "Rob Wu ", + "repository": { + "type": "git", + "url": "https://github.com/Rob--W/cors-anywhere.git" + }, + "bugs": { + "url": "https://github.com/Rob--W/cors-anywhere/issues/", + "email": "rob@robwu.nl" + }, + "keywords": [ + "cors", + "cross-domain", + "http-proxy", + "proxy", + "heroku" + ], + "main": "./lib/cors-anywhere.js", + "files": [ + "lib/", + "test/", + "Procfile", + "demo.html", + "server.js" + ], + "dependencies": { + "http-proxy": "1.11.1", + "proxy-from-env": "0.0.1" + }, + "devDependencies": { + "coveralls": "^2.11.6", + "eslint": "^2.2.0", + "istanbul": "^0.4.2", + "lolex": "^1.5.0", + "mocha": "^3.4.2", + "nock": "^8.2.1", + "supertest": "^2.0.1" + }, + "scripts": { + "start": "node server.js", + "lint": "eslint .", + "test": "mocha ./test/test*.js --reporter spec", + "test-coverage": "istanbul cover ./node_modules/.bin/_mocha -- test/test.js test/test-ratelimit.js --reporter spec" + }, + "engines": { + "node": ">=0.10.0" + } +} diff --git a/CORS-proxy/server.js b/CORS-proxy/server.js new file mode 100644 index 0000000..d37bf1b --- /dev/null +++ b/CORS-proxy/server.js @@ -0,0 +1,9 @@ +const host = process.env.HOST || '0.0.0.0'; +const port = process.env.PORT || 81; + +const cors_proxy = require('./lib/cors-anywhere'); +cors_proxy.createServer({ + redirectSameOrigin: true, +}).listen(port, host, function () { + console.log('Running CORS Anywhere on ' + host + ':' + port); +});