VimUnDoB? bI[~W*8Gl]* yyyyOG/_ OG]`       5_   vOG]a   console.log(var);5_  vOG]+var common = require('../common');/var test = common.fastOrSlow.fast();$var assert = common.assert;9var MultipartParser = common.require('multipart_parser');-var Part = common.require('part');Avar boundary = '------WebKitFormBoundarytyE4wkKlZ5CQJVTG'; var parser;test.before(function() {, parser = MultipartParser.create(boundary);});2function assertEmitsError(buffer, expectedError) { var hadError = false;$ parser.on('error', function(err) { hadError = true;M assert.equal(err.message.substr(0, expectedError.length), expectedError); }); parser.write(buffer);. assert.ok(hadError, 'no error was emitted');}8test('#write: error: invalid parser state', function() { parser._state = 'SOMETHING';L assertEmitsError(new Buffer('123'), 'MultipartParser.InvalidParserState');});:test('#write: error: write without boundary', function() { var buffer = new Buffer('a');% parser = new MultipartParser(); assert.throws(function() { parser.write(buffer); }, /Bad state: NO_BOUNDARY/);});Dtest('#write: tolerate missing CRLF on first boundary', function() {4 var buffer = new Buffer('--' + boundary + '\r\n'); parser.write(buffer);. assert.equal(parser._state, 'HEADER_FIELD');});-test('#write: leading preamble', function() {; parser.write(new Buffer(boundary.substr(0, 4) + 'HAHA'));* assert.equal(parser._state, 'PREAMBLE');5 parser.write(new Buffer('--' + boundary + '\r\n'));. assert.equal(parser._state, 'HEADER_FIELD');});8test('#write: error: Invalid header token', function() {N // ',' is an example for an invalid token for header fields (see RFC 2616). var buffer = new Buffer('Invalid,Header: ');! parser._state = 'HEADER_FIELD';F assertEmitsError(buffer, 'MultipartParser.InvalidHeaderFieldToken');});Etest('#write: Emit part object with lowercased headers', function() {J var buffer = new Buffer('Header-1:value-1\r\nHeader-2:value-2\r\n\r\n');! parser._state = 'HEADER_FIELD'; parser._part = new Part(); parser.write(buffer);* assert.deepEqual(parser._part.headers, { 'header-1': 'value-1', 'header-2': 'value-2', });});Ntest('#write: Trim leading and trailing header value whitespace', function() {4 var buffer = new Buffer('header: value \r\n\r\n');! parser._state = 'HEADER_FIELD'; parser._part = new Part(); parser.write(buffer);> assert.deepEqual(parser._part.headers, {'header': 'value'});});@test('#write: error: CR on non-empty _headerField', function() {$ var buffer = new Buffer('head\r');! parser._state = 'HEADER_FIELD';F assertEmitsError(buffer, 'MultipartParser.InvalidHeaderFieldToken');});,test('#write: no part headers', function() {" var buffer = new Buffer('\r\n');! parser._state = 'HEADER_FIELD'; parser._part = new Part(); parser.write(buffer);- assert.deepEqual(parser._part.headers, {});});test('#write: hit partial boundary in part data', function() { parser.boundary('end'); parser._preamble = false; parser._part = new Part();! parser._state = 'PART_BODY'; var buffers =[];, parser._part.on('data', function(buffer) { buffers.push(''+buffer); });* parser.write(new Buffer('ab\r\n--enc'));5 assert.deepEqual(buffers, ['ab', '\r\n--en', 'c']);});Ttest('#write: hit partial boundary in part data spread over 2 buffers', function() { parser.boundary('end'); parser._preamble = false; parser._part = new Part();! parser._state = 'PART_BODY'; var buffers =[];, parser._part.on('data', function(buffer) { buffers.push(''+buffer); });& var first = new Buffer('ab\r\n--e');" var second = new Buffer('haha'); parser.write(first);" assert.equal(buffers.length, 1); parser.write(second);7 assert.deepEqual(buffers, ['ab', '\r\n--e', 'haha']);});Ttest('#write: hit partial boundary in part data spread over 3 buffers', function() { parser.boundary('end'); parser._preamble = false; parser._part = new Part();! parser._state = 'PART_BODY'; var buffers =[];, parser._part.on('data', function(buffer) { buffers.push(''+buffer); });& var first = new Buffer('ab\r\n--e'); var second = new Buffer('n');! var third = new Buffer('haha'); parser.write(first);" assert.equal(buffers.length, 1); parser.write(second);" assert.equal(buffers.length, 1); parser.write(third);8 assert.deepEqual(buffers, ['ab', '\r\n--en', 'haha']);});'function testRfc1341Entity(chunkSize) {% parser.boundary('simple boundary'); var part1 =6 'This is implicitly typed plain ASCII text.\r\n' +( 'It does NOT end with a linebreak.'; var part2 =6 'This is explicitly typed plain ASCII text.\r\n' +( 'It DOES end with a linebreak.\r\n'; var rfc1341Entity =A 'This is the preamble. It is to be ignored, though it\r\n' += 'is a handy place for mail composers to include an\r\n' +; 'explanatory note to non-MIME compliant readers.\r\n' + '--simple boundary\r\n' + '\r\n' + part1 + '\r\n' + '--simple boundary\r\n' +6 'Content-type: text/plain; charset=us-ascii\r\n' + '\r\n' + part2 + '\r\n' + '--simple boundary--\r\n' +; 'This is the epilogue. It is also to be ignored.\r\n'; var parts = []; var ended = false; parser" .on('error', function(error) { throw error; }) .on('part', function(part) { parts.push(part); part.data = ''; part% .on('data', function(chunk) { part.data += chunk; }) .on('end', function() { part.ended = true; }); }) .on('end', function() { ended = true; });) var buffer = new Buffer(rfc1341Entity); if (!chunkSize) { parser.write(buffer); } else {8 for (var i = 0; i < buffer.length; i += chunkSize) {/ var end = (i + chunkSize < buffer.length) ? i + chunkSize : buffer.length;3 var chunk = new Buffer(buffer.slice(i, end)); parser.write(chunk); } } assert.equal(parts.length, 2);% assert.equal(parts[0].data, part1);% assert.equal(parts[1].data, part2);# parts.forEach(function(part, i) {? assert.ok(part.ended, 'Part ' + (i + 1) + ' did not end.'); }); assert.ok(ended);}0test('#write: full rfc1341 entity', function() { testRfc1341Entity();});O// What can I say, my ability to visualize this state machine has its limits :)for (var i = 1; i <= 10; i++) {H test('#write: full rfc1341 entity with chunk size: ' + i, function() {: var chunkSize = parseInt(this.name.match(/\d+$/), 10); console.log(chunkSize);! testRfc1341Entity(chunkSize); });}5_  vOG^ 5_"  vOG^5_!vOG^# parser = new MultipartParser();5_ vOG^+ parser = new MultipartParser(boundary);5_   vOG^5_ vOG^+ parser = new MultipartParser(boundary);5_ vOG^5_   vOG^5_  vOG^5_   vOG^5_vOG_ - parser = new MultipartParser(boundary);5_vOG_! 5_vOG_" console.error(var);5_vOG_# 5_vOG_ return;5_vOG_/ //parser = new MultipartParser(boundary);5_vOG_5_vOG_ 5_vOG_ 5_vOG_ console.log(var);5_vOG_  console.error(parser);5_vOG_ parser.reset();5_vOG_ console.log(parser);5_vOG_ 5_  vOG_ 5_! vOG_  5_ "!vOGa c 5_!#"vOGa  console.log(var);5_"$#  vOGa parser.removeAllListeners();5_#%$ vOGa$ 5_$&% vOGa- parser._events = {};5_%'& vOGa parser.reset();5_&*' vOGa //parser.reset();5_'+)* vOGa 5_*,+ vOGa console.log(parser);5_+-, vOGb5_,.-0+0V OGj 075_-/.1+0V OGj 025_.0/2 +0V OGj135 '#write: error: Invalid header token': function() {5_/104+0V OGj350 var buffer = new Buffer('Invalid,Header: ');5_021444%v%OGj$48 36) var buffer = new Buffer(',Header: ');5_132457*v%OGj&35# var buffer = new Buffer('Content-Type: text/html;5_243446*v%OGj&35"6 var buffer = new Buffer(' Content-Type: text/html;5_3544546*v%OGj)35"5 var buffer = new Buffer('Content-Type: text/html;5_465446*v%OGj/36"9 var buffer = new Buffer('Content-Type: text/html;\r\n5_576547*v%OGj146#% 'Content-Type: text/html;\r\n5_687347*v%OGj123P // ',' is an example for an invalid token for header fields (see RFC 2616)5_7:84#36*v%OGj235"# 'Content-Type: text/html;\r\n5_8<9:536*v%OGj946" charset="ISO-8859-4"5_:=;<536*v%OGj?46" ' charset="ISO-8859-4"5_<>=536*v%OGj@46" ' charset="ISO-8859-4"'5_=?>5!36*v%OGjB46"! ' charset="ISO-8859-4"\r\n'5_>@?636*v%OGjE57"+Content-Transfer-Encoding: quoted-printable5_?A@636*v%OGjF57",'Content-Transfer-Encoding: quoted-printable5_@BA6236*v%OGjK57"2 'Content-Transfer-Encoding: quoted-printable5_ACB6236*v%OGjN57"3 'Content-Transfer-Encoding: quoted-printable'5_BDC22 :V OGjc12 7 '#write: multi-line header field value': function() { var buffer = new Buffer(& 'Content-Type: text/html;\r\n' +# ' charset="ISO-8859-4"\r\n' +; 'Content-Transfer-Encoding: quoted-printable\r\n\r\n'');# parser._state = 'HEADER_FIELD';H assertEmitsError(buffer, 'MultipartParser.InvalidHeaderFieldToken'); },5_CED22 2V OGjd125_DFEG2 2V OGjrGQ5_EGFH2 2V OGjsGI!5_FHGI 2 2V OGjwHJ"7 '#write: multi-line header field value': function() {5_GIHI/2 2V OGjzHJ"> '#write: Handle multi-line header field value': function() {5_HJIN2 2V OGjMO"');5_IKJN2 2V OGjNP"5_JLKL2 2V OGjKM## ' charset="ISO-8859-4"\r\n' +5_KMLL 2 2V OGjKM#% '\t charset="ISO-8859-4"\r\n' +5_LNMPA!A!V!OGjPR#5_MONQA!A!V!OGjQS$5_NPOQQSVOGjPT"PQ# parser._state = 'HEADER_FIELD';H assertEmitsError(buffer, 'MultipartParser.InvalidHeaderFieldToken');5_OQPSFFVOGjSU%5_PRQTFFVOGjSU&5_QSRU,FFVOGjTW'@ assert.deepEqual(parser._part.headers, {'header': 'value'});5_RTSVFFVOGjUX( 'header': 'value'});5_SUTVFFVOGjUW) 'header': 'value'5_TVUVFFVOGjUW) 'Content-Type': 'value'5_UWVV FFVOGjUW)! 'Content-Type': 'text/html'5_VXWV+LLvOGjUW)- 'Content-Type': 'text/html; charset=""'5_WYXV6LLvOGjUW)7 'Content-Type': 'text/html; charset="ISO-8859-4"'5_XZYV8M1MvOGjUW)9 'Content-Type': 'text/html; charset="ISO-8859-4"; '5_Y[ZV6M1MvOGjUW)d 'Content-Type': 'text/html; charset="ISO-8859-4"; Content-Transfer-Encoding: quoted-printable'5_Z\[V6M1MvOGjUW)c 'Content-Type': 'text/html; charset="ISO-8859-4" Content-Transfer-Encoding: quoted-printable'5_[]\V6M1MvOGjUW)b 'Content-Type': 'text/html; charset="ISO-8859-4"Content-Transfer-Encoding: quoted-printable'5_\^]V7M1MvOGjVX* 'UX)7 'Content-Type': 'text/html; charset="ISO-8859-4"'5_]_^W M1MvOGjVX*2 'Content-Transfer-Encoding: quoted-printable5_^`_W!M1MvOGjVX*2 'Content-Transfer-Encoding' quoted-printable5__a`W#M1MvOGjVX*3 'Content-Transfer-Encoding': quoted-printable5_`baW4M1MvOGj!VX*4 'Content-Transfer-Encoding': 'quoted-printable5_acbV!M1MvOGkUW*8 'Content-Type': 'text/html; charset="ISO-8859-4"',5_bdcV!M1MvOGk"UW*7 'Content-Type': 'text/html;charset="ISO-8859-4"',5_cedI&M1MvOGl1HJ+ HJ*5_dfeIN1NvOGl4$HJ+4 // http://tools.ietf.org/html/rfc822#section-3.1.35_egfW!N1NvOGlVX+= 'Content-Type': 'text/html;\r\n\tcharset="ISO-8859-4"',5_fhgW!N1NvOGlVX+< 'Content-Type': 'text/html;r\n\tcharset="ISO-8859-4"',5_gihW!N1NvOGlVX+; 'Content-Type': 'text/html;\n\tcharset="ISO-8859-4"',5_hjiW!N1NvOGl%VX+: 'Content-Type': 'text/html;n\tcharset="ISO-8859-4"',5_ikj2N1NvOGp13+B '#write: Emit part object with lowercased headers': function() {5_jlk2N1NvOGp&13+B '#write: Emit part object with lowercased headers': function() {5_kml2N1NvOGy'13+C '!#write: Emit part object with lowercased headers': function() {5_lnmWN1NvOGy>VX+9 'Content-Type': 'text/html;\tcharset="ISO-8859-4"',5_monWN1NvOGy?VX+9 'Content-type': 'text/html;\tcharset="ISO-8859-4"',5_npoXN1NvOGy@WY+6 'Content-Transfer-Encoding': 'quoted-printable',5_oqpXN1NvOGyAWY+6 'content-Transfer-Encoding': 'quoted-printable',5_prqXN1NvOGyB(WY+6 'content-transfer-Encoding': 'quoted-printable',5_qsrVOG}I+5_rtsVOG}J95_sut VOG}L):; '#write: hit partial boundary in part data': function() {5_tvuVOG~L+ },7 assert.deepEqual(buffers, ['ab', '\r\n--en', 'c']);, parser.write(new Buffer('ab\r\n--enc')); }); buffers.push(''+buffer);. parser._part.on('data', function(buffer) { var buffers =[];# parser._state = 'PART_BODY';" parser._part = new Part(); parser._preamble = false; parser.boundary('end');D '#write: newlines before part boundary in part data': function() {5_uwvVOG.- //},9 //assert.deepEqual(buffers, ['ab', '\r\n--en', 'c']);. //parser.write(new Buffer('ab\r\n--enc')); //}); //buffers.push(''+buffer);0 //parser._part.on('data', function(buffer) { //var buffers =[];% //parser._state = 'PART_BODY';$ //parser._part = new Part(); //parser._preamble = false; //parser.boundary('end');F //'#write: newlines before part boundary in part data': function() {5_vxw VOGkD '#write: newlines before part boundary in part data': function() { parser.boundary('end'); parser._preamble = false;" parser._part = new Part();# parser._state = 'PART_BODY'; var buffers =[];. parser._part.on('data', function(buffer) { buffers.push(''+buffer); });, parser.write(new Buffer('ab\r\n--enc'));7 assert.deepEqual(buffers, ['ab', '\r\n--en', 'c']); },5_wyx VOGk.5_xy*+VOG/)* parser.removeAllListeners();5_:<;536*v%OGj=46" ' charset="ISO-8859-4'5_8:9536*v%OGj546" charset="ISO-8859-4"5_'(*) vOGa5_')( vOGa //parser.removeAllListeners();5_vOG_5_vOG_ console.log(parseparser5_  vOG^/function testRfc1341Entity(parser, chunkSize) {5