@@ -17,7 +17,6 @@ var path = require('path');
1717var os = require ( 'os' ) ;
1818var Buffer = require ( 'safe-buffer' ) . Buffer
1919var StringDecoder = require ( 'string_decoder' ) . StringDecoder ;
20- var fdSlicer = require ( 'fd-slicer' ) ;
2120
2221var START = 0 ;
2322var START_BOUNDARY = 1 ;
@@ -528,6 +527,32 @@ Form.prototype.onParseHeadersEnd = function(offset) {
528527 }
529528}
530529
530+ util . inherits ( LimitStream , stream . Transform )
531+ function LimitStream ( limit ) {
532+ stream . Transform . call ( this )
533+
534+ this . bytes = 0
535+ this . limit = limit
536+ }
537+
538+ LimitStream . prototype . _transform = function _transform ( chunk , encoding , callback ) {
539+ var length = ! Buffer . isBuffer ( chunk )
540+ ? Buffer . byteLength ( chunk , encoding )
541+ : chunk . length
542+
543+ this . bytes += length
544+
545+ if ( this . bytes > this . limit ) {
546+ var err = new Error ( 'maximum file length exceeded' )
547+ err . code = 'ETOOBIG'
548+ callback ( err )
549+ } else {
550+ this . push ( chunk )
551+ this . emit ( 'progress' , this . bytes , length )
552+ callback ( )
553+ }
554+ }
555+
531556function flushWriteCbs ( self ) {
532557 self . writeCbs . forEach ( function ( cb ) {
533558 process . nextTick ( cb ) ;
@@ -654,46 +679,41 @@ function handleFile(self, fileStream) {
654679 } ;
655680 var internalFile = {
656681 publicFile : publicFile ,
657- ws : null
682+ ls : null ,
683+ ws : fs . createWriteStream ( publicFile . path , { flags : 'wx' } )
658684 } ;
685+ self . openedFiles . push ( internalFile )
659686 beginFlush ( self ) ; // flush to write stream
660687 var emitAndReleaseHold = holdEmitQueue ( self , fileStream ) ;
661688 fileStream . on ( 'error' , function ( err ) {
662689 self . handleError ( err ) ;
663690 } ) ;
664- fs . open ( publicFile . path , 'wx ', function ( err , fd ) {
665- if ( err ) return self . handleError ( err ) ;
666- var slicer = fdSlicer . createFromFd ( fd , { autoClose : true } )
667-
691+ internalFile . ws . on ( 'error ', function ( err ) {
692+ self . handleError ( err )
693+ } )
694+ internalFile . ws . on ( 'open' , function ( ) {
668695 // end option here guarantees that no more than that amount will be written
669696 // or else an error will be emitted
670- internalFile . ws = slicer . createWriteStream ( { end : self . maxFilesSize - self . totalFileSize } )
671-
672- // if an error ocurred while we were waiting for fs.open we handle that
673- // cleanup now
674- self . openedFiles . push ( internalFile ) ;
675- if ( self . error ) return cleanupOpenFiles ( self ) ;
697+ internalFile . ls = new LimitStream ( self . maxFilesSize - self . totalFileSize )
698+ internalFile . ls . pipe ( internalFile . ws )
676699
677- var prevByteCount = 0 ;
678- internalFile . ws . on ( 'error' , function ( err ) {
700+ internalFile . ls . on ( 'error' , function ( err ) {
679701 self . handleError ( err . code === 'ETOOBIG'
680702 ? createError ( 413 , err . message , { code : err . code } )
681703 : err )
682704 } ) ;
683- internalFile . ws . on ( 'progress' , function ( ) {
684- publicFile . size = internalFile . ws . bytesWritten ;
685- var delta = publicFile . size - prevByteCount ;
686- self . totalFileSize += delta ;
687- prevByteCount = publicFile . size ;
705+ internalFile . ls . on ( 'progress' , function ( totalBytes , chunkBytes ) {
706+ publicFile . size = totalBytes
707+ self . totalFileSize += chunkBytes
688708 } ) ;
689- slicer . on ( 'close' , function ( ) {
709+ internalFile . ws . on ( 'close' , function ( ) {
690710 if ( self . error ) return ;
691711 emitAndReleaseHold ( function ( ) {
692712 self . emit ( 'file' , fileStream . name , publicFile ) ;
693713 } ) ;
694714 endFlush ( self ) ;
695715 } ) ;
696- fileStream . pipe ( internalFile . ws ) ;
716+ fileStream . pipe ( internalFile . ls )
697717 } ) ;
698718}
699719
0 commit comments