ext-utils/form.js

121 lines
2.3 KiB
JavaScript
Raw Normal View History

2016-05-31 09:56:05 +00:00
var cl = global.botanLoader;
var WebParam = cl.load( "botanss.utils.WebParam" );
var ReadStream = require( "stream" ).Readable;
var qstr = require( "./querystr.js" );
module.exports = {
form_multipart: function( boundary, request, handler )
{
2022-04-06 04:52:43 +00:00
boundary = Buffer.from( "--" + boundary );
var delim = Buffer.from( "0D0A0D0A", "hex" );
var endBuff = Buffer.from( "2D2D0D0A", "hex" );
2016-05-31 09:56:05 +00:00
var st = request.resultStream();
var firstRead = true;
var tarBuff = null;
var content = [[]];
var i = 0;
var ring = 0;
st.addListener( "readable", function()
{
if( firstRead )
{
firstRead = false;
var r = st.read( boundary.length, "hex" );
if( !r.equals( boundary ) )
throw new Error( "Invalid form input" );
}
// Read them byte by byte
while( ( r = st.read( 1, "hex" ) ) !== null )
{
switch( ring )
{
case 0:
tarRBuff = delim;
nextRing = 1;
break;
case 1:
tarRBuff = boundary;
nextRing = 0;
break;
}
if( tarBuff )
{
content[ i ].push( tarBuff[0] );
tarBuff = Buffer.concat([ tarBuff.slice( 1 ), r ]);
}
else
{
tarBuff = Buffer.concat([ r, st.read( tarRBuff.length - 1, "hex" ) ]);
}
if( tarBuff.equals( tarRBuff ) )
{
i ++; content[ i ] = [];
ring = nextRing;
tarBuff = null;
}
}
} );
st.addListener( "end", function()
{
if( !tarBuff.equals( endBuff ) )
{
throw new Error( "Invalid form data" );
}
2022-04-06 04:52:43 +00:00
content = content.map( ( v ) => Buffer.from( v ) );
2016-05-31 09:56:05 +00:00
var item;
var formData = [];
var l = content.length;
for( var i = 0; i < l; i ++ )
{
if( i % 2 == 0 )
{
item = {};
content[i].toString().split( "\r\n" ).forEach(
function( v )
{
if( !v ) return;
v = v.split( ":" );
item[ v[0] ] = new WebParam( v[1] );
} );
}
else
{
// the -2 is the last 0D0A
item.file = {
content: new ReadStream()
, size: content[i].length - 2
};
item.file.content._read = function(){};
setTimeout(
function()
{
this.f.push( this.c.slice( 0, -2 ) );
this.f.push( null );
}.bind({ f: item.file.content, c: content[i] })
, 0 );
formData.push( item );
}
}
handler( formData );
} );
}
};