Jump to content
GillesL.

SslHttpClient Post problem

Recommended Posts

Can someone point me out in the right direction please. I used the following code in 2 different programs. One works the other fails because the "Document" file does not get created...

 

const Document : string = 'c:\temp\rcvdata.txt';

 

function TForm5.PostURL(URL, HeaderKey, HeaderValue, Data: string): string;
var S: TStringList;
begin
  if FileExists(Document) then
    DeleteFile(Document);
  S:= TStringList.Create;
  try
    if HeaderKey <> '' then
    begin
      SslHttpCli1.ExtraHeaders.Add(HeaderKey + ': ' + HeaderValue);
    end;
    SslHttpCli1.SendStream := TMemoryStream.Create;
    SslHttpCli1.SendStream.Write(Data[1], Length(Data));
    SslHttpCli1.SendStream.Seek(0, 0);
    SslHttpCli1.RcvdStream      := TMemoryStream.Create;  //not to sure about this see HTTPDocBegin
    SslHttpCli1.URL             := Trim(URL);
    SslHttpCli1.ContentTypePost := 'application/json';
    SslHttpCli1.Post;
    S.LoadFromFile(Document);
    Result:= S.Text;
    Memo1.Lines.Add('DATA SENT:');
    Memo1.Lines.Add(Data);
    Memo1.Lines.Add('RESPONSE:');
    Memo1.Lines.Add(Result);
  finally
    S.Free;
  end;
end;

 

procedure TForm5.SslHttpCli1BeforeHeaderSend(Sender: TObject; const Method: string;
  Headers: TStrings);
begin
  Memo1.Lines.Add('HEADERS:');
  Memo1.Lines.add(Headers.text);
end;

 

procedure TForm5.SslHttpCli1DocBegin(Sender: TObject);
begin
  FByteCount:= 0;
  SslHttpCli1.RcvdStream := TFileStream.Create(Document, fmCreate);
end;

 

procedure TForm5.SslHttpCli1DocData(Sender: TObject; Buffer: Pointer; Len: Integer);
begin
  Inc(FByteCount, Len);
end;

 

procedure TForm5.SslHttpCli1DocEnd(Sender: TObject);
begin
  if Assigned(SslHttpCli1.RcvdStream) then
  begin
    SslHttpCli1.RcvdStream.Free;
    SslHttpCli1.RcvdStream := nil;
  end;
end;


 

Share this post


Link to post

Could it be in write permissions?

Did you try to run the programm elevated?

Share this post


Link to post

You don't say what errors or exceptions are reported, so no idea whether the problem is the client or server.

 

Your code is the old way of doing this, recent versions of ICS have a new TSslHttpRest component derived from TSslHttpCli that handles all send and receive streams internally (and SSL context),, and has logging built in. 

 

There is a new OverbyteIcsHttpRestTst sample that should allow you test your request and see the result, also the OverbyteIcsSslHttpRest unit itself has several example of using TSslHttpRest to access Google, Twitter, Microsoft and other REST APIs, the code for sending a Json email is as simple as::

 

HttpRest.RestParams.Clear;
HttpRest.RestParams.AddItem('raw', IcsBase64UrlEncode(Content));
HttpRest.RestParams.PContent := PContBodyJson;
HttpRest.ServerAuth := httpAuthBearer;
HttpRest.AuthBearerToken := FAccToken;
HttpRest.DebugLevel := FDebugLevel;
StatCode := HttpRest.RestRequest(httpPOST, EmailURL, False, '');
FResponseRaw := HttpRest.ResponseRaw;
FResponseJson := HttpRest.ResponseJson;
 

This is a sync request, so does not return until the request is done, but the third boolean argument makes it async.  No events are needed, you write ResponseRaw to a file if you really need it saved.

 

Angus

 

  • Like 1

Share this post


Link to post

 The problem was with th TSSLContext. I duplicated the settings from the sample code and everything worked. The issue was in the SSLOptions I am not sure which one was causing the problem:

[sslOpt_MICROSOFT_SESS_ID_BUG,sslOpt_NETSCAPE_CHALLENGE_BUG,sslOpt_NETSCAPE_REUSE_CIPHER_CHANGE_BUG,sslOpt_MICROSOFT_BIG_SSLV3_BUFFER,sslOpt_SSLEAY_080_CLIENT_DH_BUG,sslOpt_TLS_D5_BUG,sslOpt_TLS_BLOCK_PADDING_BUG,sslOpt_TLS_ROLLBACK_BUG,sslOpt_NO_SSLv2,sslOpt_NO_SSLv3,sslOpt_NETSCAPE_CA_DN_BUG,sslOpt_NETSCAPE_DEMO_CIPHER_CHANGE_BUG]

I do appreciated the suggestion about using Rest instead and I will rewrite my code to do so. Thanks for the response.

Share this post


Link to post

With the TSslHttpRest component, you don't need an SslContext, you just set HttpRest.SslCliSecurity to one of the 14 TSslCliSecurity types, like sslCliSecTls12 for TLS/1.2 or better, and all the context options are set.  other options force TLS/1.0 is you want to check is old stuff is supported, etc. 

 

BTW, recommend you use TSslHttpRest from V8.65 in the overnight zip, it has a large number of improvements over V8.64, and will be finally released next week.

 

Angus

 

Share this post


Link to post

First app migration to Rest was easy and works. One issue but I think it is server side. Working on 2d app, looks good so far. So much easier! Thanks for the help.

Share this post


Link to post

There are more authentication methods in newer ICS versions, not sure which method you are using, but you can still add your own header the same as your old application, and do use the logging event, makes debugging so much easier.

 

Angus

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×