2013-06-28 3 views
0

Я написал простую службу обработки изображений, которая использует узел gm для изображения из потока ответов HTTP. Если я использую стандартную передачу-кодировку nodejs: chunked, все работает нормально. Но, как только я попытаюсь добавить реализацию длины содержимого, nodejs зависает от ответа или я получаю ошибки несоответствия длины содержимого.nodejs gm content-length реализация зависает браузер

Вот суть кода в вопросе (переменные были опущены из-за, например):

var image = gm(response); 
    // gm getter used to get origin properties of image 
    image.identify({bufferStream: true}, function(error, value){ 
     this.setFormat(imageFormat) 
     .compress(compression) 
     .resize(width,height); 

     // instead of default transfer-encoding: chunked, calculate content-length 
     this.toBuffer(function(err, buffer){ 
     console.log(buffer.length); 
     res.setHeader('Content-Length', buffer.length); 
     gm(buffer).stream(function (stError, stdout, stderr){ 
      stdout.pipe(res); 
     }); 
     }); 
    }); 

Это будет выплюнуть нужное изображение и длину контента, который выглядит хорошо, но браузер будет висеть предлагая что есть некоторая несоответствие или что-то еще неправильное. Я использую node gm 1.9.0.

Я видел аналогичные сообщения о реализации длины узла nodejs gm, но я еще не видел, чтобы кто-нибудь отправлял эту проблему.

Заранее спасибо.

+1

Рекомендуется использовать 'buffer.byteLength', а не' length'. Основная проблема * появляется * как проблема в модуле Stream узла (в частности, 'ReadableStream'), в основном, если ожидаемая длина (так что в вашем случае' Content-Length') больше, чем фактическое содержимое потока, которое он вечно вешает по этим дополнительным данным. – James

ответ

0

В итоге я изменил свой подход. Вместо использования this.toBuffer() я сохраняю новый файл на диске, используя this.write (имя_файла, обратный вызов), затем читаю его с помощью fs.createReadStream (имя_файла) и связывает его с ответом. Что-то вроде:

var filePath = './output/' + req.param('id') +'.' + imageFormat; 
this.write(filePath, function (writeErr) { 
    var stat = fs.statSync(filePath);       
    res.writeHead(200, { 
    'Content-Type': 'image/' + imageFormat, 
    'Content-Length': stat.size 
    }); 

    var readStream = fs.createReadStream(filePath); 
    readStream.pipe(res); 

    // async delete the file from filesystem 
    ... 
}); 

Вы в конечном итоге получить все заголовки, которые необходимы в том числе и ваша новый контент длиной, чтобы вернуться к клиенту.