Как вы читаете поток в промежуточном программном обеспечении и все еще можете быть в потоке следующего промежуточного программного обеспечения? - PullRequest
0 голосов
/ 08 мая 2018

Я использую промежуточное ПО для прокси для пересылки многокомпонентных данных на другую конечную точку. Я хотел бы получить некоторую информацию из потока, используя предыдущее промежуточное программное обеспечение, и все еще иметь поток, читаемый для промежуточного программного обеспечения прокси, которое следует. Есть ли шаблон потока, который позволяет мне сделать это?

function preMiddleware(req, res, next) {
  req.rawBody = '';

  req.on('data', function(chunk) {
    req.rawBody += chunk;
  });

  req.on('end', () => {
    next();
  })
}

function proxyMiddleware(req, res, next) {
  console.log(req.rawBody)
  console.log(req.readable) // false
}

app.use('/cfs', preMiddleware, proxyMiddleware)

Я хочу получить доступ к значению name <input name="fee" type='file' /> перед отправкой потоковых данных на внешнюю конечную точку. Я думаю, что мне нужно сделать это, потому что конечная точка анализирует fee в окончательном URL-адресе, и я хотел бы иметь ручку для выполнения некоторой постобработки. Я открыт для альтернативных моделей, чтобы решить эту проблему.

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Вам нужно будет иметь возможность отправлять один поток в двух разных направлениях, что будет непросто, если вы попробуете его самостоятельно - к счастью, я написал полезный модуль еще в тот день rereadable-stream , что вы могли бы использовать, и я буду использовать scramjet для поиска интересующих вас данных.

Я предполагаю, что ваши данные будут составной границей:

const {StringStream} = require('scramjet');
const {ReReadable} = require("rereadable-stream");

// I will use a single middleware, since express does not allow to pass an altered request object to next()
app.use('/cfs', (req, res, next) => {
    const buffered = req.pipe(new ReReadable());        // rewind file to 
    let file = '';                                                  
    buffered.pipe(new StringStream)                     // pipe to a StringStream
        .lines('\n')                                    // split request by line
        .filter(x => x.startsWith('Content-Disposition: form-data;'))
                                                        // find form-data lines
        .parse(x => x.split(/;\s*/).reduce((a, y) => {  // split values
            const z = y.split(/:\s*/);                  // split value name from value
            a[z[0]] = JSON.parse(z[1]);                 // assign to accumulator (values are quoted)
            return a;
        }, {}))
        .until(x => x.name === 'fee' && (file = x.filename, 1))
                                                        // run the stream until filename is found
        .run()
        .then(() => uploadFileToProxy(file, buffered.rewind(), res, next))
                                                        // upload the file using your method

});

Возможно, вам придется немного адаптировать это, чтобы оно работало в реальном сценарии. Дайте мне знать, если вы застряли или есть что-то, чтобы исправить в ответе выше.

0 голосов
/ 08 мая 2018

Я не думаю, что существует какой-либо механизм для просмотра потока без фактического удаления данных из потока или какой-либо механизм для «непрочитания» данных из потока, чтобы вернуть их обратно в поток.

Таким образом, я могу придумать несколько возможных идей:

  1. Считайте нужные данные из потока и затем вручную отправьте данные в конечную конечную точку (не используя прокси-код, ожидающий читаемый поток).

  2. Считайте поток, получите необходимые данные, если он есть, затем создайте новый читаемый поток, поместите прочитанные данные в этот читаемый поток и передайте этот читаемый поток на прокси. Точно так же, как передать его, только прокси нужно будет изучить код прокси. Возможно, вам придется создать новый req объект, который будет новым потоком.

  3. Создание преобразования потока, которое позволяет читать поток (возможно, даже изменять его) при создании нового потока, который можно передавать на прокси.

  4. Зарегистрируйте свой собственный обработчик событий data, затем приостановите поток (регистрация данных даже автоматически запускает поток, а поток вам пока не нужен), затем сразу вызовите next(). Я думаю, что это позволит вам «видеть» копию всех данных в процессе, когда промежуточное ПО прокси-сервера считывает поток, поскольку будет только несколько обработчиков событий data, один для вашего промежуточного ПО и один для промежуточного ПО прокси. Это теоретическая идея - я еще не пробовал.

...