Best JavaScript code snippet using pact-foundation-pact
test.js
Source:test.js
1/* eslint-env mocha */2require('./setup');3var createServer = require('../').createServer;4var request = require('supertest');5var path = require('path');6var http = require('http');7var https = require('https');8var fs = require('fs');9var assert = require('assert');10var helpTextPath = path.join(__dirname, '../lib/help.txt');11var helpText = fs.readFileSync(helpTextPath, {encoding: 'utf8'});12request.Test.prototype.expectJSON = function(json, done) {13 this.expect(function(res) {14 // Assume that the response can be parsed as JSON (otherwise it throws).15 var actual = JSON.parse(res.text);16 assert.deepEqual(actual, json);17 });18 return done ? this.end(done) : this;19};20request.Test.prototype.expectNoHeader = function(header, done) {21 this.expect(function(res) {22 if (header.toLowerCase() in res.headers) {23 return new Error('Unexpected header in response: ' + header);24 }25 });26 return done ? this.end(done) : this;27};28var cors_anywhere;29var cors_anywhere_port;30function stopServer(done) {31 cors_anywhere.close(function() {32 done();33 });34 cors_anywhere = null;35}36describe('Basic functionality', function() {37 before(function() {38 cors_anywhere = createServer();39 cors_anywhere_port = cors_anywhere.listen(0).address().port;40 });41 after(stopServer);42 it('GET /', function(done) {43 request(cors_anywhere)44 .get('/')45 .type('text/plain')46 .expect('Access-Control-Allow-Origin', '*')47 .expect(200, helpText, done);48 });49 it('GET /iscorsneeded', function(done) {50 request(cors_anywhere)51 .get('/iscorsneeded')52 .expectNoHeader('access-control-allow-origin', done);53 });54 it('GET /example.com:65536', function(done) {55 request(cors_anywhere)56 .get('/example.com:65536')57 .expect('Access-Control-Allow-Origin', '*')58 .expect(400, 'Port number too large: 65536', done);59 });60 it('GET /favicon.ico', function(done) {61 request(cors_anywhere)62 .get('/favicon.ico')63 .expect('Access-Control-Allow-Origin', '*')64 .expect(404, 'Invalid host: favicon.ico', done);65 });66 it('GET /robots.txt', function(done) {67 request(cors_anywhere)68 .get('/robots.txt')69 .expect('Access-Control-Allow-Origin', '*')70 .expect(404, 'Invalid host: robots.txt', done);71 });72 it('GET /http://robots.txt should be proxied', function(done) {73 request(cors_anywhere)74 .get('/http://robots.txt')75 .expect('Access-Control-Allow-Origin', '*')76 .expect(200, 'this is http://robots.txt', done);77 });78 it('GET /example.com', function(done) {79 request(cors_anywhere)80 .get('/example.com')81 .expect('Access-Control-Allow-Origin', '*')82 .expect('x-request-url', 'http://example.com/')83 .expect(200, 'Response from example.com', done);84 });85 it('GET /example.com:80', function(done) {86 request(cors_anywhere)87 .get('/example.com:80')88 .expect('Access-Control-Allow-Origin', '*')89 .expect('x-request-url', 'http://example.com:80/')90 .expect(200, 'Response from example.com', done);91 });92 it('GET /example.com:443', function(done) {93 request(cors_anywhere)94 .get('/example.com:443')95 .expect('Access-Control-Allow-Origin', '*')96 .expect('x-request-url', 'https://example.com:443/')97 .expect(200, 'Response from https://example.com', done);98 });99 it('GET //example.com', function(done) {100 // '/example.com' is an invalid URL.101 request(cors_anywhere)102 .get('//example.com')103 .expect('Access-Control-Allow-Origin', '*')104 .expect(200, helpText, done);105 });106 it('GET /http://:1234', function(done) {107 // 'http://:1234' is an invalid URL.108 request(cors_anywhere)109 .get('/http://:1234')110 .expect('Access-Control-Allow-Origin', '*')111 .expect(200, helpText, done);112 });113 it('GET /http:///', function(done) {114 // 'http://:1234' is an invalid URL.115 request(cors_anywhere)116 .get('/http:///')117 .expect('Access-Control-Allow-Origin', '*')118 .expect(200, helpText, done);119 });120 it('GET /http:/notenoughslashes', function(done) {121 // 'http:/notenoughslashes' is an invalid URL.122 request(cors_anywhere)123 .get('/http:/notenoughslashes')124 .expect('Access-Control-Allow-Origin', '*')125 .expect(400, 'The URL is invalid: two slashes are needed after the http(s):.', done);126 });127 it('GET ///example.com', function(done) {128 // API base URL (with trailing slash) + '//example.com'129 request(cors_anywhere)130 .get('///example.com')131 .expect('Access-Control-Allow-Origin', '*')132 .expect('x-request-url', 'http://example.com/')133 .expect(200, 'Response from example.com', done);134 });135 it('GET /http://example.com', function(done) {136 request(cors_anywhere)137 .get('/http://example.com')138 .expect('Access-Control-Allow-Origin', '*')139 .expect('x-request-url', 'http://example.com/')140 .expect(200, 'Response from example.com', done);141 });142 it('POST plain text', function(done) {143 request(cors_anywhere)144 .post('/example.com/echopost')145 .send('{"this is a request body & should not be mangled":1.00}')146 .expect('Access-Control-Allow-Origin', '*')147 .expect('{"this is a request body & should not be mangled":1.00}', done);148 });149 it('POST file', function(done) {150 request(cors_anywhere)151 .post('/example.com/echopost')152 .attach('file', path.join(__dirname, 'dummy.txt'))153 .expect('Access-Control-Allow-Origin', '*')154 .expect(/\r\nContent-Disposition: form-data; name="file"; filename="dummy.txt"\r\nContent-Type: text\/plain\r\n\r\ndummy content\n\r\n/, done); // eslint-disable-line max-len155 });156 it('HEAD with redirect should be followed', function(done) {157 // Redirects are automatically followed, because redirects are to be158 // followed automatically per specification regardless of the HTTP verb.159 request(cors_anywhere)160 .head('/example.com/redirect')161 .redirects(0)162 .expect('Access-Control-Allow-Origin', '*')163 .expect('some-header', 'value')164 .expect('x-request-url', 'http://example.com/redirect')165 .expect('x-cors-redirect-1', '302 http://example.com/redirecttarget')166 .expect('x-final-url', 'http://example.com/redirecttarget')167 .expect('access-control-expose-headers', /some-header,x-final-url/)168 .expectNoHeader('header at redirect')169 .expect(200, undefined, done);170 });171 it('GET with redirect should be followed', function(done) {172 request(cors_anywhere)173 .get('/example.com/redirect')174 .redirects(0)175 .expect('Access-Control-Allow-Origin', '*')176 .expect('some-header', 'value')177 .expect('x-request-url', 'http://example.com/redirect')178 .expect('x-cors-redirect-1', '302 http://example.com/redirecttarget')179 .expect('x-final-url', 'http://example.com/redirecttarget')180 .expect('access-control-expose-headers', /some-header,x-final-url/)181 .expectNoHeader('header at redirect')182 .expect(200, 'redirect target', done);183 });184 it('GET with redirect loop should interrupt', function(done) {185 request(cors_anywhere)186 .get('/example.com/redirectloop')187 .redirects(0)188 .expect('Access-Control-Allow-Origin', '*')189 .expect('x-request-url', 'http://example.com/redirectloop')190 .expect('x-cors-redirect-1', '302 http://example.com/redirectloop')191 .expect('x-cors-redirect-2', '302 http://example.com/redirectloop')192 .expect('x-cors-redirect-3', '302 http://example.com/redirectloop')193 .expect('x-cors-redirect-4', '302 http://example.com/redirectloop')194 .expect('x-cors-redirect-5', '302 http://example.com/redirectloop')195 .expect('Location', /^http:\/\/127.0.0.1:\d+\/http:\/\/example.com\/redirectloop$/)196 .expect(302, 'redirecting ad infinitum...', done);197 });198 it('POST with 302 redirect should be followed', function(done) {199 request(cors_anywhere)200 .post('/example.com/redirectpost')201 .redirects(0)202 .expect('Access-Control-Allow-Origin', '*')203 .expect('x-request-url', 'http://example.com/redirectpost')204 .expect('x-cors-redirect-1', '302 http://example.com/redirectposttarget')205 .expect('x-final-url', 'http://example.com/redirectposttarget')206 .expect('access-control-expose-headers', /x-final-url/)207 .expect(200, 'post target', done);208 });209 it('GET with 302 redirect without Location header should not be followed', function(done) {210 // There is nothing to follow, so let the browser decide what to do with it.211 request(cors_anywhere)212 .get('/example.com/redirectwithoutlocation')213 .redirects(0)214 .expect('Access-Control-Allow-Origin', '*')215 .expect('x-request-url', 'http://example.com/redirectwithoutlocation')216 .expect('x-final-url', 'http://example.com/redirectwithoutlocation')217 .expect('access-control-expose-headers', /x-final-url/)218 .expect(302, 'maybe found', done);219 });220 it('GET with 302 redirect to an invalid Location should not be followed', function(done) {221 // There is nothing to follow, so let the browser decide what to do with it.222 request(cors_anywhere)223 .get('/example.com/redirectinvalidlocation')224 .redirects(0)225 .expect('Access-Control-Allow-Origin', '*')226 .expect('x-request-url', 'http://example.com/redirectinvalidlocation')227 .expect('x-final-url', 'http://example.com/redirectinvalidlocation')228 .expect('access-control-expose-headers', /x-final-url/)229 .expect('Location', 'http:///')230 .expect(302, 'redirecting to junk...', done);231 });232 it('POST with 307 redirect should not be handled', function(done) {233 // Because of implementation difficulties (having to keep the request body234 // in memory), handling HTTP 307/308 redirects is deferred to the requestor.235 request(cors_anywhere)236 .post('/example.com/redirect307')237 .redirects(0)238 .expect('Access-Control-Allow-Origin', '*')239 .expect('x-request-url', 'http://example.com/redirect307')240 .expect('Location', /^http:\/\/127.0.0.1:\d+\/http:\/\/example.com\/redirectposttarget$/)241 .expect('x-final-url', 'http://example.com/redirect307')242 .expect('access-control-expose-headers', /x-final-url/)243 .expect(307, 'redirecting...', done);244 });245 it('OPTIONS /', function(done) {246 request(cors_anywhere)247 .options('/')248 .expect('Access-Control-Allow-Origin', '*')249 .expect(200, '', done);250 });251 it('OPTIONS / with Access-Control-Request-Method / -Headers', function(done) {252 request(cors_anywhere)253 .options('/')254 .set('Access-Control-Request-Method', 'DELETE')255 .set('Access-Control-Request-Headers', 'X-Tralala')256 .expect('Access-Control-Allow-Origin', '*')257 .expect('Access-Control-Allow-Methods', 'DELETE')258 .expect('Access-Control-Allow-Headers', 'X-Tralala')259 .expect(200, '', done);260 });261 it('OPTIONS //bogus', function(done) {262 // The preflight request always succeeds, regardless of whether the request263 // is valid.264 request(cors_anywhere)265 .options('//bogus')266 .expect('Access-Control-Allow-Origin', '*')267 .expect(200, '', done);268 });269 it('X-Forwarded-* headers', function(done) {270 request(cors_anywhere)271 .get('/example.com/echoheaders')272 .set('test-include-xfwd', '')273 .expect('Access-Control-Allow-Origin', '*')274 .expectJSON({275 host: 'example.com',276 'x-forwarded-port': String(cors_anywhere_port),277 'x-forwarded-proto': 'http',278 }, done);279 });280 it('X-Forwarded-* headers (non-standard port)', function(done) {281 request(cors_anywhere)282 .get('/example.com:1337/echoheaders')283 .set('test-include-xfwd', '')284 .expect('Access-Control-Allow-Origin', '*')285 .expectJSON({286 host: 'example.com:1337',287 'x-forwarded-port': String(cors_anywhere_port),288 'x-forwarded-proto': 'http',289 }, done);290 });291 it('X-Forwarded-* headers (https)', function(done) {292 request(cors_anywhere)293 .get('/https://example.com/echoheaders')294 .set('test-include-xfwd', '')295 .expect('Access-Control-Allow-Origin', '*')296 .expectJSON({297 host: 'example.com',298 'x-forwarded-port': String(cors_anywhere_port),299 'x-forwarded-proto': 'http',300 }, done);301 });302 it('Ignore cookies', function(done) {303 request(cors_anywhere)304 .get('/example.com/setcookie')305 .expect('Access-Control-Allow-Origin', '*')306 .expect('Set-Cookie3', 'z')307 .expectNoHeader('set-cookie')308 .expectNoHeader('set-cookie2', done);309 });310});311describe('Proxy errors', function() {312 before(function() {313 cors_anywhere = createServer();314 cors_anywhere_port = cors_anywhere.listen(0).address().port;315 });316 after(stopServer);317 var bad_http_server;318 var bad_http_server_url;319 before(function() {320 bad_http_server = http.createServer(function(req, res) {321 res.writeHead(418, {322 'Content-Length': 'Not a digit',323 });324 res.end('This response has an invalid Content-Length header.');325 });326 bad_http_server_url = 'http://127.0.0.1:' + bad_http_server.listen(0).address().port;327 });328 after(function(done) {329 bad_http_server.close(function() {330 done();331 });332 });333 var bad_status_http_server;334 var bad_status_http_server_url;335 before(function() {336 bad_status_http_server = require('net').createServer(function(socket) {337 socket.setEncoding('utf-8');338 socket.on('data', function(data) {339 if (data.indexOf('\r\n') >= 0) {340 // Assume end of headers.341 socket.write('HTTP/1.0 0\r\n');342 socket.write('Content-Length: 0\r\n');343 socket.end('\r\n');344 }345 });346 });347 bad_status_http_server_url = 'http://127.0.0.1:' + bad_status_http_server.listen(0).address().port;348 });349 after(function(done) {350 bad_status_http_server.close(function() {351 done();352 });353 });354 var bad_tcp_server;355 var bad_tcp_server_url;356 before(function() {357 bad_tcp_server = require('net').createServer(function(socket) {358 socket.setEncoding('utf-8');359 socket.on('data', function(data) {360 if (data.indexOf('\r\n') >= 0) {361 // Assume end of headers.362 socket.write('HTTP/1.1 418 OK\r\n');363 socket.write('Transfer-Encoding: chunked\r\n');364 socket.write('\r\n');365 socket.end('JK I lied, this is NOT a chunked response!');366 }367 });368 });369 bad_tcp_server_url = 'http://127.0.0.1:' + bad_tcp_server.listen(0).address().port;370 });371 after(function(done) {372 bad_tcp_server.close(function() {373 done();374 });375 });376 it('Proxy error', function(done) {377 request(cors_anywhere)378 .get('/example.com/proxyerror')379 .expect('Access-Control-Allow-Origin', '*')380 .expect(404, 'Not found because of proxy error: Error: throw node', done);381 });382 it('Content-Length mismatch', function(done) {383 var errorMessage = 'Error: Parse Error: Invalid character in Content-Length';384 // <13.0.0: https://github.com/nodejs/node/commit/ba565a37349e81c9d2402b0c8ef05ab39dca8968385 // <12.7.0: https://github.com/nodejs/node/pull/28817386 var nodev = process.versions.node.split('.').map(function(v) { return parseInt(v); });387 if (nodev[0] < 12 ||388 nodev[0] === 12 && nodev[1] < 7) {389 errorMessage = 'Error: Parse Error';390 }391 request(cors_anywhere)392 .get('/' + bad_http_server_url)393 .expect('Access-Control-Allow-Origin', '*')394 .expect(404, 'Not found because of proxy error: ' + errorMessage, done);395 });396 it('Invalid HTTP status code', function(done) {397 // Strict HTTP status validation was introduced in Node 4.5.5+, 5.11.0+.398 // https://github.com/nodejs/node/pull/6291399 var nodev = process.versions.node.split('.').map(function(v) { return parseInt(v); });400 if (nodev[0] < 4 ||401 nodev[0] === 4 && nodev[1] < 5 ||402 nodev[0] === 4 && nodev[1] === 5 && nodev[2] < 5 ||403 nodev[0] === 5 && nodev[1] < 11) {404 this.skip();405 }406 var errorMessage = 'RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: 0';407 if (parseInt(process.versions.node, 10) < 9) {408 errorMessage = 'RangeError: Invalid status code: 0';409 }410 request(cors_anywhere)411 .get('/' + bad_status_http_server_url)412 .expect('Access-Control-Allow-Origin', '*')413 .expect(404, 'Not found because of proxy error: ' + errorMessage, done);414 });415 it('Content-Encoding invalid body', function(done) {416 // The HTTP status can't be changed because the headers have already been417 // sent.418 request(cors_anywhere)419 .get('/' + bad_tcp_server_url)420 .expect('Access-Control-Allow-Origin', '*')421 .expect(418, '', done);422 });423 it('Invalid header values', function(done) {424 if (parseInt(process.versions.node, 10) < 6) {425 // >=6.0.0: https://github.com/nodejs/node/commit/7bef1b790727430cb82bf8be80cfe058480de100426 this.skip();427 }428 // >=9.0.0: https://github.com/nodejs/node/commit/11a2ca29babcb35132e7d93244b69c544d52dfe4429 var errorMessage = 'TypeError [ERR_INVALID_CHAR]: Invalid character in header content ["headername"]';430 if (parseInt(process.versions.node, 10) < 9) {431 // >=6.0.0, <9.0.0: https://github.com/nodejs/node/commit/7bef1b790727430cb82bf8be80cfe058480de100432 errorMessage = 'TypeError: The header content contains invalid characters';433 }434 stopServer(function() {435 cors_anywhere = createServer({436 // Setting an invalid header below in request(...).set(...) would trigger437 // a header validation error in superagent. So we use setHeaders to test438 // the attempt to proxy a request with invalid request headers.439 setHeaders: {headername: 'invalid\x01value'},440 });441 cors_anywhere_port = cors_anywhere.listen(0).address().port;442 request(cors_anywhere)443 .get('/' + bad_tcp_server_url) // Any URL that isn't intercepted by Nock would do.444 .expect('Access-Control-Allow-Origin', '*')445 .expect(404, 'Not found because of proxy error: ' + errorMessage, done);446 });447 });448});449describe('server on https', function() {450 var NODE_TLS_REJECT_UNAUTHORIZED;451 before(function() {452 cors_anywhere = createServer({453 httpsOptions: {454 key: fs.readFileSync(path.join(__dirname, 'key.pem')),455 cert: fs.readFileSync(path.join(__dirname, 'cert.pem')),456 },457 });458 cors_anywhere_port = cors_anywhere.listen(0).address().port;459 // Disable certificate validation in case the certificate expires.460 NODE_TLS_REJECT_UNAUTHORIZED = process.env.NODE_TLS_REJECT_UNAUTHORIZED;461 process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';462 });463 after(function(done) {464 if (NODE_TLS_REJECT_UNAUTHORIZED === undefined) {465 delete process.env.NODE_TLS_REJECT_UNAUTHORIZED;466 } else {467 process.env.NODE_TLS_REJECT_UNAUTHORIZED = NODE_TLS_REJECT_UNAUTHORIZED;468 }469 stopServer(done);470 });471 it('X-Forwarded-* headers (http)', function(done) {472 request(cors_anywhere)473 .get('/example.com/echoheaders')474 .set('test-include-xfwd', '')475 .expect('Access-Control-Allow-Origin', '*')476 .expectJSON({477 host: 'example.com',478 'x-forwarded-port': String(cors_anywhere_port),479 'x-forwarded-proto': 'https',480 }, done);481 });482 it('X-Forwarded-* headers (https)', function(done) {483 request(cors_anywhere)484 .get('/https://example.com/echoheaders')485 .set('test-include-xfwd', '')486 .expect('Access-Control-Allow-Origin', '*')487 .expectJSON({488 host: 'example.com',489 'x-forwarded-port': String(cors_anywhere_port),490 'x-forwarded-proto': 'https',491 }, done);492 });493 it('X-Forwarded-* headers (https, non-standard port)', function(done) {494 request(cors_anywhere)495 .get('/https://example.com:1337/echoheaders')496 .set('test-include-xfwd', '')497 .expect('Access-Control-Allow-Origin', '*')498 .expectJSON({499 host: 'example.com:1337',500 'x-forwarded-port': String(cors_anywhere_port),501 'x-forwarded-proto': 'https',502 }, done);503 });504});505describe('NODE_TLS_REJECT_UNAUTHORIZED', function() {506 var NODE_TLS_REJECT_UNAUTHORIZED;507 var bad_https_server;508 var bad_https_server_port;509 var certErrorMessage = 'Error: certificate has expired';510 // <0.11.11: https://github.com/nodejs/node/commit/262a752c2943842df7babdf55a034beca68794cd511 if (/^0\.(?!11\.1[1-4]|12\.)/.test(process.versions.node)) {512 certErrorMessage = 'Error: CERT_HAS_EXPIRED';513 }514 before(function() {515 cors_anywhere = createServer({});516 cors_anywhere_port = cors_anywhere.listen(0).address().port;517 });518 after(function(done) {519 stopServer(done);520 });521 before(function() {522 bad_https_server = https.createServer({523 // rejectUnauthorized: false,524 key: fs.readFileSync(path.join(__dirname, 'key.pem')),525 cert: fs.readFileSync(path.join(__dirname, 'cert.pem')),526 }, function(req, res) {527 res.end('Response from server with expired cert');528 });529 bad_https_server_port = bad_https_server.listen(0).address().port;530 NODE_TLS_REJECT_UNAUTHORIZED = process.env.NODE_TLS_REJECT_UNAUTHORIZED;531 });532 after(function(done) {533 if (NODE_TLS_REJECT_UNAUTHORIZED === undefined) {534 delete process.env.NODE_TLS_REJECT_UNAUTHORIZED;535 } else {536 process.env.NODE_TLS_REJECT_UNAUTHORIZED = NODE_TLS_REJECT_UNAUTHORIZED;537 }538 bad_https_server.close(function() {539 done();540 });541 });542 it('respects certificate errors by default', function(done) {543 // Test is expected to run without NODE_TLS_REJECT_UNAUTHORIZED=0544 request(cors_anywhere)545 .get('/https://127.0.0.1:' + bad_https_server_port)546 .set('test-include-xfwd', '')547 .expect('Access-Control-Allow-Origin', '*')548 .expect('Not found because of proxy error: ' + certErrorMessage, done);549 });550 it('ignore certificate errors via NODE_TLS_REJECT_UNAUTHORIZED=0', function(done) {551 stopServer(function() {552 process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';553 cors_anywhere = createServer({});554 cors_anywhere_port = cors_anywhere.listen(0).address().port;555 request(cors_anywhere)556 .get('/https://127.0.0.1:' + bad_https_server_port)557 .set('test-include-xfwd', '')558 .expect('Access-Control-Allow-Origin', '*')559 .expect('Response from server with expired cert', done);560 });561 });562 it('respects certificate errors when httpProxyOptions.secure=true', function(done) {563 stopServer(function() {564 cors_anywhere = createServer({565 httpProxyOptions: {566 secure: true,567 },568 });569 cors_anywhere_port = cors_anywhere.listen(0).address().port;570 request(cors_anywhere)571 .get('/https://127.0.0.1:' + bad_https_server_port)572 .set('test-include-xfwd', '')573 .expect('Access-Control-Allow-Origin', '*')574 .expect('Not found because of proxy error: ' + certErrorMessage, done);575 });576 });577});578describe('originBlacklist', function() {579 before(function() {580 cors_anywhere = createServer({581 originBlacklist: ['http://denied.origin.test'],582 });583 cors_anywhere_port = cors_anywhere.listen(0).address().port;584 });585 after(stopServer);586 it('GET /example.com with denied origin', function(done) {587 request(cors_anywhere)588 .get('/example.com/')589 .set('Origin', 'http://denied.origin.test')590 .expect('Access-Control-Allow-Origin', '*')591 .expect(403, done);592 });593 it('GET /example.com without denied origin', function(done) {594 request(cors_anywhere)595 .get('/example.com/')596 .set('Origin', 'https://denied.origin.test') // Note: different scheme!597 .expect('Access-Control-Allow-Origin', '*')598 .expect(200, done);599 });600 it('GET /example.com without origin', function(done) {601 request(cors_anywhere)602 .get('/example.com/')603 .expect('Access-Control-Allow-Origin', '*')604 .expect(200, done);605 });606});607describe('originWhitelist', function() {608 before(function() {609 cors_anywhere = createServer({610 originWhitelist: ['https://permitted.origin.test'],611 });612 cors_anywhere_port = cors_anywhere.listen(0).address().port;613 });614 after(stopServer);615 it('GET /example.com with permitted origin', function(done) {616 request(cors_anywhere)617 .get('/example.com/')618 .set('Origin', 'https://permitted.origin.test')619 .expect('Access-Control-Allow-Origin', '*')620 .expect(200, done);621 });622 it('GET /example.com without permitted origin', function(done) {623 request(cors_anywhere)624 .get('/example.com/')625 .set('Origin', 'http://permitted.origin.test') // Note: different scheme!626 .expect('Access-Control-Allow-Origin', '*')627 .expect(403, done);628 });629 it('GET /example.com without origin', function(done) {630 request(cors_anywhere)631 .get('/example.com/')632 .expect('Access-Control-Allow-Origin', '*')633 .expect(403, done);634 });635});636describe('handleInitialRequest', function() {637 afterEach(stopServer);638 it('GET / with handleInitialRequest', function(done) {639 cors_anywhere = createServer({640 handleInitialRequest: function(req, res, location) {641 res.writeHead(419);642 res.end('res:' + (location && location.href));643 return true;644 },645 });646 cors_anywhere_port = cors_anywhere.listen(0).address().port;647 request(cors_anywhere)648 .get('/')649 .expect(419, 'res:null', done);650 });651 it('GET /dummy with handleInitialRequest', function(done) {652 cors_anywhere = createServer({653 handleInitialRequest: function(req, res, location) {654 res.writeHead(419);655 res.end('res:' + (location && location.href));656 return true;657 },658 });659 cors_anywhere_port = cors_anywhere.listen(0).address().port;660 request(cors_anywhere)661 .get('/dummy')662 .expect(419, 'res:http://dummy/', done);663 });664 it('GET /example.com with handleInitialRequest', function(done) {665 cors_anywhere = createServer({666 handleInitialRequest: function(req, res, location) {667 res.setHeader('X-Extra-Header', 'hello ' + location.href);668 },669 });670 cors_anywhere_port = cors_anywhere.listen(0).address().port;671 request(cors_anywhere)672 .get('/example.com')673 .set('Origin', 'null')674 .expect('Access-Control-Allow-Origin', '*')675 .expect('X-Extra-Header', 'hello http://example.com/')676 .expect(200, 'Response from example.com', done);677 });678});679describe('checkRateLimit', function() {680 afterEach(stopServer);681 it('GET /example.com without rate-limit', function(done) {682 cors_anywhere = createServer({683 checkRateLimit: function() {},684 });685 cors_anywhere_port = cors_anywhere.listen(0).address().port;686 request(cors_anywhere)687 .get('/example.com/')688 .expect('Access-Control-Allow-Origin', '*')689 .expect(200, done);690 });691 it('GET /example.com with rate-limit', function(done) {692 cors_anywhere = createServer({693 checkRateLimit: function(origin) {694 // Non-empty value. Let's return the origin parameter so that we also verify that the695 // the parameter is really the origin.696 return '[' + origin + ']';697 },698 });699 cors_anywhere_port = cors_anywhere.listen(0).address().port;700 request(cors_anywhere)701 .get('/example.com/')702 .set('Origin', 'http://example.net:1234')703 .expect('Access-Control-Allow-Origin', '*')704 .expect(429, done,705 'The origin "http://example.net" has sent too many requests.\n[http://example.com:1234]');706 });707});708describe('redirectSameOrigin', function() {709 before(function() {710 cors_anywhere = createServer({711 redirectSameOrigin: true,712 });713 cors_anywhere_port = cors_anywhere.listen(0).address().port;714 });715 after(stopServer);716 it('GET /example.com with Origin: http://example.com', function(done) {717 request(cors_anywhere)718 .get('/example.com/')719 .set('Origin', 'http://example.com')720 .expect('Access-Control-Allow-Origin', '*')721 .expect('Cache-Control', 'private')722 .expect('Vary', 'origin')723 .expect('Location', 'http://example.com/')724 .expect(301, done);725 });726 it('GET /example.com with Origin: https://example.com', function(done) {727 // Not same-origin because of different schemes.728 request(cors_anywhere)729 .get('/example.com/')730 .set('Origin', 'https://example.com')731 .expect('Access-Control-Allow-Origin', '*')732 .expect(200, 'Response from example.com', done);733 });734 it('GET /example.com with Origin: http://example.com:1234', function(done) {735 // Not same-origin because of different ports.736 request(cors_anywhere)737 .get('/example.com/')738 .set('Origin', 'http://example.com:1234')739 .expect('Access-Control-Allow-Origin', '*')740 .expect(200, 'Response from example.com', done);741 });742 it('GET /example.com:1234 with Origin: http://example.com', function(done) {743 // Not same-origin because of different ports.744 request(cors_anywhere)745 .get('/example.com:1234/')746 .set('Origin', 'http://example.com')747 .expect('Access-Control-Allow-Origin', '*')748 .expect(200, 'Response from example.com:1234', done);749 });750 it('GET /example.com with Origin: http://example.com.test', function(done) {751 // Not same-origin because of different host names.752 request(cors_anywhere)753 .get('/example.com/')754 .set('Origin', 'http://example.com.test')755 .expect('Access-Control-Allow-Origin', '*')756 .expect(200, 'Response from example.com', done);757 });758 it('GET /example.com.com with Origin: http://example.com', function(done) {759 // Not same-origin because of different host names.760 request(cors_anywhere)761 .get('/example.com.com/')762 .set('Origin', 'http://example.com')763 .expect('Access-Control-Allow-Origin', '*')764 .expect(200, 'Response from example.com.com', done);765 });766 it('GET /prefix.example.com with Origin: http://example.com', function(done) {767 // Not same-origin because of different host names.768 request(cors_anywhere)769 .get('/prefix.example.com/')770 .set('Origin', 'http://example.com')771 .expect('Access-Control-Allow-Origin', '*')772 .expect(200, 'Response from prefix.example.com', done);773 });774});775describe('requireHeader', function() {776 before(function() {777 cors_anywhere = createServer({778 requireHeader: ['origin', 'x-requested-with'],779 });780 cors_anywhere_port = cors_anywhere.listen(0).address().port;781 });782 after(stopServer);783 it('GET /example.com without header', function(done) {784 request(cors_anywhere)785 .get('/example.com/')786 .expect('Access-Control-Allow-Origin', '*')787 .expect(400, 'Missing required request header. Must specify one of: origin,x-requested-with', done);788 });789 it('GET /example.com with X-Requested-With header', function(done) {790 request(cors_anywhere)791 .get('/example.com/')792 .set('X-Requested-With', '')793 .expect('Access-Control-Allow-Origin', '*')794 .expect(200, done);795 });796 it('GET /example.com with Origin header', function(done) {797 request(cors_anywhere)798 .get('/example.com/')799 .set('Origin', 'null')800 .expect('Access-Control-Allow-Origin', '*')801 .expect(200, done);802 });803 it('GET /example.com without header (requireHeader as string)', function(done) {804 stopServer(function() {805 cors_anywhere = createServer({806 requireHeader: 'origin',807 });808 cors_anywhere_port = cors_anywhere.listen(0).address().port;809 request(cors_anywhere)810 .get('/example.com/')811 .expect('Access-Control-Allow-Origin', '*')812 .expect(400, 'Missing required request header. Must specify one of: origin', done);813 });814 });815 it('GET /example.com with header (requireHeader as string)', function(done) {816 stopServer(function() {817 cors_anywhere = createServer({818 requireHeader: 'origin',819 });820 cors_anywhere_port = cors_anywhere.listen(0).address().port;821 request(cors_anywhere)822 .get('/example.com/')823 .set('Origin', 'null')824 .expect('Access-Control-Allow-Origin', '*')825 .expect(200, 'Response from example.com', done);826 });827 });828 it('GET /example.com without header (requireHeader as string, uppercase)', function(done) {829 stopServer(function() {830 cors_anywhere = createServer({831 requireHeader: 'ORIGIN',832 });833 cors_anywhere_port = cors_anywhere.listen(0).address().port;834 request(cors_anywhere)835 .get('/example.com/')836 .expect('Access-Control-Allow-Origin', '*')837 .expect(400, 'Missing required request header. Must specify one of: origin', done);838 });839 });840 it('GET /example.com with header (requireHeader as string, uppercase)', function(done) {841 stopServer(function() {842 cors_anywhere = createServer({843 requireHeader: 'ORIGIN',844 });845 cors_anywhere_port = cors_anywhere.listen(0).address().port;846 request(cors_anywhere)847 .get('/example.com/')848 .set('Origin', 'null')849 .expect('Access-Control-Allow-Origin', '*')850 .expect(200, 'Response from example.com', done);851 });852 });853 it('GET /example.com (requireHeader is an empty array)', function(done) {854 stopServer(function() {855 cors_anywhere = createServer({856 requireHeader: [],857 });858 cors_anywhere_port = cors_anywhere.listen(0).address().port;859 request(cors_anywhere)860 .get('/example.com/')861 .expect('Access-Control-Allow-Origin', '*')862 .expect(200, 'Response from example.com', done);863 });864 });865});866describe('removeHeaders', function() {867 before(function() {868 cors_anywhere = createServer({869 removeHeaders: ['cookie', 'cookie2'],870 });871 cors_anywhere_port = cors_anywhere.listen(0).address().port;872 });873 after(stopServer);874 it('GET /example.com with request cookie', function(done) {875 request(cors_anywhere)876 .get('/example.com/echoheaders')877 .set('cookie', 'a')878 .set('cookie2', 'b')879 .expect('Access-Control-Allow-Origin', '*')880 .expectJSON({881 host: 'example.com',882 }, done);883 });884 it('GET /example.com with unknown header', function(done) {885 request(cors_anywhere)886 .get('/example.com/echoheaders')887 .set('cookie', 'a')888 .set('cookie2', 'b')889 .set('cookie3', 'c')890 .expect('Access-Control-Allow-Origin', '*')891 .expectJSON({892 host: 'example.com',893 cookie3: 'c',894 }, done);895 });896});897describe('setHeaders', function() {898 before(function() {899 cors_anywhere = createServer({900 setHeaders: {'x-powered-by': 'CORS Anywhere'},901 });902 cors_anywhere_port = cors_anywhere.listen(0).address().port;903 });904 after(stopServer);905 it('GET /example.com', function(done) {906 request(cors_anywhere)907 .get('/example.com/echoheaders')908 .expect('Access-Control-Allow-Origin', '*')909 .expectJSON({910 host: 'example.com',911 'x-powered-by': 'CORS Anywhere',912 }, done);913 });914 it('GET /example.com should replace header', function(done) {915 request(cors_anywhere)916 .get('/example.com/echoheaders')917 .set('x-powered-by', 'should be replaced')918 .expect('Access-Control-Allow-Origin', '*')919 .expectJSON({920 host: 'example.com',921 'x-powered-by': 'CORS Anywhere',922 }, done);923 });924});925describe('setHeaders + removeHeaders', function() {926 before(function() {927 // setHeaders takes precedence over removeHeaders928 cors_anywhere = createServer({929 removeHeaders: ['x-powered-by'],930 setHeaders: {'x-powered-by': 'CORS Anywhere'},931 });932 cors_anywhere_port = cors_anywhere.listen(0).address().port;933 });934 after(stopServer);935 it('GET /example.com', function(done) {936 request(cors_anywhere)937 .get('/example.com/echoheaders')938 .expect('Access-Control-Allow-Origin', '*')939 .expectJSON({940 host: 'example.com',941 'x-powered-by': 'CORS Anywhere',942 }, done);943 });944 it('GET /example.com should replace header', function(done) {945 request(cors_anywhere)946 .get('/example.com/echoheaders')947 .set('x-powered-by', 'should be replaced')948 .expect('Access-Control-Allow-Origin', '*')949 .expectJSON({950 host: 'example.com',951 'x-powered-by': 'CORS Anywhere',952 }, done);953 });954});955describe('Access-Control-Max-Age set', function() {956 before(function() {957 cors_anywhere = createServer({958 corsMaxAge: 600,959 });960 cors_anywhere_port = cors_anywhere.listen(0).address().port;961 });962 after(stopServer);963 it('OPTIONS /', function(done) {964 request(cors_anywhere)965 .options('/')966 .expect('Access-Control-Allow-Origin', '*')967 .expect('Access-Control-Max-Age', '600')968 .expect(200, '', done);969 });970 it('OPTIONS /example.com', function(done) {971 request(cors_anywhere)972 .options('/example.com')973 .expect('Access-Control-Allow-Origin', '*')974 .expect('Access-Control-Max-Age', '600')975 .expect(200, '', done);976 });977 it('GET / no Access-Control-Max-Age on GET', function(done) {978 request(cors_anywhere)979 .get('/')980 .type('text/plain')981 .expect('Access-Control-Allow-Origin', '*')982 .expectNoHeader('Access-Control-Max-Age')983 .expect(200, helpText, done);984 });985 it('GET /example.com no Access-Control-Max-Age on GET', function(done) {986 request(cors_anywhere)987 .get('/example.com')988 .expect('Access-Control-Allow-Origin', '*')989 .expectNoHeader('Access-Control-Max-Age')990 .expect(200, 'Response from example.com', done);991 });992});993describe('Access-Control-Max-Age not set', function() {994 before(function() {995 cors_anywhere = createServer();996 cors_anywhere_port = cors_anywhere.listen(0).address().port;997 });998 after(stopServer);999 it('OPTIONS / corsMaxAge disabled', function(done) {1000 request(cors_anywhere)1001 .options('/')1002 .expect('Access-Control-Allow-Origin', '*')1003 .expectNoHeader('Access-Control-Max-Age')1004 .expect(200, '', done);1005 });1006 it('OPTIONS /example.com corsMaxAge disabled', function(done) {1007 request(cors_anywhere)1008 .options('/example.com')1009 .expect('Access-Control-Allow-Origin', '*')1010 .expectNoHeader('Access-Control-Max-Age')1011 .expect(200, '', done);1012 });1013 it('GET /', function(done) {1014 request(cors_anywhere)1015 .get('/')1016 .type('text/plain')1017 .expect('Access-Control-Allow-Origin', '*')1018 .expectNoHeader('Access-Control-Max-Age')1019 .expect(200, helpText, done);1020 });1021 it('GET /example.com', function(done) {1022 request(cors_anywhere)1023 .get('/example.com')1024 .expect('Access-Control-Allow-Origin', '*')1025 .expectNoHeader('Access-Control-Max-Age')1026 .expect(200, 'Response from example.com', done);1027 });1028});1029describe('httpProxyOptions.xfwd=false', function() {1030 before(function() {1031 cors_anywhere = createServer({1032 httpProxyOptions: {1033 xfwd: false,1034 },1035 });1036 cors_anywhere_port = cors_anywhere.listen(0).address().port;1037 });1038 after(stopServer);1039 it('X-Forwarded-* headers should not be set', function(done) {1040 request(cors_anywhere)1041 .get('/example.com/echoheaders')1042 .set('test-include-xfwd', '')1043 .expect('Access-Control-Allow-Origin', '*')1044 .expectJSON({1045 host: 'example.com',1046 }, done);1047 });1048});1049describe('httpProxyOptions.getProxyForUrl', function() {1050 var proxy_server;1051 var proxy_url;1052 before(function() {1053 // Using a real server instead of a mock because Nock doesn't can't mock proxies.1054 proxy_server = http.createServer(function(req, res) {1055 res.end(req.method + ' ' + req.url + ' Host=' + req.headers.host);1056 });1057 proxy_url = 'http://127.0.0.1:' + proxy_server.listen(0).address().port;1058 cors_anywhere = createServer({1059 httpProxyOptions: {1060 xfwd: false,1061 },1062 });1063 cors_anywhere_port = cors_anywhere.listen(0).address().port;1064 });1065 afterEach(function() {1066 // Assuming that they were not set before.1067 delete process.env.https_proxy;1068 delete process.env.http_proxy;1069 delete process.env.no_proxy;1070 });1071 after(function(done) {1072 proxy_server.close(function() {1073 done();1074 });1075 });1076 after(stopServer);1077 it('http_proxy should be respected for matching domains', function(done) {1078 process.env.http_proxy = proxy_url;1079 request(cors_anywhere)1080 .get('/http://example.com')1081 .expect('Access-Control-Allow-Origin', '*')1082 .expect(200, 'GET http://example.com/ Host=example.com', done);1083 });1084 it('http_proxy should be ignored for http URLs', function(done) {1085 process.env.http_proxy = proxy_url;1086 request(cors_anywhere)1087 .get('/https://example.com')1088 .expect('Access-Control-Allow-Origin', '*')1089 .expect(200, 'Response from https://example.com', done);1090 });1091 it('https_proxy should be respected for matching domains', function(done) {1092 process.env.https_proxy = proxy_url;1093 request(cors_anywhere)1094 .get('/https://example.com')1095 .expect('Access-Control-Allow-Origin', '*')1096 .expect(200, 'GET https://example.com/ Host=example.com', done);1097 });1098 it('https_proxy should be ignored for http URLs', function(done) {1099 process.env.https_proxy = proxy_url;1100 request(cors_anywhere)1101 .get('/http://example.com')1102 .expect('Access-Control-Allow-Origin', '*')1103 .expect(200, 'Response from example.com', done);1104 });1105 it('https_proxy + no_proxy should not intercept requests in no_proxy', function(done) {1106 process.env.https_proxy = proxy_url;1107 process.env.no_proxy = 'example.com:443';1108 request(cors_anywhere)1109 .get('/https://example.com')1110 .expect('Access-Control-Allow-Origin', '*')1111 .expect(200, 'Response from https://example.com', done);1112 });1113});1114describe('helpFile', function() {1115 afterEach(stopServer);1116 it('GET / with custom text helpFile', function(done) {1117 var customHelpTextPath = path.join(__dirname, './customHelp.txt');1118 var customHelpText = fs.readFileSync(customHelpTextPath, {encoding: 'utf8'});1119 cors_anywhere = createServer({1120 helpFile: customHelpTextPath,1121 });1122 cors_anywhere_port = cors_anywhere.listen(0).address().port;1123 request(cors_anywhere)1124 .get('/')1125 .type('text/plain')1126 .expect('Access-Control-Allow-Origin', '*')1127 .expect(200, customHelpText, done);1128 });1129 it('GET / with custom HTML helpFile', function(done) {1130 var customHelpTextPath = path.join(__dirname, './customHelp.html');1131 var customHelpText = fs.readFileSync(customHelpTextPath, {encoding: 'utf8'});1132 cors_anywhere = createServer({1133 helpFile: customHelpTextPath,1134 });1135 cors_anywhere_port = cors_anywhere.listen(0).address().port;1136 request(cors_anywhere)1137 .get('/')1138 .type('text/html')1139 .expect('Access-Control-Allow-Origin', '*')1140 .expect(200, customHelpText, done);1141 });1142 it('GET / with non-existent help file', function(done) {1143 var customHelpTextPath = path.join(__dirname, 'Some non-existing file.');1144 cors_anywhere = createServer({1145 helpFile: customHelpTextPath,1146 });1147 cors_anywhere_port = cors_anywhere.listen(0).address().port;1148 request(cors_anywhere)1149 .get('/')1150 .type('text/plain')1151 .expect('Access-Control-Allow-Origin', '*')1152 .expect(500, '', done);1153 });...
cors-anywhere.js
Source:cors-anywhere.js
1// © 2013 - 2016 Rob Wu <rob@robwu.nl>2// Released under the MIT license3'use strict';4var httpProxy = require('http-proxy');5var net = require('net');6var url = require('url');7var regexp_tld = require('./regexp-top-level-domain');8var getProxyForUrl = require('proxy-from-env').getProxyForUrl;9var help_text = {};10function showUsage(help_file, headers, response) {11 var isHtml = /\.html$/.test(help_file);12 headers['content-type'] = isHtml ? 'text/html' : 'text/plain';13 if (help_text[help_file] != null) {14 response.writeHead(200, headers);15 response.end(help_text[help_file]);16 } else {17 require('fs').readFile(help_file, 'utf8', function(err, data) {18 if (err) {19 console.error(err);20 response.writeHead(500, headers);21 response.end();22 } else {23 help_text[help_file] = data;24 showUsage(help_file, headers, response); // Recursive call, but since data is a string, the recursion will end25 }26 });27 }28}29/**30 * Check whether the specified hostname is valid.31 *32 * @param hostname {string} Host name (excluding port) of requested resource.33 * @return {boolean} Whether the requested resource can be accessed.34 */35function isValidHostName(hostname) {36 return !!(37 regexp_tld.test(hostname) ||38 net.isIPv4(hostname) ||39 net.isIPv6(hostname)40 );41}42/**43 * Adds CORS headers to the response headers.44 *45 * @param headers {object} Response headers46 * @param request {ServerRequest}47 */48function withCORS(headers, request) {49 headers['access-control-allow-origin'] = '*';50 var corsMaxAge = request.corsAnywhereRequestState.corsMaxAge;51 if (request.method === 'OPTIONS' && corsMaxAge) {52 headers['access-control-max-age'] = corsMaxAge;53 }54 if (request.headers['access-control-request-method']) {55 headers['access-control-allow-methods'] = request.headers['access-control-request-method'];56 delete request.headers['access-control-request-method'];57 }58 if (request.headers['access-control-request-headers']) {59 headers['access-control-allow-headers'] = request.headers['access-control-request-headers'];60 delete request.headers['access-control-request-headers'];61 }62 headers['access-control-expose-headers'] = Object.keys(headers).join(',');63 return headers;64}65/**66 * Performs the actual proxy request.67 *68 * @param req {ServerRequest} Incoming http request69 * @param res {ServerResponse} Outgoing (proxied) http request70 * @param proxy {HttpProxy}71 */72function proxyRequest(req, res, proxy) {73 var location = req.corsAnywhereRequestState.location;74 req.url = location.path;75 var proxyOptions = {76 changeOrigin: false,77 prependPath: false,78 target: location,79 headers: {80 host: location.host,81 },82 // HACK: Get hold of the proxyReq object, because we need it later.83 // https://github.com/nodejitsu/node-http-proxy/blob/v1.11.1/lib/http-proxy/passes/web-incoming.js#L14484 buffer: {85 pipe: function(proxyReq) {86 var proxyReqOn = proxyReq.on;87 // Intercepts the handler that connects proxyRes to res.88 // https://github.com/nodejitsu/node-http-proxy/blob/v1.11.1/lib/http-proxy/passes/web-incoming.js#L146-L15889 proxyReq.on = function(eventName, listener) {90 if (eventName !== 'response') {91 return proxyReqOn.call(this, eventName, listener);92 }93 return proxyReqOn.call(this, 'response', function(proxyRes) {94 if (onProxyResponse(proxy, proxyReq, proxyRes, req, res)) {95 try {96 listener(proxyRes);97 } catch (err) {98 // Wrap in try-catch because an error could occur:99 // "RangeError: Invalid status code: 0"100 // https://github.com/Rob--W/cors-anywhere/issues/95101 // https://github.com/nodejitsu/node-http-proxy/issues/1080102 // Forward error (will ultimately emit the 'error' event on our proxy object):103 // https://github.com/nodejitsu/node-http-proxy/blob/v1.11.1/lib/http-proxy/passes/web-incoming.js#L134104 proxyReq.emit('error', err);105 }106 }107 });108 };109 return req.pipe(proxyReq);110 },111 },112 };113 var proxyThroughUrl = req.corsAnywhereRequestState.getProxyForUrl(location.href);114 if (proxyThroughUrl) {115 proxyOptions.target = proxyThroughUrl;116 proxyOptions.toProxy = true;117 // If a proxy URL was set, req.url must be an absolute URL. Then the request will not be sent118 // directly to the proxied URL, but through another proxy.119 req.url = location.href;120 }121 // Start proxying the request122 try {123 proxy.web(req, res, proxyOptions);124 } catch (err) {125 proxy.emit('error', err, req, res);126 }127}128/**129 * This method modifies the response headers of the proxied response.130 * If a redirect is detected, the response is not sent to the client,131 * and a new request is initiated.132 *133 * client (req) -> CORS Anywhere -> (proxyReq) -> other server134 * client (res) <- CORS Anywhere <- (proxyRes) <- other server135 *136 * @param proxy {HttpProxy}137 * @param proxyReq {ClientRequest} The outgoing request to the other server.138 * @param proxyRes {ServerResponse} The response from the other server.139 * @param req {IncomingMessage} Incoming HTTP request, augmented with property corsAnywhereRequestState140 * @param req.corsAnywhereRequestState {object}141 * @param req.corsAnywhereRequestState.location {object} See parseURL142 * @param req.corsAnywhereRequestState.getProxyForUrl {function} See proxyRequest143 * @param req.corsAnywhereRequestState.proxyBaseUrl {string} Base URL of the CORS API endpoint144 * @param req.corsAnywhereRequestState.maxRedirects {number} Maximum number of redirects145 * @param req.corsAnywhereRequestState.redirectCount_ {number} Internally used to count redirects146 * @param res {ServerResponse} Outgoing response to the client that wanted to proxy the HTTP request.147 *148 * @returns {boolean} true if http-proxy should continue to pipe proxyRes to res.149 */150function onProxyResponse(proxy, proxyReq, proxyRes, req, res) {151 var requestState = req.corsAnywhereRequestState;152 var statusCode = proxyRes.statusCode;153 if (!requestState.redirectCount_) {154 res.setHeader('x-request-url', requestState.location.href);155 }156 // Handle redirects157 if (statusCode === 301 || statusCode === 302 || statusCode === 303 || statusCode === 307 || statusCode === 308) {158 var locationHeader = proxyRes.headers.location;159 var parsedLocation;160 if (locationHeader) {161 locationHeader = url.resolve(requestState.location.href, locationHeader);162 parsedLocation = parseURL(locationHeader);163 }164 if (parsedLocation) {165 if (statusCode === 301 || statusCode === 302 || statusCode === 303) {166 // Exclude 307 & 308, because they are rare, and require preserving the method + request body167 requestState.redirectCount_ = requestState.redirectCount_ + 1 || 1;168 if (requestState.redirectCount_ <= requestState.maxRedirects) {169 // Handle redirects within the server, because some clients (e.g. Android Stock Browser)170 // cancel redirects.171 // Set header for debugging purposes. Do not try to parse it!172 res.setHeader('X-CORS-Redirect-' + requestState.redirectCount_, statusCode + ' ' + locationHeader);173 req.method = 'GET';174 req.headers['content-length'] = '0';175 delete req.headers['content-type'];176 requestState.location = parsedLocation;177 // Remove all listeners (=reset events to initial state)178 req.removeAllListeners();179 // Remove the error listener so that the ECONNRESET "error" that180 // may occur after aborting a request does not propagate to res.181 // https://github.com/nodejitsu/node-http-proxy/blob/v1.11.1/lib/http-proxy/passes/web-incoming.js#L134182 proxyReq.removeAllListeners('error');183 proxyReq.once('error', function catchAndIgnoreError() {});184 proxyReq.abort();185 // Initiate a new proxy request.186 proxyRequest(req, res, proxy);187 return false;188 }189 }190 proxyRes.headers.location = requestState.proxyBaseUrl + '/' + locationHeader;191 }192 }193 // Strip cookies194 delete proxyRes.headers['set-cookie'];195 delete proxyRes.headers['set-cookie2'];196 proxyRes.headers['x-final-url'] = requestState.location.href;197 withCORS(proxyRes.headers, req);198 return true;199}200/**201 * @param req_url {string} The requested URL (scheme is optional).202 * @return {object} URL parsed using url.parse203 */204function parseURL(req_url) {205 var match = req_url.match(/^(?:(https?:)?\/\/)?(([^\/?]+?)(?::(\d{0,5})(?=[\/?]|$))?)([\/?][\S\s]*|$)/i);206 // ^^^^^^^ ^^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^207 // 1:protocol 3:hostname 4:port 5:path + query string208 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^209 // 2:host210 if (!match) {211 return null;212 }213 if (!match[1]) {214 if (/^https?:/i.test(req_url)) {215 // The pattern at top could mistakenly parse "http:///" as host="http:" and path=///.216 return null;217 }218 // Scheme is omitted.219 if (req_url.lastIndexOf('//', 0) === -1) {220 // "//" is omitted.221 req_url = '//' + req_url;222 }223 req_url = (match[4] === '443' ? 'https:' : 'http:') + req_url;224 }225 var parsed = url.parse(req_url);226 if (!parsed.hostname) {227 // "http://:1/" and "http:/notenoughslashes" could end up here.228 return null;229 }230 return parsed;231}232// Request handler factory233function getHandler(options, proxy) {234 var corsAnywhere = {235 handleInitialRequest: null, // Function that may handle the request instead, by returning a truthy value.236 getProxyForUrl: getProxyForUrl, // Function that specifies the proxy to use237 maxRedirects: 5, // Maximum number of redirects to be followed.238 originBlacklist: [], // Requests from these origins will be blocked.239 originWhitelist: [], // If non-empty, requests not from an origin in this list will be blocked.240 checkRateLimit: null, // Function that may enforce a rate-limit by returning a non-empty string.241 redirectSameOrigin: false, // Redirect the client to the requested URL for same-origin requests.242 requireHeader: null, // Require a header to be set?243 removeHeaders: [], // Strip these request headers.244 setHeaders: {}, // Set these request headers.245 corsMaxAge: 0, // If set, an Access-Control-Max-Age header with this value (in seconds) will be added.246 helpFile: __dirname + '/help.txt',247 };248 Object.keys(corsAnywhere).forEach(function(option) {249 if (Object.prototype.hasOwnProperty.call(options, option)) {250 corsAnywhere[option] = options[option];251 }252 });253 // Convert corsAnywhere.requireHeader to an array of lowercase header names, or null.254 if (corsAnywhere.requireHeader) {255 if (typeof corsAnywhere.requireHeader === 'string') {256 corsAnywhere.requireHeader = [corsAnywhere.requireHeader.toLowerCase()];257 } else if (!Array.isArray(corsAnywhere.requireHeader) || corsAnywhere.requireHeader.length === 0) {258 corsAnywhere.requireHeader = null;259 } else {260 corsAnywhere.requireHeader = corsAnywhere.requireHeader.map(function(headerName) {261 return headerName.toLowerCase();262 });263 }264 }265 var hasRequiredHeaders = function(headers) {266 return !corsAnywhere.requireHeader || corsAnywhere.requireHeader.some(function(headerName) {267 return Object.hasOwnProperty.call(headers, headerName);268 });269 };270 return function(req, res) {271 req.corsAnywhereRequestState = {272 getProxyForUrl: corsAnywhere.getProxyForUrl,273 maxRedirects: corsAnywhere.maxRedirects,274 corsMaxAge: corsAnywhere.corsMaxAge,275 };276 var cors_headers = withCORS({}, req);277 if (req.method === 'OPTIONS') {278 // Pre-flight request. Reply successfully:279 res.writeHead(200, cors_headers);280 res.end();281 return;282 }283 var location = parseURL(req.url.slice(1));284 if (corsAnywhere.handleInitialRequest && corsAnywhere.handleInitialRequest(req, res, location)) {285 return;286 }287 if (!location) {288 // Special case http:/notenoughslashes, because new users of the library frequently make the289 // mistake of putting this application behind a server/router that normalizes the URL.290 // See https://github.com/Rob--W/cors-anywhere/issues/238#issuecomment-629638853291 if (/^\/https?:\/[^/]/i.test(req.url)) {292 res.writeHead(400, 'Missing slash', cors_headers);293 res.end('The URL is invalid: two slashes are needed after the http(s):.');294 return;295 }296 // Invalid API call. Show how to correctly use the API297 showUsage(corsAnywhere.helpFile, cors_headers, res);298 return;299 }300 if (location.host === 'iscorsneeded') {301 // Is CORS needed? This path is provided so that API consumers can test whether it's necessary302 // to use CORS. The server's reply is always No, because if they can read it, then CORS headers303 // are not necessary.304 res.writeHead(200, {'Content-Type': 'text/plain'});305 res.end('no');306 return;307 }308 if (location.port > 65535) {309 // Port is higher than 65535310 res.writeHead(400, 'Invalid port', cors_headers);311 res.end('Port number too large: ' + location.port);312 return;313 }314 if (!/^\/https?:/.test(req.url) && !isValidHostName(location.hostname)) {315 // Don't even try to proxy invalid hosts (such as /favicon.ico, /robots.txt)316 res.writeHead(404, 'Invalid host', cors_headers);317 res.end('Invalid host: ' + location.hostname);318 return;319 }320 if (!hasRequiredHeaders(req.headers)) {321 res.writeHead(400, 'Header required', cors_headers);322 res.end('Missing required request header. Must specify one of: ' + corsAnywhere.requireHeader);323 return;324 }325 var origin = req.headers.origin || '';326 if (corsAnywhere.originBlacklist.indexOf(origin) >= 0) {327 res.writeHead(403, 'Forbidden', cors_headers);328 res.end('The origin "' + origin + '" was blacklisted by the operator of this proxy.');329 return;330 }331 if (corsAnywhere.originWhitelist.length && corsAnywhere.originWhitelist.indexOf(origin) === -1) {332 res.writeHead(403, 'Forbidden', cors_headers);333 res.end('The origin "' + origin + '" was not whitelisted by the operator of this proxy.');334 return;335 }336 var rateLimitMessage = corsAnywhere.checkRateLimit && corsAnywhere.checkRateLimit(origin);337 if (rateLimitMessage) {338 res.writeHead(429, 'Too Many Requests', cors_headers);339 res.end('The origin "' + origin + '" has sent too many requests.\n' + rateLimitMessage);340 return;341 }342 if (corsAnywhere.redirectSameOrigin && origin && location.href[origin.length] === '/' &&343 location.href.lastIndexOf(origin, 0) === 0) {344 // Send a permanent redirect to offload the server. Badly coded clients should not waste our resources.345 cors_headers.vary = 'origin';346 cors_headers['cache-control'] = 'private';347 cors_headers.location = location.href;348 res.writeHead(301, 'Please use a direct request', cors_headers);349 res.end();350 return;351 }352 var isRequestedOverHttps = req.connection.encrypted || /^\s*https/.test(req.headers['x-forwarded-proto']);353 var proxyBaseUrl = (isRequestedOverHttps ? 'https://' : 'http://') + req.headers.host;354 corsAnywhere.removeHeaders.forEach(function(header) {355 delete req.headers[header];356 });357 Object.keys(corsAnywhere.setHeaders).forEach(function(header) {358 req.headers[header] = corsAnywhere.setHeaders[header];359 });360 req.corsAnywhereRequestState.location = location;361 req.corsAnywhereRequestState.proxyBaseUrl = proxyBaseUrl;362 proxyRequest(req, res, proxy);363 };364}365// Create server with default and given values366// Creator still needs to call .listen()367exports.createServer = function createServer(options) {368 options = options || {};369 // Default options:370 var httpProxyOptions = {371 xfwd: true, // Append X-Forwarded-* headers372 secure: process.env.NODE_TLS_REJECT_UNAUTHORIZED !== '0',373 };374 // Allow user to override defaults and add own options375 if (options.httpProxyOptions) {376 Object.keys(options.httpProxyOptions).forEach(function(option) {377 httpProxyOptions[option] = options.httpProxyOptions[option];378 });379 }380 var proxy = httpProxy.createServer(httpProxyOptions);381 var requestHandler = getHandler(options, proxy);382 var server;383 if (options.httpsOptions) {384 server = require('https').createServer(options.httpsOptions, requestHandler);385 } else {386 server = require('http').createServer(requestHandler);387 }388 // When the server fails, just show a 404 instead of Internal server error389 proxy.on('error', function(err, req, res) {390 if (res.headersSent) {391 // This could happen when a protocol error occurs when an error occurs392 // after the headers have been received (and forwarded). Do not write393 // the headers because it would generate an error.394 // Prior to Node 13.x, the stream would have ended.395 // As of Node 13.x, we must explicitly close it.396 if (res.writableEnded === false) {397 res.end();398 }399 return;400 }401 // When the error occurs after setting headers but before writing the response,402 // then any previously set headers must be removed.403 var headerNames = res.getHeaderNames ? res.getHeaderNames() : Object.keys(res._headers || {});404 headerNames.forEach(function(name) {405 res.removeHeader(name);406 });407 res.writeHead(404, {'Access-Control-Allow-Origin': '*'});408 res.end('Not found because of proxy error: ' + err);409 });410 return server;...
cors_vx.x.x.js
Source:cors_vx.x.x.js
1// flow-typed signature: da7d0f3b3f5db2df0a234563f903d1772// flow-typed version: <<STUB>>/cors_v^2.8.4/flow_v0.71.03/**4 * This is an autogenerated libdef stub for:5 *6 * 'cors'7 *8 * Fill this stub out by replacing all the `any` types.9 *10 * Once filled out, we encourage you to share your work with the11 * community by sending a pull request to:12 * https://github.com/flowtype/flow-typed13 */14declare module 'cors' {15 declare module.exports: any;16}17/**18 * We include stubs for each file inside this npm package in case you need to19 * require those files directly. Feel free to delete any files that aren't20 * needed.21 */22declare module 'cors/lib/index' {23 declare module.exports: any;24}25declare module 'cors/test/basic-auth' {26 declare module.exports: any;27}28declare module 'cors/test/body-events' {29 declare module.exports: any;30}31declare module 'cors/test/cors' {32 declare module.exports: any;33}34declare module 'cors/test/error-response' {35 declare module.exports: any;36}37declare module 'cors/test/example-app' {38 declare module.exports: any;39}40declare module 'cors/test/issue-2' {41 declare module.exports: any;42}43declare module 'cors/test/issue-31' {44 declare module.exports: any;45}46declare module 'cors/test/support/env' {47 declare module.exports: any;48}49// Filename aliases50declare module 'cors/lib/index.js' {51 declare module.exports: $Exports<'cors/lib/index'>;52}53declare module 'cors/test/basic-auth.js' {54 declare module.exports: $Exports<'cors/test/basic-auth'>;55}56declare module 'cors/test/body-events.js' {57 declare module.exports: $Exports<'cors/test/body-events'>;58}59declare module 'cors/test/cors.js' {60 declare module.exports: $Exports<'cors/test/cors'>;61}62declare module 'cors/test/error-response.js' {63 declare module.exports: $Exports<'cors/test/error-response'>;64}65declare module 'cors/test/example-app.js' {66 declare module.exports: $Exports<'cors/test/example-app'>;67}68declare module 'cors/test/issue-2.js' {69 declare module.exports: $Exports<'cors/test/issue-2'>;70}71declare module 'cors/test/issue-31.js' {72 declare module.exports: $Exports<'cors/test/issue-31'>;73}74declare module 'cors/test/support/env.js' {75 declare module.exports: $Exports<'cors/test/support/env'>;...
routes.js
Source:routes.js
2const express = require("express");3const controller = require("./controllers.js");4const router = express.Router();5// --------------- API REST CRUD6router.get ("/clientes", cors(), controller.readClientes); // Read All7router.get ("/clientes/:id", cors(), controller.readCliente); // Read8router.delete ("/clientes/:id", cors(), controller.deleteCliente); // Delete9router.put ("/clientes/:id", cors(), controller.updateCliente); // Update10router.post ("/clientes", cors(), controller.createCliente); // Create11router.get ("/articulos", cors(), controller.readArticulos); // Read All12router.get ("/articulos/:id", cors(), controller.readArticulo); // Read13router.delete ("/articulos/:id", cors(), controller.deleteArticulo); // Delete14router.put ("/articulos/:id", cors(), controller.updateArticulo); // Update15router.post ("/articulos", cors(), controller.createArticulo); // Create16router.get ("/distribuidores", cors(), controller.readDistribuidores); // Read All17router.get ("/distribuidores/:id", cors(), controller.readDistribuidor); // Read18router.delete ("/distribuidores/:id", cors(), controller.deleteDistribuidor); // Delete19router.put ("/distribuidores/:id", cors(), controller.updateDistribuidor); // Update20router.post ("/distribuidores", cors(), controller.createDistribuidor); // Create21router.get ("/plantas", cors(), controller.readPlantas); // Read All22router.get ("/plantas/:id", cors(), controller.readPlanta); // Read23router.delete ("/plantas/:id", cors(), controller.deletePlanta); // Delete24router.put ("/plantas/:id", cors(), controller.updatePlanta); // Update25router.post ("/plantas", cors(), controller.createPlanta); // Create...
Using AI Code Generation
1const { Pact } = require('@pact-foundation/pact');2const { somethingLike } = require('@pact-foundation/pact/dsl/matchers');3const { like } = require('@pact-foundation/pact/dsl/matchers');4const { eachLike } = require('@pact-foundation/pact/dsl/matchers');5const { term } = require('@pact-foundation/pact/dsl/matchers');6const { PactWeb } = require('@pact-foundation/pact-web');7const { Matchers } = require('@pact-foundation/pact');8const { somethingLike: like2 } = require('@pact-foundation/pact/dsl/matchers');9const { eachLike: like3 } = require('@pact-foundation/pact/dsl/matchers');10const { term: like4 } = require('@pact-foundation/pact/dsl/matchers');11const { PactWeb: like5 } = require('@pact-foundation/pact-web');12const { Matchers: like6 } = require('@pact-foundation/pact');13const { somethingLike: like7 } = require('@pact-foundation/pact/dsl/matchers');14const { eachLike: like8 } = require('@pact-foundation/pact/dsl/matchers');15const { term: like9 } = require('@pact-foundation/pact/dsl/matchers');16const { PactWeb: like10 } = require('@pact-foundation/pact-web');17const { Matchers: like11 } = require('@pact-foundation/pact');18const { somethingLike: like12 } = require('@pact-foundation/pact/dsl/matchers');19const { eachLike: like13 } = require('@pact-foundation/pact/dsl/matchers');20const { term: like14 } = require('@pact-foundation/pact/dsl/matchers');21const { PactWeb: like15 } = require('@pact-foundation/pact-web');22const { Matchers: like16 } = require('@pact-foundation/pact');23const { somethingLike: like17 } = require('@pact-foundation/pact/dsl/matchers');24const { eachLike: like18 } = require('@pact-foundation/pact/dsl/matchers');25const { term: like19 } = require('@pact-foundation/pact/d
Using AI Code Generation
1var Pact = require('pact-foundation-pact-node');2var path = require('path');3var pact = new Pact({4 log: path.resolve(process.cwd(), 'logs', 'pact.log'),5 dir: path.resolve(process.cwd(), 'pacts'),6});7pact.setup().then(function () {8 console.log('setup');9 pact.addInteraction({10 withRequest: {11 headers: {12 },13 body: {14 }15 },16 willRespondWith: {17 headers: {18 'Content-Type': 'application/json; charset=utf-8'19 },20 body: {21 }22 }23 }).then(function () {24 console.log('addInteraction');25 pact.verify().then(function (output) {26 console.log('verify');27 console.log(output);28 pact.finalize().then(function () {29 console.log('finalize');30 });31 });32 });33});34var Pact = require('pact-foundation-pact-node');35var path = require('path');36var pact = new Pact({37 log: path.resolve(process.cwd(), 'logs', 'pact.log'),38 dir: path.resolve(process.cwd(), 'pacts'),39});40pact.setup().then(function () {41 console.log('setup');42 pact.addInteraction({43 withRequest: {44 headers: {45 }46 },47 willRespondWith: {48 headers: {49 'Content-Type': 'application/json; charset=utf-8'50 },51 body: [{
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!