Error on TIdHTTP on Setting Host and Port at Runti

2019-08-03 18:19发布

I am trying to use an SMS API for Delphi from http://www.human.com.br but I get an 'access violation' error when the component tries to set the host and port of the webservice after creating an instance of Indy's TIdHTTP.

host := TidHTTP.Create; 
host.Socket.Port := 80; // error right here!
host.Socket.Host := 'system.human.com.br';
uri := TidURI.Create();

The original component was created in Indy60 and I have Indy170, so the was no Socket between host and Port and I had to put it.

What is wrong? I tried to put the component directly on the form and in the button code I did the Socket settings and I get the same error too!


The send method they use is this:

 data := TIdMultiPartFormDataStream.Create;
 host.Request.ContentType := 'application/x-www-form-urlencoded';
 host.Post(strSMStext , data);

1条回答
再贱就再见
2楼-- · 2019-08-03 19:09

The Socket property is a special property that provides easier access to socket-specific functionality when the current IOHandler property value points at a TIdIOHandlerSocket descendant component. It is nil otherwise. You should NOT be setting the Socket.Host and Socket.Port properties directly. TIdTCPClient.Connect() handles that internally for you. To set a Host/Port, you need to use the TIdTCPClient.Host and TIdTCPClient.Port properties instead. However, TIdHTTP is an exception to that rule, because TIdHTTP sets the Host/Port properties internally for you based on the URL you pass to it, eg:

host := TidHTTP.Create; 
host.Get('http://system.human.com.br/', ...); // <-- sets Host and Port for you!

host := TidHTTP.Create; 
host.Post('http://system.human.com.br/', ...); // <-- sets Host and Port for you!

So DO NOT set the Host/Port properties manually at all. That has always been true in every Indy version that has a TIdHTTP component.

Posting a TIdMultiPartFormDataStream object forces the Content-Type header to be multipart/form-data. You cannot override that. Trying to send MIME-encoded data using application/x-www-form-urlencoded is just plain wrong. If you really want to send application/x-www-form-urlencoded data, you need to post a TStrings object instead, eg:

data := TStringList.Create;
data.Add('name=value');
...
host.Post(strSMStext , data);

When posting a TIdMultipartFormDataStream or a TStrings, let TIdHTTP.Post() decide which Content-Type value to use, don't set it manually.

Looking at the library code you provided a link to, the following changes need to be made:

  1. Remove the assignment of the http.Port and http.Host properties from the TSMSSender constructor.

  2. in TSMSSender.SimpleSend(), prepend the desired Host to the URL being created:

    //StrEnvio := '/GatewayIntegration/msgSms.do?dispatch=send' +
    StrEnvio := 'http://system.human.com.br/GatewayIntegration/msgSms.do?dispatch=send' +
    
  3. in TSMSSender.MultipleSend(), remove the assignment of the http.Request.ContentType property.

查看更多
登录 后发表回答