Erro estranho ao tentar baixar o XML de CTe autorizado.
uid: cte_3a1120d42c874b2d96181927df2ecd6a
referencia: 3e95c666-da25-11ee-928d-9457a55bde60
endpoint: https://api.nuvemfiscal.com.br/cte/cte_3a1120d42c874b2d96181927df2ecd6a/xml
Retorno: 400
“response”: “<?xml version=\"1.0\" encoding=\"UTF-8\"?>InvalidRequest
Missing x-amz-content-sha256”
Observação: O PDF da DACTE foi obtido sem problemas, somente com o XML é que ocorre este erro.
Bom dia, @nilton.
Aparentemente, você está recebendo o erro na requisição da URL de redirecionamento.
Para mais informações, favor ler o seguinte tópico:
Poxa Arimatea, não recebi nenhum email sobre esta alteração que também afeta as DACTE’s, utilizo Harbour como linguagem de programação para isto, não entendi o que devo alterar no endpoint, vou analisar a documentação do endpoit para baixar XML no CTe e ver o que mudou.
Eu olhei a documentação, utilizo o endpoint “Baixar XML do CT-e processado”
https://api.nuvemfiscal.com.br/cte/{id}/xml
Não houve alteração alguma na documentação
O que extamente devo alterar em meu programa para obter o XML? No tópico que você indicou, não deixa muito claro o que devo alterar na requisição e nem tem nada na documentação. Devo usar outro endpoint? Por favor, fico no aguardo de uma orientação.
Grato!
Complementando: Eu testei utilizando o Insomnia da mesma forma que minha aplicação o faz e o XML retornou sem problemas pelo Insomnia com código 200 ao invés de 302 ou 307 conforme tópico e não veio compactado (gzip) . O que não estou entendendo?
Grato.
Olá @nilton, a comunicação foi enviada via e-mail no dia 24/01/2024 com o assunto “Novidades: Alteração importante nos endpoints de baixa de XML e DANFE”.
Também foi publicado no link que o @arimateia postou acima. Você pode acompanhar todos os postos na categoria releases, vá na URL Tópicos etiquetados com releases e clique no ícone do sino no canto superior direito. Clique em “Acompanhando” e receberá notificação sempre que um novo tópico for criado nessa categoria.
O Insomnia já faz esse processamento automático pra você. Se quiser testar o Insomnia sem esse recurso, você tem que desabilitar o redirecionamento automático, nas configurações dele:
Da mesma forma que ele está resolvendo o gzip automaticamente.
Obrigado pelo retorno Wagner, no caso da minha aplicação em Harbour, uso a DLL da Microsoft win_oleCreateObject(“MSXML2.ServerXMLHTTP.6.0”), o que eu mudo na requisição? Não achei na documentação da MSXML2 algo como redirects. Pode me ajudar?
Eu desabilitei a opção “Follow redirects” no Insomnia para testar o response, mesmo assim foi retornado codigo 302 e o location, só não trouxe o XML, já na minha aplicação, não retorna o código 302, retorna um erro 400 com o response: “response”: “<?xml version=\"1.0\" encoding=\"UTF-8\"?>InvalidRequest
Missing x-amz-content-sha256”, não me dando a opção de obter o location para redirecionar a requisição.
Como citei anteriormente, o erro parece ser exatamente na requisição da URL de redirecionamento. Ou seja, quem está retornando o status code 400 não é a API da Nuvem Fiscal e sim o serviço da Amazon S3 ou Cloudflare R2.
Suspeito que o header “authorization” está sendo incluído indevidamente na requisição pela sua biblioteca. Poderia verificar isso através do Fiddler, Wireshark ou algum outro software similar?
Ainda, você pode colocar aqui o código exato que você usa pra fazer a requisição à API da Nuvem?
Segue o código, não sei se vai ajudar, mas as únicas informações enviada no Header são:
- Autorization Bearer
- Accept /
#include "hmg.ch"
/*
Broadcast: Transmitir
Transmite à API da Nuvem Fiscal a solicitação (endpoint) e json
(body) de acordo com o método http solicitado.
*/
function Broadcast(connection, httpMethod, apiUrl, token, operation, body, content_type, accept)
local oError, log := {=>}
local response := {"error" => false, "http_status" => 0, "ContentType" => "", "response" => "", "sefazOff" => {=>}}
local sefazOFF
try
connection:Open(httpMethod, apiUrl, false)
connection:SetRequestHeader("Authorization", "Bearer " + token)
if Empty(content_type)
content_type := ""
else
connection:SetRequestHeader("Content-Type", content_type) // Request Body Schema
endif
if !Empty(accept)
connection:SetRequestHeader("Accept", accept)
endif
if Empty(body)
try
connection:Send()
catch oError
if (oError:genCode == 0)
apiLog({"type" => "Error", "description" => "Erro em WinOle MSXML6.DLL"})
Break
else
if ("O tempo limite da opera" $ oError:description)
apiLog({"type" => "Error", "description" => oError:description + " ... Tentando mais uma vez..."})
SysWait(10) // Aguarda 10 segundos e tenta novamente
connection:Send()
else
apiLog({"type" => "Error", "description" => "Erro em Send() para API Nuvem Fiscal: " + oError:description})
Break
endif
endif
end
else
// Request Body
try
connection:Send(body)
catch oError
if (oError:genCode == 0)
apiLog({"type" => "Error", "description" => "Erro em WinOle MSXML6.DLL"})
Break
else
if ("o tempo limite da opera" $ Lower(oError:description))
apiLog({"type" => "Error", "description" => oError:description + " ... Tentando mais uma vez..."})
SysWait(10) // Aguarda 10 segundos e tenta novamente
connection:Send(body)
else
apiLog({"type" => "Error", "description" => "Erro em Send() para API Nuvem Fiscal: " + oError:description})
Break
endif
endif
end
endif
if ("image" $ content_type)
connection:WaitForResponse(70000)
else
connection:WaitForResponse(5000)
endif
catch oError
log["type"] := "Error"
log["method"] := httpMethod
log["url"] := apiUrl
log["content_type"] := iif(content_type == nil, "$$null$$", content_type)
log["accept"] := iif(accept == nil, "$$null$$", accept)
log["body"] := iif(body == nil, "$$null$$", iif("image" $ content_type, "[ ARQUIVO BINARIO DA IMAGEM ]", body))
if (oError:genCode == 0)
log["description"] := "Erro desconhecido de conexão com o site"
log["response"] := "Erro desconhecido de conexão com o site " + operation
response["response"] := "Erro de conexão com a API Nuvem Fiscal em " + operation
else
log["description"] := oError:description
log["response"] := "Erro de conexão com API Nuvem Fiscal em " + operation
response["response"] := "Erro de conexão com a API Nuvem Fiscal em " + operation + " | " + oError:description
endif
apiLog(log)
log := nil
response["error"] := true
response["ContentType"] := "text"
Break
end
if !response["error"]
response["http_status"] := connection:Status
if (response["http_status"] > 199) .and. (response["http_status"] < 300)
// Entre 200 e 299
if !Empty(connection:ResponseBody)
response["response"] := connection:ResponseBody
response["ContentType"] := "json"
endif
else // elseif (response["http_status"] > 399) .and. (response["http_status"] < 600)
if ("json" $ connection:getResponseHeader("Content-Type"))
// "application/json"
response["ContentType"] := "json"
response["response"] := connection:ResponseBody
sefazOFF := hb_jsonDecode(response["response"])
if hb_HGetRef(sefazOFF, "status") .and. hb_HGetRef(sefazOFF, "autorizacao")
sefazOFF := sefazOFF["autorizacao"]
if hb_HGetRef(sefazOFF, "motivo_status")
if "the server name cannot be resolved" $ Lower(sefazOFF["motivo_status"])
response["sefazOff"]["id"] := sefazOFF["id"]
response["sefazOff"]["codigo_status"] := sefazOFF["codigo_status"]
response["sefazOff"]["motivo_status"] := sefazOFF["motivo_status"]
elseif response["http_status"] == 500 .and. ("internal server error" $ Lower(sefazOFF["motivo_status"]))
log["type"] := "Error"
log["method"] := httpMethod
log["url"] := apiUrl
log["content_type"] := iif(content_type == nil, "$$null$$", content_type)
log["accept"] := iif(accept == nil, "$$null$$", accept)
log["body"] := iif(body == nil, "$$null$$", iif("image" $ content_type, "[ ARQUIVO BINARIO DA IMAGEM ]", body))
log["description"] := "HTTP Status: 500 - Internal Server Error, " + sefazOFF["motivo_status"]
log["response"] := iif(response["response"] == nil .or. Empty(response["response"]), "$$null$$", ;
iif((Lower(Left(operation, 6)) == "baixar"), "Response é um ARQUIVO BINÁRIO", response["response"]))
apiLog(log)
MsgStop({"Erro no servidor da api de DFe", hb_eol(), "Erro: ", sefazOFF["motivo_status"]}, "DFeMonitor " + appData:version + ": Erro HTTP:500")
turnOFF()
endif
endif
endif
else
// "application/text"
response["ContentType"] := "text"
if !Empty(connection:ResponseText)
response["response"] := connection:ResponseText
elseif !Empty(connection:ResponseBody)
response["response"] := connection:ResponseBody
else
response["response"] := "ResponseText e ResponseBody retornaram vazio, sem mensagem"
endif
endif
response["error"] := true
endif
log["type"] := "Information"
log["method"] := httpMethod
log["url"] := apiUrl
log["content_type"] := iif(content_type == nil, "$$null$$", content_type)
log["accept"] := iif(accept == nil, "$$null$$", accept)
log["body"] := iif(body == nil, "$$null$$", iif("image" $ content_type, "[ ARQUIVO BINARIO DA IMAGEM ]", body))
log["description"] := "HTTP Status: " + hb_ntos(response["http_status"]) + " - " + operation
log["response"] := iif(response["response"] == nil .or. Empty(response["response"]), "$$null$$", ;
iif((Lower(Left(operation, 6)) == "baixar"), "Response é um ARQUIVO BINÁRIO", response["response"]))
apiLog(log)
endif
return response
Parece ser uma limitação desse objeto. Algumas referências:
Seria interessante verificar em um Fiddler, como disse o Arimateia, pra ver se o IXMLHTTP está incluindo o Header Authorization no redirect. Isso não é desejado, e parece ser o que está ocorrendo.
E, infelizmente, parece que você como programador não tem muito controle sobre isso. Não há um suporte no Harbour que eles possam te orientar como fazer, ou usar uma outra biblioteca para requisição HTTP?
O Harbour é fraco em blibliotecas para API’s, mas estive pesquisando, tem outra dll da MS (WinHttp.WinHttpRequest.5.1) que estou testando, ela permite setar o redirecionamento, estou testando mas o método Option(6) não está aceitando alterar pra true, a documentação da MS também é muito ruim.
Bom, o importante é que este problema só aconteceu com um CTe, meu cliente emititu vários hoje a tarde e nenhum deles retornou aquele erro 400. Parece ser um caso de isolado de momento. Vai saber?!..
Ah, só pra informar: Estou migrando aos poucos minha aplicação com Node.JS, Tyscript, Next.JS com React. Com essas ferramentas não terei problemas com bibliotecas para me conectar com APIs.
Este tópico foi fechado automaticamente 24 horas depois da última resposta. Novas respostas não são mais permitidas.