1'use strict'; 2 3require('../common'); 4const http = require('http'); 5const net = require('net'); 6const url = require('url'); 7const assert = require('assert'); 8const Countdown = require('../common/countdown'); 9 10// Response splitting example, credit: Amit Klein, Safebreach 11const str = '/welcome?lang=bar%c4%8d%c4%8aContentLength:%200%c4%8d%c4%8a%c' + 12 '4%8d%c4%8aHTTP/1.1%20200%20OK%c4%8d%c4%8aContentLength:%202' + 13 '0%c4%8d%c4%8aLastModified:%20Mon,%2027%20Oct%202003%2014:50:18' + 14 '%20GMT%c4%8d%c4%8aContentType:%20text/html%c4%8d%c4%8a%c4%8' + 15 'd%c4%8a%3chtml%3eGotcha!%3c/html%3e'; 16 17// Response splitting example, credit: Сковорода Никита Андреевич (@ChALkeR) 18const x = 'fooഊSet-Cookie: foo=barഊഊ<script>alert("Hi!")</script>'; 19const y = 'foo⠊Set-Cookie: foo=bar'; 20 21let count = 0; 22const countdown = new Countdown(3, () => server.close()); 23 24function test(res, code, key, value) { 25 const header = { [key]: value }; 26 assert.throws( 27 () => res.writeHead(code, header), 28 { 29 code: 'ERR_INVALID_CHAR', 30 name: 'TypeError', 31 message: `Invalid character in header content ["${key}"]` 32 } 33 ); 34} 35 36const server = http.createServer((req, res) => { 37 switch (count++) { 38 case 0: 39 const loc = url.parse(req.url, true).query.lang; 40 test(res, 302, 'Location', `/foo?lang=${loc}`); 41 break; 42 case 1: 43 test(res, 200, 'foo', x); 44 break; 45 case 2: 46 test(res, 200, 'foo', y); 47 break; 48 default: 49 assert.fail('should not get to here.'); 50 } 51 countdown.dec(); 52 res.end('ok'); 53}); 54server.listen(0, () => { 55 const end = 'HTTP/1.1\r\n\r\n'; 56 const client = net.connect({ port: server.address().port }, () => { 57 client.write(`GET ${str} ${end}`); 58 client.write(`GET / ${end}`); 59 client.write(`GET / ${end}`); 60 client.end(); 61 }); 62}); 63