Post problems with Indy TIdHTTP
Asked Answered
B

2

9

I am having issues posting to Amazon's SES Service using Indy's TIdHTTP.

Here is an example of the code i am using:

procedure TMainFrm.btnAmazonSESClick(Sender: TObject);
var
  SSLHandler: TIdSSLIOHandlerSocket;
  HttpClient: TIdHTTP;  
  Params: TStringStream;
begin
  SSLHandler := TIdSSLIOHandlerSocket.Create(Self);
  HttpClient := TIdHTTP.Create(Self);  
  Params := TStringStream.create('');
  try
    with SSLHandler do
      SSLOptions.Method := sslvSSLv3
    with HttpClient do
    begin
      IOHandler := SSLHandler;
      AllowCookies := True;
      HandleRedirects := True;
      HTTPOptions := [hoForceEncodeParams];
      Request.ContentType := 'application/x-www-form-urlencoded';
    end;

    PageMemo.Text := HttpClient.Post('https://email.us-east-1.amazonaws.com?Action=VerifyEmailAddress&AWSAccessKeyId=012Some123Key46&EmailAddress=test@test%2Ecom', Params);

  finally
    SSLHandler.Free;
    HttpClient.Free; 
    Params.Free;
  end;
end;

Result

  • Under Indy 10.5.7 I get the error: HTTP/1.1 404 Not Found

  • Under Indy 9.0.14 I get the error: Socket Error # 11004

Debugging Trials

  • This same demo can successfully GET the HTML from an HTTPS web page.

  • If i paste the URL above into a browser it displays the expected XML result.

I would appreciate any advice on the cause.

Brachy answered 14/10, 2011 at 2:53 Comment(5)
I believe you need the SSL dll's in the same folder as the application or in windows system32 folder... let me know if you want me to upload the ones I have somewhere, my version is libeay32.dll 1.0.0.4 and ssleay32.dll 1.0.0.4Golfer
You do not POST any Params, are you sure you want to communicate with webservice this way?Reductase
@PrematureOptimization everything after ? is param name=value, in this case Action=VerifyEmailAddress&AWSAccessKeyId=012Some123Key46&EmailAddress=test@test%2EcomGolfer
@Dorin Duminica, not really. query-string <> form-dataReductase
@DorinDuminica: Thanks, I have included the latest SSL DLL's in the folderBrachy
T
3

This post is just an incomplete wild guess.

Maybe Remy might help you to correct it. With the following code I'm getting HTTP/1.1 400 Bad Request but I'm not wondering because the API reference talks about Common Query Parameters where is at least required the digital signature you'll create for the request what I don't know how to do.

I can't test this at all because I have no account there. But I think the

procedure TForm1.Button1Click(Sender: TObject);
var
  HTTPClient: TIdHTTP;
  Parameters: TStrings;
  SSLHandler: TIdSSLIOHandlerSocketOpenSSL;

begin
  SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  HTTPClient := TIdHTTP.Create(nil);
  Parameters := TStringList.Create;

  try
    SSLHandler.SSLOptions.Method := sslvSSLv3;
    SSLHandler.SSLOptions.Mode := sslmUnassigned;

    HTTPClient.IOHandler := SSLHandler;
    HTTPClient.HTTPOptions := [hoForceEncodeParams];
    HTTPClient.Request.ContentType := 'application/x-www-form-urlencoded';

    Parameters.Add('Action=VerifyEmailAddress');
    Parameters.Add('[email protected]');
    Parameters.Add('AWSAccessKeyId=012Some123Key46');
    Parameters.Add('SignatureVersion=2');
    Parameters.Add('Expires='); // ???
    Parameters.Add('Signature='); // ???

    PageMemo.Text := HTTPClient.Post('https://email.us-east-1.amazonaws.com', Parameters);

  finally
    SSLHandler.Free;
    HTTPClient.Free; 
    Parameters.Free;
  end;
end;
Traps answered 14/10, 2011 at 14:45 Comment(6)
Thanks I will try that, though I cannot see why I should get a different result between Indy and pasting the same URL into the browser. IOW surely if the problem is due to parameters i should receive their XML failure result?!?Brachy
@Xaz, for instance Firefox displays the content even if he get HTTP 400 Bad Request error. E.g. Internet Explorer tell you that bad request happened and doesn't display the XML content response, Indy works the same, create the error message and throw away the content. The request from your example has wrong parameters; namely IncompleteSignature what gives you as described in the table HTTP Status Code = 400 (bad request).Traps
Thank you for filling in the gaps in my understanding. I am making good progress now.Brachy
@TLama: TIdHTTP does not throw away the response content if an HTTP error occurs. It exposes it as properties of the raised EIdHTTPProtocolException exception instead.Desolate
"I cannot see why I should get a different result between Indy and pasting the same URL into the browser" - if you paste https://email.us-east-1.amazonaws.com?Action=VerifyEmailAddress&AWSAccessKeyId=012Some123Key46&EmailAddress=test@test%2Ecom into a browser, it is going to send a GET request, not a POST request, so do the same in Indy, eg: PageMemo.Text := HttpClient.Get('https://email.us-east-1.amazonaws.com?Action=VerifyEmailAddress&AWSAccessKeyId=012Some123Key46&EmailAddress=test@test%2Ecom');. Otherwise, put the name=value pairs into a TStringList and Post() that.Desolate
"required the digital signature you'll create for the request what I don't know how to do" - this is explained in Amazon's documentation: Signature Version 4 Signing Process.Desolate
S
0

Basically, you need to use the right library, i.e.:

For Indy 10.5.7 use openssl-1.0.1e-i386-win32 or openssl-1.0.1e-x64_86-win64 from http://indy.fulgan.com/SSL/ You may want to download an ssl demo from: http://indy.fulgan.com/ZIP/

Regards

Jose

Shaver answered 12/11, 2013 at 15:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.