IdHttp Just Get Response Code
Asked Answered
D

2

10

I'm using idhttp (Indy) to do some website checking. All I want it to do is check the response code from the server after my request has been sent, I don't want to actually have to receive the HTML output from the server as I'm only monitoring for a 200 OK code, any other code meaning there is an issue of some form.

I've looked up idhttp help documents and the only way I could see to possible do this would be to assign the code to a MemoryStream and then just clear it straight away, however that isn't very efficient and uses memory that isn't needed. Is there a way to just call a site and get the response but ignore the HTML sent back that is more efficient and doesn't waste memory?

Currently the code would look something like this. However this is just sample code which I haven't tested yet, I'm just using it to explain what I'm trying to do.

Procedure Button1Click(Sender: TObject);

var
http : TIdHttp;
s : TStream;
url : string;
code : integer;

begin 

   s := TStream.Create();
   http := Tidhttp.create();
   url := 'http://www.WEBSITE.com';

   try

    http.get(url,s);
    code := http.ResponseCode;
    ShowMessage(IntToStr(code));

   finally

   s.Free();
   http.Free();

end;
Defrayal answered 10/2, 2011 at 20:11 Comment(0)
S
16

TIdHTTP.Head() is the best option.

However, as an alternative, in the latest version, you can call TIdHTTP.Get() with a nil destination TStream, or a TIdEventStream with no event handlers assigned, and TIdHTTP will still read the server's data but not store it anywhere.

Either way, also keep in mind that if the server sends back a failure response code, TIdHTTP will raise an exception (unless you use the AIgnoreReplies parameter to specify specific response code values you are interested in ignoring), so you should account for that as well, eg:

procedure Button1Click(Sender: TObject);
var
  http : TIdHttp;
  url : string;
  code : integer;
begin
  url := 'http://www.WEBSITE.com';
  http := TIdHTTP.Create(nil);
  try
    try
      http.Head(url);
      code := http.ResponseCode;
    except
      on E: EIdHTTPProtocolException do
        code := http.ResponseCode; // or: code := E.ErrorCode;
    end;
    ShowMessage(IntToStr(code));
  finally
    http.Free;
  end;
end; 

procedure Button2Click(Sender: TObject);
var
  http : TIdHttp;
  url : string;
  code : integer;
begin
  url := 'http://www.WEBSITE.com';
  http := TIdHTTP.Create(nil);
  try
    try
      http.Get(url, nil);
      code := http.ResponseCode;
    except
      on E: EIdHTTPProtocolException do
        code := http.ResponseCode; // or: code := E.ErrorCode;
    end;
    ShowMessage(IntToStr(code));
  finally
    http.Free;
  end;
end;

UPDATE: to avoid the EIdHTTPProtocolException being raised on failures, you can enable the hoNoProtocolErrorException flag in the TIdHTTP.HTTPOptions property:

procedure Button1Click(Sender: TObject);
var
  http : TIdHttp;
  url : string;
  code : integer;
begin
  url := 'http://www.WEBSITE.com';
  http := TIdHTTP.Create(nil);
  try
    http.HTTPOptions := http.HTTPOptions + [hoNoProtocolErrorException];
    http.Head(url);
    code := http.ResponseCode;
    ShowMessage(IntToStr(code));
  finally
    http.Free;
  end;
end; 

procedure Button2Click(Sender: TObject);
var
  http : TIdHttp;
  url : string;
  code : integer;
begin
  url := 'http://www.WEBSITE.com';
  http := TIdHTTP.Create(nil);
  try
    http.HTTPOptions := http.HTTPOptions + [hoNoProtocolErrorException];
    http.Get(url, nil);
    code := http.ResponseCode;
    ShowMessage(IntToStr(code));
  finally
    http.Free;
  end;
end;
Solidstate answered 10/2, 2011 at 21:33 Comment(6)
I have just been playing around with this code more. All this runs inside a thread, however if there is anything other than a 200 code reply e.g. 404, 302 etc or a socket error it causes the thread to exit.Defrayal
Any response code that does not indicate a successful retreive will raise an exception. If your thread is not handling exceptions, or at least not handling the particular exception type that is actually raised, then yes, the thread will exit (and the TThread.FatalException property will be set). In my example, it is only handling EIdHTTPProtocolException exceptions. Expand your thread code to handle other types of exceptions if needed.Solidstate
@RemyLebeau What if we receive a 'Continue' 100 response? We will need to try again, right?Alchemize
TIdHTTP handles 100 internally for you. And no, it is not an indication to retry. 100 is only used if a client sends an Expect: 100-Continue header, which allows the client to send just the request headers and then wait for 100 before sending a POST body. That way, no bandwidth is wasted if the server decides to reject the request.Solidstate
Some URLs return "false" 404 errors if I use http.Head. It is safer to go with http.Get(url, nil)Mammillary
@Andrzej then those servers are flawed and not following the HTTP spec correctly.Solidstate
M
8

Try with http.head() instead of http.get().

Mesh answered 10/2, 2011 at 20:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.