<p>request.get falha com "O conteúdo do cabeçalho contém caracteres inválidos"</p>

Criado em 8 mar. 2016  ·  20Comentários  ·  Fonte: request/request

Experimente isto:

require('request').get('http://www.test.com/אבגד.pdf');

Depois de alguns milissegundos, isso trava com TypeError('The header content contains invalid characters')

Agora, se eu embrulhar em encodeURI - é bem-sucedido.
Mas se recebermos urls de uma fonte externa - eles podem ou não ser codificados. Existe algum tipo de mecanismo embutido para lidar com isso? (Além de fazer encodeURI(decodeURI(url)) )

Comentários muito úteis

O fato é que, embora seja fácil consertar isso, request deve capturar o erro e propagá-lo por meio dos manipuladores de erros. Atualmente, ele é lançado como uma exceção não detectada que pode causar travamentos de servidor muito graves, dos quais você nunca pode se recuperar porque não pode tentar / detectar manualmente.

Portanto, eu diria que este é um bug bastante grave em request . O erro precisa ser propagado.

Todos 20 comentários

Além disso, não encontrei maneira de detectar essa exceção. Não importa se há um try-catch ou .on('error', ...

Estou recebendo o mesmo erro ao usar o Node versão 0.12.12 e superior. O mesmo código funciona com 0.12.9:

_http_outgoing.js:355
      throw new TypeError('The header content contains invalid characters');
            ^
TypeError: The header content contains invalid characters
    at ClientRequest.OutgoingMessage.setHeader (_http_outgoing.js:355:13)
    at new ClientRequest (_http_client.js:101:14)
    at Object.exports.request (http.js:49:10)
    at Object.exports.request (https.js:136:15)
    at Request.start (//application/node_modules/request/request.js:747:30)
    at Request.end (/application/node_modules/request/request.js:1381:10)
    at end (/application/node_modules/request/request.js:575:14)
    at Immediate._onImmediate (/application/node_modules/request/request.js:589:7)
    at processImmediate [as _immediateCallback] (timers.js:367:17)

Acontece que, no meu caso, eu estava enviando uma quebra de linha em um cookie. Eu tive que removê-lo.

Não, meu caso é simples, sem cookies, sem cabeçalhos adicionais.

Eu recebo o mesmo problema, usando https://github.com/matt-major/do-wrapper ao tentar acessar as informações da minha conta.

_http_outgoing.js:348
    throw new TypeError('The header content contains invalid characters');
    ^

TypeError: The header content contains invalid characters
    at ClientRequest.OutgoingMessage.setHeader (_http_outgoing.js:348:11)
    at new ClientRequest (_http_client.js:85:14)
    at Object.exports.request (http.js:31:10)
    at Object.exports.request (https.js:197:15)
    at Request.start (/home/pierre/Documents/freelance/upwork/dosh/node_modules/do-wrapper/node_modules/request/request.js:746:30)
    at Request.write (/home/pierre/Documents/freelance/upwork/dosh/node_modules/do-wrapper/node_modules/request/request.js:1345:10)
    at end (/home/pierre/Documents/freelance/upwork/dosh/node_modules/do-wrapper/node_modules/request/request.js:560:16)
    at Immediate._onImmediate (/home/pierre/Documents/freelance/upwork/dosh/node_modules/do-wrapper/node_modules/request/request.js:588:7)
    at processImmediate [as _immediateCallback] (timers.js:383:17)

O fato é que, embora seja fácil consertar isso, request deve capturar o erro e propagá-lo por meio dos manipuladores de erros. Atualmente, ele é lançado como uma exceção não detectada que pode causar travamentos de servidor muito graves, dos quais você nunca pode se recuperar porque não pode tentar / detectar manualmente.

Portanto, eu diria que este é um bug bastante grave em request . O erro precisa ser propagado.

Eu investi boas 2h agora tentando consertar esse problema, para o qual escrever um caso de teste de reprodução era bem trivial.
Cheguei à conclusão de que, com meu conhecimento atual da base de código, ele não pode ser corrigido, a menos que a validação seja adicionada a https://github.com/request/caseless , o que, a propósito, me custou sólidos 20-30 minutos para descobrir, na verdade self.setHeader . Esse comportamento não está documentado em caseless , nem é óbvio pelo nome que ele lida com a configuração e obtenção de cabeçalhos, e nem é esperado que caseless.httpify(self, self.headers) faria um monkey patch para o objeto com setHeader .

try/catch no ponto onde o objeto de solicitação é criado é praticamente impossível de recuperar porque não há uma maneira simples de abortar a execução nesse momento. self.req.end ainda será chamado e, se a chamada for removida, nenhum dos comportamentos subsequentes será acionado (novamente, por razões não óbvias).

Para ser franco, me assusta que meus serviços de produção dependem de uma biblioteca com um arquivo principal de 1.4k linhas em que a lógica é tão complicada que algo tão fácil quanto propagar um erro de um try / catch é praticamente impossível sem estudar profundamente todo o máquina de eventos rube goldberg. É hora de se afastar disso.

Isso também afeta o Nó 5.6.0 e acima, que tem uma validação de cabeçalho mais estrita: https://github.com/nodejs/node/blob/v5.6.0/CHANGELOG.md

Corrigido aqui https://github.com/request/request/pull/2164

Dê uma olhada no teste sobre como lidar com o erro em seu código.

Parece que o tratamento do erro é como sempre, com um evento .on('error', ... . Boa!

Isso tornará o request mais à prova de balas, sem travar o aplicativo em coisas estúpidas no futuro.

Bem, agora me sinto um idiota incrivelmente bobo.
Na verdade, eu tinha exatamente a mesma solução pronta e meus testes falhavam constantemente.
Acontece que no meu 'caso de teste trivial' esqueci de chamar t.end() .

Minhas desculpas, da próxima vez vou publicar meu branch e pedir feedback.

@TimBeyer sem problemas, a versão 2.71 foi publicada com a correção: +1:

@simov A versão 2.71 corrigiu o problema parcialmente para mim. Aqui está o meu cenário. Estou enviando uma solicitação de postagem e obtendo dados como blocos,

request({
              method: 'POST',
              headers: {
                 'test': 'אבגד'
              },
              uri: apiUrl,
              qs: req.query,
              json: req.body,
              gzip: true
            }
            , function(error, response, body) {
               console.log('callback')
            })
            .on('response', function (response) {
             console.log(response)
            })
            .on('error', function (err) {
              console.log(err);
            });

Quando eu executo isso, recebo um erro

return self.req.write.apply(self.req, arguments)
                 ^

TypeError: Cannot read property 'write' of undefined
    at Request.write (/Users/muhammadkhurrumqureshi/Workspace/www/node_modules/request/request.js:1385:18)
    at end (/Users/muhammadkhurrumqureshi/Workspace/www/node_modules/request/request.js:565:18)
    at Immediate._onImmediate (/Users/muhammadkhurrumqureshi/Workspace/www/node_modules/request/request.js:594:7)
    at processImmediate [as _immediateCallback] (timers.js:383:17)

Você pode gentilmente ajudar nisso?

@khurrumqureshi corrigido aqui https://github.com/request/request/pull/2165 : +1:

Basicamente, a mesma verificação do método end . A razão é porque start está sendo chamado na linha anterior e até agora não era esperado que ocorresse. Quando sua solicitação tem um corpo write é chamada antes de end , daí o erro.

@simov : +1:

Mesmo aqui.

TypeError: The header content contains invalid characters
    at ClientRequest.OutgoingMessage.setHeader (_http_outgoing.js:348:11)
    at new ClientRequest (_http_client.js:85:14)
    at Object.exports.request (http.js:31:10)
    at Object.exports.request (https.js:199:15)
    at Request.start (/home/mymodule/node_modules/request/request.js:744:32)
    at Request.end (/home/mymodule/node_modules/request/request.js:1433:10)
    at end (/home/mymodule/node_modules/request/request.js:566:14)
    at Immediate.<anonymous> (/home/mymodule/node_modules/request/request.js:580:7)
    at runCallback (timers.js:570:20)
    at tryOnImmediate (timers.js:550:5)

Os cabeçalhos de resposta são:

headers:
      { 'x-backside-transport': 'OK OK,FAIL FAIL',
        connection: 'close',
        'transfer-encoding': 'chunked',
        'x-dp-local-file': 'true',
        'x-client-ip': '127.0.0.1,176.31.126.162',
        'x-global-transaction-id': '145630106',
        date: 'Tue, 08 Nov 2016 01:03:59 GMT',
        'www-authenticate': 'Basic realm="Gateway(Log-in)"',
        'x-archived-client-ip': '127.0.0.1',
        'content-type': '',
        'x-dp-tran-id': 'gateway' },
     rawHeaders:
      [ 'X-Backside-Transport',
        'OK OK,FAIL FAIL',
        'Connection',
        'close',
        'Transfer-Encoding',
        'chunked',
        'x-dp-local-file',
        'true',
        'X-Client-IP',
        '127.0.0.1,176.31.126.162',
        'X-Global-Transaction-ID',
        '145630106',
        'Date',
        'Tue, 08 Nov 2016 01:03:59 GMT',
        'WWW-Authenticate',
        'Basic realm="Gateway(Log-in)"',
        'X-Archived-Client-IP',
        '127.0.0.1',
        'Content-Type',
        '',
        'X-DP-Watson-Tran-ID',
        'gateway' ]

Os cabeçalhos da solicitação são:

{ accept: 'application/json',
     authorization: 'Basic ...g==',
     referer: 'https://hostname.com/classify?text=%20So%20happy%20with%20this%20👍👍👍👍👍',
     host: 'gateway.myclass.net' }

Como você pode ver, a solicitação contém 3 vezes um caractere especial <U+1F44D> .

Pode ser esse o problema?

Parece que o módulo node.js https não o suporta.

Apenas no caso de outra pessoa ter o mesmo problema que eu - eu tive esse erro com aws-sdk e isso estava me deixando louco por horas. Acabou sendo um caractere PrvScan \u001b[5~ que, por algum motivo, estava escondido em meu arquivo ~/.aws/credentials , que se propagou para o cabeçalho de autorização usado pelas solicitações da AWS. O erro só apareceu na minha máquina com Windows 7, então provavelmente foi algo relacionado a como o arquivo de credenciais foi recuperado da minha conta da AWS e alguma codificação de caracteres do Windows. Também não estava visível quando cat ing o arquivo de credenciais, mas tornou-se visível assim que abri o arquivo com vi .

Sim, apenas tive o mesmo problema. Levei algumas horas para descobrir, devo admitir.
estava usando MINGW64 (Git Bash) em uma máquina Windows. Tentei executar o mesmo script usando o Node no prompt de comando .... e olá .... funcionou ????

Acabei de encontrar o mesmo erro e não consigo encontrar uma maneira de detectá-lo. Estou construindo um proxy de imagem, então não posso controlar o que o outro servidor está retornando. Como posso evitar o rodízio de todo o servidor em produção ?!

Tive o mesmo problema, começou a funcionar quando troquei o "set" por "auth". Por exemplo:

it('ERROR, Wrong GET request', (done)=>{
    request(server).get("/api/")
    .set('Authorization', 'Bearer ' + tokenKey)
    .then(res=>{
        expect(res.statusCode).to.equal(404);
        done()
    }).catch(err=>done(err))
})

CONSOLE RES: ERROR, Wrong GET request:
TypeError [ERR_INVALID_CHAR]: Caractere inválido no conteúdo do cabeçalho ["Autorização"]

Depois de alterar o código para:

it('ERROR, Wrong GET request', (done)=>{
    request(server).get("/api/")
    .auth('Authorization', 'Bearer ' + tokenKey) //**<---here is the change**
    .then(res=>{
        expect(res.statusCode).to.equal(404);
        done()
    }).catch(err=>done(err))
})

CONSOLE RES: OKI; p

Esta página foi útil?
0 / 5 - 0 avaliações