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);
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:
Remove the assignment of the http.Port
and http.Host
properties from the TSMSSender
constructor.
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' +
in TSMSSender.MultipleSend()
, remove the assignment of the http.Request.ContentType
property.