@@ -1701,6 +1701,92 @@ describe('multiparty', function () {
17011701 rimraf ( TMP_PATH , done )
17021702 } )
17031703
1704+ describe ( 'content transfer encoding (issue 280)' , function ( ) {
1705+ var cases = [
1706+ { encoding : 'base64' , chunkSize : 0 } ,
1707+ { encoding : 'binary' , chunkSize : 5 } ,
1708+ { encoding : 'base64' , chunkSize : 4 } ,
1709+ { encoding : 'base64' , chunkSize : 1 } ,
1710+ { encoding : 'base64' , chunkSize : 2 } ,
1711+ { encoding : 'base64' , chunkSize : 3 } ,
1712+ { encoding : 'base64' , chunkSize : 5 } ,
1713+ { encoding : 'base64' , chunkSize : 6 } ,
1714+ { encoding : 'base64' , chunkSize : 7 } ,
1715+ { encoding : 'base64' , chunkSize : 5 , variant : 'line-wrapped' } ,
1716+ { encoding : 'base64' , chunkSize : 5 , variant : 'unpadded' , size : 19 } ,
1717+ { encoding : 'base64' , chunkSize : 5 , variant : 'unpadded' , size : 20 }
1718+ ]
1719+
1720+ cases . forEach ( function ( testCase ) {
1721+ var chunks = testCase . chunkSize ? testCase . chunkSize + '-byte chunks' : 'one chunk'
1722+ var variant = testCase . variant ? ' (' + testCase . variant + ')' : ''
1723+ if ( testCase . size ) variant += ' with ' + testCase . size + ' original bytes'
1724+
1725+ it ( 'preserves a ' + testCase . encoding + ' file sent in ' + chunks + variant , function ( done ) {
1726+ var original = Buffer . from ( '000102037f80feff48656c6c6f20776f726c6421' , 'hex' )
1727+ if ( testCase . size ) original = original . slice ( 0 , testCase . size )
1728+ var body = testCase . encoding === 'base64'
1729+ ? Buffer . from ( original . toString ( 'base64' ) )
1730+ : original
1731+ if ( testCase . variant === 'line-wrapped' ) {
1732+ body = Buffer . from ( body . toString ( ) . replace ( / ( .{ 4 } ) / g, '$1\r\n \t' ) )
1733+ } else if ( testCase . variant === 'unpadded' ) {
1734+ body = Buffer . from ( body . toString ( ) . replace ( / = + $ / , '' ) )
1735+ }
1736+ var header = Buffer . from (
1737+ '--foo\r\n' +
1738+ 'Content-Disposition: form-data; name="file"; filename="file.bin"\r\n' +
1739+ 'Content-Type: application/octet-stream\r\n' +
1740+ 'Content-Transfer-Encoding: ' + testCase . encoding + '\r\n\r\n'
1741+ )
1742+ var footer = Buffer . from ( '\r\n--foo--\r\n' )
1743+ var req = new stream . PassThrough ( )
1744+ var form = new multiparty . Form ( { uploadDir : TMP_PATH } )
1745+
1746+ req . headers = {
1747+ 'content-type' : 'multipart/form-data; boundary=foo' ,
1748+ 'content-length' : header . length + body . length + footer . length
1749+ }
1750+
1751+ form . parse ( req , function ( err , fields , files ) {
1752+ if ( err ) return done ( err )
1753+ fs . readFile ( files . file [ 0 ] . path , function ( err , actual ) {
1754+ if ( err ) return done ( err )
1755+ assert . deepEqual ( actual , original )
1756+ done ( )
1757+ } )
1758+ } )
1759+
1760+ // Preserve explicit request chunk boundaries without TCP buffering.
1761+ req . write ( header )
1762+ var chunkSize = testCase . chunkSize || body . length
1763+ for ( var offset = 0 ; offset < body . length ; offset += chunkSize ) {
1764+ req . write ( body . slice ( offset , offset + chunkSize ) )
1765+ }
1766+ req . end ( footer )
1767+ } )
1768+ } )
1769+
1770+ it ( 'flushes and resets the base64 remainder between parts' , function ( done ) {
1771+ var req = new stream . PassThrough ( )
1772+ var form = new multiparty . Form ( )
1773+ req . headers = { 'content-type' : 'multipart/form-data; boundary=foo' }
1774+
1775+ form . parse ( req , function ( err , fields ) {
1776+ if ( err ) return done ( err )
1777+ assert . deepEqual ( fields , { first : [ 'a' ] , second : [ 'bc' ] , third : [ 'plain' ] } )
1778+ done ( )
1779+ } )
1780+
1781+ req . write ( '--foo\r\nContent-Disposition: form-data; name="first"\r\n' +
1782+ 'Content-Transfer-Encoding: base64\r\n\r\nYQ' )
1783+ req . write ( '\r\n--foo\r\nContent-Disposition: form-data; name="second"\r\n' +
1784+ 'Content-Transfer-Encoding: base64\r\n\r\nYmM' )
1785+ req . end ( '\r\n--foo\r\nContent-Disposition: form-data; name="third"\r\n' +
1786+ '\r\nplain\r\n--foo--\r\n' )
1787+ } )
1788+ } )
1789+
17041790 describe ( 'fixture tests' , function ( ) {
17051791 var fixtureServer = http . createServer ( )
17061792 var fixtureTests = requireAll ( path . join ( FIXTURE_PATH , 'js' ) )
0 commit comments