11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ciconst http = require('http'); 51cb0ef41Sopenharmony_ciconst net = require('net'); 61cb0ef41Sopenharmony_ciconst assert = require('assert'); 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci// The maximum http chunk extension size is set in `src/node_http_parser.cc`. 91cb0ef41Sopenharmony_ci// These tests assert that once the extension size is reached, an HTTP 413 101cb0ef41Sopenharmony_ci// response is returned. 111cb0ef41Sopenharmony_ci// Currently, the max size is set to 16KiB (16384). 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci// Verify that chunk extensions are limited in size when sent all together. 141cb0ef41Sopenharmony_ci{ 151cb0ef41Sopenharmony_ci const server = http.createServer((req, res) => { 161cb0ef41Sopenharmony_ci req.on('end', () => { 171cb0ef41Sopenharmony_ci res.writeHead(200, { 'Content-Type': 'text/plain' }); 181cb0ef41Sopenharmony_ci res.end('bye'); 191cb0ef41Sopenharmony_ci }); 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci req.resume(); 221cb0ef41Sopenharmony_ci }); 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ci server.listen(0, () => { 251cb0ef41Sopenharmony_ci const port = server.address().port; 261cb0ef41Sopenharmony_ci const sock = net.connect(port); 271cb0ef41Sopenharmony_ci let data = ''; 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci sock.on('data', (chunk) => data += chunk.toString('utf-8')); 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci sock.on('end', common.mustCall(function() { 321cb0ef41Sopenharmony_ci assert.strictEqual(data, 'HTTP/1.1 413 Payload Too Large\r\nConnection: close\r\n\r\n'); 331cb0ef41Sopenharmony_ci server.close(); 341cb0ef41Sopenharmony_ci })); 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci sock.end('' + 371cb0ef41Sopenharmony_ci 'GET / HTTP/1.1\r\n' + 381cb0ef41Sopenharmony_ci `Host: localhost:${port}\r\n` + 391cb0ef41Sopenharmony_ci 'Transfer-Encoding: chunked\r\n\r\n' + 401cb0ef41Sopenharmony_ci '2;' + 'a'.repeat(17000) + '\r\n' + // Chunk size + chunk ext + CRLF 411cb0ef41Sopenharmony_ci 'AA\r\n' + // Chunk data 421cb0ef41Sopenharmony_ci '0\r\n' + // Last chunk 431cb0ef41Sopenharmony_ci '\r\n' // End of http message 441cb0ef41Sopenharmony_ci ); 451cb0ef41Sopenharmony_ci }); 461cb0ef41Sopenharmony_ci} 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci// Verify that chunk extensions are limited in size when sent in parts 491cb0ef41Sopenharmony_ci{ 501cb0ef41Sopenharmony_ci const server = http.createServer((req, res) => { 511cb0ef41Sopenharmony_ci req.on('end', () => { 521cb0ef41Sopenharmony_ci res.writeHead(200, { 'Content-Type': 'text/plain' }); 531cb0ef41Sopenharmony_ci res.end('bye'); 541cb0ef41Sopenharmony_ci }); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci req.resume(); 571cb0ef41Sopenharmony_ci }); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci server.listen(0, () => { 601cb0ef41Sopenharmony_ci const port = server.address().port; 611cb0ef41Sopenharmony_ci const sock = net.connect(port); 621cb0ef41Sopenharmony_ci let data = ''; 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci sock.on('data', (chunk) => data += chunk.toString('utf-8')); 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci sock.on('end', common.mustCall(function() { 671cb0ef41Sopenharmony_ci assert.strictEqual(data, 'HTTP/1.1 413 Payload Too Large\r\nConnection: close\r\n\r\n'); 681cb0ef41Sopenharmony_ci server.close(); 691cb0ef41Sopenharmony_ci })); 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci sock.write('' + 721cb0ef41Sopenharmony_ci 'GET / HTTP/1.1\r\n' + 731cb0ef41Sopenharmony_ci `Host: localhost:${port}\r\n` + 741cb0ef41Sopenharmony_ci 'Transfer-Encoding: chunked\r\n\r\n' + 751cb0ef41Sopenharmony_ci '2;' // Chunk size + start of chunk-extension 761cb0ef41Sopenharmony_ci ); 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci sock.write('A'.repeat(8500)); // Write half of the chunk-extension 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci queueMicrotask(() => { 811cb0ef41Sopenharmony_ci sock.write('A'.repeat(8500) + '\r\n' + // Remaining half of the chunk-extension 821cb0ef41Sopenharmony_ci 'AA\r\n' + // Chunk data 831cb0ef41Sopenharmony_ci '0\r\n' + // Last chunk 841cb0ef41Sopenharmony_ci '\r\n' // End of http message 851cb0ef41Sopenharmony_ci ); 861cb0ef41Sopenharmony_ci }); 871cb0ef41Sopenharmony_ci }); 881cb0ef41Sopenharmony_ci} 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci// Verify the chunk extensions is correctly reset after a chunk 911cb0ef41Sopenharmony_ci{ 921cb0ef41Sopenharmony_ci const server = http.createServer((req, res) => { 931cb0ef41Sopenharmony_ci req.on('end', () => { 941cb0ef41Sopenharmony_ci res.writeHead(200, { 'content-type': 'text/plain', 'connection': 'close', 'date': 'now' }); 951cb0ef41Sopenharmony_ci res.end('bye'); 961cb0ef41Sopenharmony_ci }); 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci req.resume(); 991cb0ef41Sopenharmony_ci }); 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci server.listen(0, () => { 1021cb0ef41Sopenharmony_ci const port = server.address().port; 1031cb0ef41Sopenharmony_ci const sock = net.connect(port); 1041cb0ef41Sopenharmony_ci let data = ''; 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci sock.on('data', (chunk) => data += chunk.toString('utf-8')); 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci sock.on('end', common.mustCall(function() { 1091cb0ef41Sopenharmony_ci assert.strictEqual( 1101cb0ef41Sopenharmony_ci data, 1111cb0ef41Sopenharmony_ci 'HTTP/1.1 200 OK\r\n' + 1121cb0ef41Sopenharmony_ci 'content-type: text/plain\r\n' + 1131cb0ef41Sopenharmony_ci 'connection: close\r\n' + 1141cb0ef41Sopenharmony_ci 'date: now\r\n' + 1151cb0ef41Sopenharmony_ci 'Transfer-Encoding: chunked\r\n' + 1161cb0ef41Sopenharmony_ci '\r\n' + 1171cb0ef41Sopenharmony_ci '3\r\n' + 1181cb0ef41Sopenharmony_ci 'bye\r\n' + 1191cb0ef41Sopenharmony_ci '0\r\n' + 1201cb0ef41Sopenharmony_ci '\r\n', 1211cb0ef41Sopenharmony_ci ); 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci server.close(); 1241cb0ef41Sopenharmony_ci })); 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci sock.end('' + 1271cb0ef41Sopenharmony_ci 'GET / HTTP/1.1\r\n' + 1281cb0ef41Sopenharmony_ci `Host: localhost:${port}\r\n` + 1291cb0ef41Sopenharmony_ci 'Transfer-Encoding: chunked\r\n\r\n' + 1301cb0ef41Sopenharmony_ci '2;' + 'A'.repeat(10000) + '=bar\r\nAA\r\n' + 1311cb0ef41Sopenharmony_ci '2;' + 'A'.repeat(10000) + '=bar\r\nAA\r\n' + 1321cb0ef41Sopenharmony_ci '2;' + 'A'.repeat(10000) + '=bar\r\nAA\r\n' + 1331cb0ef41Sopenharmony_ci '0\r\n\r\n' 1341cb0ef41Sopenharmony_ci ); 1351cb0ef41Sopenharmony_ci }); 1361cb0ef41Sopenharmony_ci} 137