3

I have an issue handling redirects with a custom header. A few requests to a REST-API endpoint are acknowledged with HTTP/1.1 301 Moved Permanently.

This is my code:

procedure APIRequest(const url, token: string; request, response: TStream);
var
  http: TIdHttp;
  ssl: TIdSSLIOHandlerSocketOpenSSL;
begin
  http := TIdHttp.Create(nil);
  ssl := TIdSSLIOHandlerSocketOpenSSL.Create(http);
  try
    ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
    http.IOHandler := ssl;

    http.HandleRedirects := true;

    http.Request.CustomHeaders.Clear;
    http.Request.Accept := 'application/json';
    http.Request.CustomHeaders.FoldLines := false; // without http status code 400
    http.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + token;

    try
      if request = nil then
        http.Get(url, response)
      else
        http.Post(url, request, response);
    except
      on e: EIdHTTPProtocolException do begin
        if response is TStringStream then
          (response as TStringStream).WriteString(e.ErrorMessage); // errormessage is the actual http-body
      end;
    end;
  finally
    http.Free;
  end;
end;

It works perfectly fine until it has to handle redirects. It throws following error:

HTTP/1.1 400 Authentication information is not given in the correct format. Check the value of Authorization header.

I assume the custom header gets lost while it follows the redirect.

I tried to have a look at the request header but fiddler 4 isn't tracking my process.

Does anyone have an idea how to do that? Please point me in the right direction. Thanks in advance.

Update 20190710 09:40

Okay, the custom header does not get lost. Do I need a cookie manager?

This is the log from TIdLogFile as Remy suggested:

Stat Connected.
Sent 10.07.2019 09:35:52: GET /api/v1.0/Products HTTP/1.1
Authorization: Bearer mysecrettoken
Host: mysecrethost.de
Accept: application/json
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)


Recv 10.07.2019 09:35:52: HTTP/1.1 301 Moved Permanently
Location: https://mysecretsubdomain.blob.core.windows.net/products/Products.json?sv=2018-03-28&sr=b&sig=%2F8Y4qCtsLhJUYHJVHgM2cvlyg6hLI4pLg16FEmvQzsY%3D&st=2019-07-10T07%3A20%3A52Z&se=2019-07-10T07%3A50%3A52Z&sp=r
Request-Context: appId=cid-v1:49572fba-119a-44ce-80c2-e12dd8810c9a
Date: Wed, 10 Jul 2019 07:35:52 GMT
Content-Length: 0


Stat Disconnected.
Stat Connected.
Sent 10.07.2019 09:35:52: GET /products/Products.json?sv=2018-03-28&sr=b&sig=%2F8Y4qCtsLhJUYHJVHgM2cvlyg6hLI4pLg16FEmvQzsY%3D&st=2019-07-10T07%3A20%3A52Z&se=2019-07-10T07%3A50%3A52Z&sp=r HTTP/1.1
Authorization: Bearer mysecrettoken
Host: mysecretsubdomain.blob.core.windows.net
Accept: application/json
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)


Recv 10.07.2019 09:35:52: HTTP/1.1 400 Authentication information is not given in the correct format. Check the value of Authorization header.
Content-Length: 298
Content-Type: application/xml
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: ec5b36eb-c01e-0112-69f2-36b58a000000
Date: Wed, 10 Jul 2019 07:35:52 GMT

<?xml version="1.0" encoding="utf-8"?>
<Error><Code>InvalidAuthenticationInfo</Code><Message>Authentication information is not given in the correct format. Check the value of Authorization header.
RequestId:ec5b36eb-c01e-0112-69f2-36b58a000000
Time:2019-07-10T07:35:52.8167021Z</Message></Error>
Stat Disconnected.
  • Wireshark v3.x provides a local loopback adapter (nmap) so you can track local traffic. – whosrdaddy Jul 09 '19 at 17:00
  • 1
    `TIdHTTP` should not be clearing/losing any `Request.CustomHeaders` values on a redirect. I suggest you assign one of the `TIdLog...` components to the `TIdHTTP.Intercept` property and capture the raw HTTP messages that `TIdHTTP` is actually sending/receiving back and forth. – Remy Lebeau Jul 09 '19 at 17:37
  • On a side note, consider using the `hoNoProtocolErrorException` and `hoWantProtocolErrorContent` flags in the `TIdHTTP.HTTPOptions` property instead of handling `EIdHTTPProtocolException` errors. – Remy Lebeau Jul 09 '19 at 17:39
  • @RemyLebeau I added the log from TIdLogFile – complete_stranger Jul 10 '19 at 07:42
  • It's all about the "Request-Context", isn't it? – complete_stranger Jul 10 '19 at 07:52
  • 1
    @complete_stranger you are being redirected to a completely different domain. Is it possible that `windows.net` simply does not use Bearer tokens for authentication? Or do you have to reauthenticate with the new server to get a new token? `Request-Context` is not a standard HTTP header, most user agents would just ignore it. What does `windows.net`'s REST API documentation say about it? – Remy Lebeau Jul 10 '19 at 15:58
  • Thank you very much. You are totally right. It simply does not use the Bearer token. I have to get rid off it on redirect. A simple GET on the "Location" of the redirect gets me the file. How do I do that on the initial call? – complete_stranger Jul 11 '19 at 06:45
  • It seems that OnRedirect with "if Sender is TIdHttp then (Sender as TIdHttp).Request.CustomHeaders.Clear;" does the trick. – complete_stranger Jul 11 '19 at 06:50

0 Answers0