by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Sep 05 05:55
    ZGabrovski opened #321
  • Aug 21 18:37
    rlebeau commented #320
  • Aug 21 18:34
    rlebeau commented #320
  • Aug 21 18:34
    rlebeau closed #320
  • Aug 21 18:33
    rlebeau commented #320
  • Aug 21 16:31
    zencode1 edited #320
  • Aug 21 16:29
    zencode1 opened #320
  • Aug 20 18:31
    rlebeau assigned #319
  • Aug 20 18:31
    rlebeau labeled #319
  • Aug 20 18:31
    rlebeau labeled #319
  • Aug 20 18:31
    rlebeau labeled #319
  • Aug 20 18:30
    rlebeau opened #319
  • Aug 18 07:51
    xjikka commented #299
  • Aug 18 07:50
    xjikka commented #299
  • Aug 17 21:04
    xjikka commented #299
  • Aug 17 20:27
    SlMaker commented #299
  • Aug 17 17:13
    xjikka commented #299
  • Aug 17 16:30
    rlebeau commented #299
  • Aug 17 07:14
    xjikka commented #299
  • Aug 17 07:14
    xjikka commented #299
Sergey
@icegood

Hi, Remy. After migration from Indy9 to Indy10 i found one more issue:
our web server always requires Content-Length in header of HTTP Post method. It doesn't matter whether ContentStream is assigned or not.
In Indy10 code i see that in case when ASource is not assigned then header is not added:
if Assigned(ARequest.Source) then begin
ARequest.ContentLength := ARequest.Source.Size;
end else begin
ARequest.ContentLength := -1; => leads to omitting of 'Content-Length'
end;
For this moment i have workaround via adding 'Content-Length' to CustomHeaders (value is '0', works great!). Moreover, seems Indy9 always added 'Content-Length'!

Please, consider adding 'Content-Length' always in library as well. At least i see it is a widespread issue:
http://stackoverflow.com/questions/19227142/http-status-code-411-length-required

perverez
@perverez
Hi, I have problem with GStack.LocalAddress. When I call this function on Windows Server 2016 (ver. 1607, build 14393, virtualized), error occured. Function Stub_GetAdaptersAddresses() returns any pointer, but GetAdaptersAddresses() return error 127. Some solution?
Remy Lebeau
@rlebeau
@icegood Indy 9 does not allow the source stream to be nil. If the request is POST or PUT, it assumes a valid stream and will crash accessing the Size if the stream is nil. Indy 9 also omitted the Content-Length for all requests other than POST and PUT. Indy 10 allows a nil source stream, but the real question is - why are you posting a nil source stream to begin with? You really shouldn't be. That being said, I have checked in a fix to generate a 'Content-Length: 0' header when the source stream is nil for POST and PUT requests.
Remy Lebeau
@rlebeau
@perverez error 127 is ERROR_PROC_NOT_FOUND. GetAdaptersAddresses() should not be returning that error, it comes from GetProcAddress() instead. Did you check to make sure Indy is able to load iphlpapi.dll correctly before calling GetAdaptersAddresses()?
perverez
@perverez
Hi, I check all - DLL is loaded (hIpHlpApi > 0), GetAdaptersAddresses is assigned, function Stub_GetAdaptersAddresses not calling Impl_GetAdaptersAddresses. The problem does not occur in the physical network interface cards, only in Hyper-V.
Remy Lebeau
@rlebeau
@perverez Then that is an OS issue, not an Indy issue. Ask Microsoft why GetAdaptersAddresses() returns 127 in Hyper-V (apparently you have already tried to?). It is likely a driver bug or something like that.
Remy Lebeau
@rlebeau
@perverez does GetAdaptersInfo() exhibit the same problem? If I have Indy treat ERROR_PROC_NOT_FOUND the same as ERROR_NOT_SUPPORTED when calling GetAdaptersAddresses(), Indy would then fallback to GetAdaptersInfo().
Sergey
@icegood

Hi, Remy. I wonder, what Indy10 means by 'Content-Length' for TIdMultipartFormDataStream?

I have next code:

AMultiPartFormData := TIdMultipartFormDataStream.Create; // Size=-1, OK

AField := AMultiPartFormData.AddFormField(AId, '', '', 'application/octet-stream'); // size = 222, might be OK

DataStream.CopyFrom(AStream, ALength); // ALength = 100500 bytes
ADataStream.Position := 0;
AField.FieldStream := ADataStream; // after that size became even smaller 220 bytes! why? i expect to see it >= ALength

moreover i must also sent 'Content-MD5' header and have no idea what should be there... In previous version of code with Alcinoe library we had there
CalculateMD5ForStream(ADataStream); and everything works well!

Sergey
@icegood
Should be ADataStream.Position := 0; before Post. But question about decreasing of size remains...
Remy Lebeau
@rlebeau
@icegood The Content-Length is the total bytes of the entire generated MIME content, from opening boundary to closing boundary, as one would expect. AMultiPartFormData.Size is not calculated until TIdHTTP requests it during posting, at which time the current field content is counted, but there is no way the size could be calculated so low, it takes the full MIME headers and FieldStream.Size into account (see TIdFormDataField.GetFieldSize()). How exactly are you determining the size is decreasing? You can use TIdHashMessageDigest5 to generate an MD5 hash, but there is currently no option to add custom headers to TIdMultipartFormDataStream fields, sorry.
Sergey
@icegood

@rlebeau, i've just checked change of size via Debug Watch . As i said above it happens only in case when my stream position is at the end.

I have another question, my HTTP protocol has KeepAlive=True and i see that in this case no disconnection happens:

if not Response.KeepAlive then begin
// TODO: do not disconnect if hoNoReadMultipartMIME is in effect
// TODO: do not disconnect if hoNoReadChunked is in effect
Disconnect;
end;

but i wonder whether is it a good idea to disconnect in case when socket error occurs? E.g. 'connection reset by peer'?

Sergey
@icegood
@rlebeau : "but there is currently no option to add custom headers to TIdMultipartFormDataStream fields, sorry."
we don't need that , do we? I've added MD5 header directly to TIdHTTP.CustomHeader and it works for me
irawancepu
@irawancepu
Using Delphi 2007, Indy 10 version 10.6.2.0, i got : E2251: ambiguous overloaded call to 'Post'. How to resolve this?
irawancepu
@irawancepu
Whew, there are 8 overloaded functions in idHttp.pas What i wanto to do actually is simply read response from portchecker.co. From there i can decide my port forwarding correctly or not. Many combination on Post methods are possible. Depend on STRING_IS_ANSI directive too. Too hard for me.
davidpn
@davidpn
you could just read the return value of the version of Post that returns a value
you can use code completion to determine which overloads are applicable
I mean code insight
irawancepu
@irawancepu
Here is my fragment code procedure TfMain.btnPostClick(Sender: TObject);
var ms: TMemoryStream; s: string;
begin
mmoLog.Clear; s:= '';
ms := TMemoryStream.Create;
try
try
s := idhttpX.Post(edtHost.Text,nil);
mmoLog.Lines.Text := s;
except on E: Exception do ShowMessage(e.ClassName + ':' + e.Message);
end; // try..except
finally ms.Free;
end; // try..finally
end;
davidpn
@davidpn
does the server support only Post for that URL? Are you able to use a Get?
Post usually includes sending content, and you're passing nil, so the compiler does not know whether to use the overload with TStream or with TIdMultiPartFormDataStream
thus the "ambiguous" message
irawancepu
@irawancepu
This error raise up on compile process. From html text the server produces, yes this server support POST method.
davidpn
@davidpn
I asked if it also supports Get
I know it will raise a compile error; I explained why
irawancepu
@irawancepu
Coz, i never pass compile process, err: E2251, i never know whether this site (yougetsignal.com and portchecker.co) is really support POST method or not. I only evaluate their html i got using Curl, curl.haxx.se. Using web browser, Torch and Firefox , everything is fine, so i assume it support GET method.
davidpn
@davidpn
ok.. so use Get instead
irawancepu
@irawancepu
But this site wat POST method, not GET method. Can i use GET method to emulate POST method? Here is a part of html code from portchecker.com. <form class="row" id="mainForm" action="/check" method="post">
<div class="large-7 columns">
<div class="row">
<div class="large-7 columns">
<label>Your IP Address</label>
<input type="text" name="target_ip" id="targetIP" value="36.78.221.82" disabled />
</div>
<div class="large-5 columns">
<label>Port Number</label>
<input type="text" name="port" id="portNumber" value="80" required/>
</div>
</div>
<div class="common-ports-list" id="labels-wrapper">
<span class="label info" data-port="80" >HTTP - 80</span>
<span class="label success hidden-on-mobile" data-port="115" >SFTP - 115</span>
<span class="label alert" data-port="25">SMTP - 25</span>
<span class="label info" data-port="8080" >HTTP - 8080</span>
<span class="label alert" data-port="21" >FTP - 21</span>
<span class="label hidden-on-mobile" data-port="22" >SSH - 22</span>
<span class="label warning" data-port="143">IMAP - 143</span>
<span class="label success hidden-on-mobile" data-port="443" >HTTPS - 443</span>
<span class="label alert hidden-on-mobile" data-port="873" >RSYNC - 873</span>
<span class="label info hidden-on-mobile" data-port="110" >POP3 - 110</span>
<span class="label success hidden-on-mobile" data-port="993">IMAPS - 993</span>
</div>
</div>
<div class="large-5 columns btn-wrapper">
<button type="submit" class="button">Check</button>
</div>
</f
davidpn
@davidpn
yes, it will require Post. It also means you'll need to pass the content it expects when you call Post. You're passing nil, which means no content
irawancepu
@irawancepu
problem is, i never pass compile process. how can i send the data it needs then? i will try using other delphi version. maybe D2007 is too old. very hard to keep many versions.
davidpn
@davidpn
it has been a while since I have done that with Indy, perhaps @rlebeau can help when he is around
I might be able to find an example
davidpn
@davidpn
there's an example here which is similar to what you need to do:
http://stackoverflow.com/questions/7762584/post-problems-with-indy-tidhttp
Although you can ignore the parts about SSL. Refer to the accepted answer
the main thing is that you need to pass the content that the URL expects, in the 2nd parameter where you are passing nil instead
mezen
@mezen
Sound like a chicken or egg problem: You cant compile because you dont send data, but you cant send data, because you cant compile...
irawancepu
@irawancepu
From insight, Post(AURL string; ASourceFile: string; ADestEncoding: IIdTexEncoding=nil): string. There are 3 params needed, the third is defaulted to nil. So at least 2 params must be included. I try another way, try only one param and two params with the second param is nil. So error. The error message successfully driving me crazy. Thx for yours help.
irawancepu
@irawancepu
http://stackoverflow.com/questions/7762584/post-problems-with-indy-tidhttp is not closed too. no definite answer available.
davidpn
@davidpn
there is a definite answer
mezen
@mezen
Is there any ready-to-use solution for multithreaded pings to prevent http://stackoverflow.com/a/12868771/4121488 ?
Or have i to implement all stuff on my own?
Jos de Bruijn
@josdebr_twitter
I'm having problems with the IMAPClient, one of our customers is getting a RangeError when retrieving mailmessages from an IMAP server (Exchange). When I read the headers (IMAPClient.retrieveHeaders() I get the correct header information, but when I try to download the complete message using Retrieve() I get the RangeError. Using IdLogDebug I found that it does return all the parts of the message and the debug ends with: "C33 OK FETCH completed." So it looks like the message is downloaded completely, and the range error is generated when Indy is parsing the message. Any idea on what this can be? (I'm using Indy 10.6.2.0)
Remy Lebeau
@rlebeau
@icegood TIdHTTP already does disconnect in case of socket errors (see the try/except blocks inside of RetreiveHeaders() and around calls to ReadResult()). Putting Content-MD5 in the TIdHTTP header applies the MD5 hash to the entire request body, not to any individual MIME field within the multipart stream, so it can make sense to want to add custom headers on a per-field basis.
Remy Lebeau
@rlebeau
@irawancepu based on the HTML you showed, you need to use something more like this instead:
procedure TfMain.btnPostClick(Sender: TObject);
var
params: TStringList;
s: string;
begin
mmoLog.Clear;
s := '';
params := TStringList.Create;
try
params.Add('target_ip=36.78.221.82'); // substitute desired IP
params.Add('port=80'); // substitute desired port
try
s := idhttpX.Post('http://hostname/check', params);
mmoLog.Lines.Text := s;
except
on E: Exception do
ShowMessage(e.ClassName + ':' + e.Message);
end;
finally
params.Free;
end;
end;
@mezen I don't know of any ready-made solutions, if you can't find one then you will have to implement it yourself.
Remy Lebeau
@rlebeau
@josdebr_twitter what is the EXACT error message? What does the call stack look like when the error occurs?
SandroHerbst
@SandroHerbst
Hi, I need to update my Indy in Delphi 2010, I´ve download the SVN Repo, and in trunk/lib there are a lot of batch files to compile it, but there is not a Full_D2010.bat or a Indy140.groupproj. Am I searching in the wrong place? Thanks
Remy Lebeau
@rlebeau
@SandroHerbst No, you are not. Indy stopped using batch scripts in Delphi years ago (looks like D2009 was the last version), though it still uses them in C++Builder (for now, they will eventually be phased out). And no, there is no project group for D2010 (never got around to creating one). Just open the 5 Indy packages in the IDE and compile them from there, in this order: IndySystem140, IndyCore140, IndyProtocols140, dclIndyCore140, dclIndyProtocols140, and then install the 2 dcl packages into the IDE.
irawancepu
@irawancepu
@Remy Lebeau Everything works as expected now. The 2nd parameter needed in Post method is a TStrings that contains form parameter. I lost this one, never pass compile process. However, the result is of string type, is it nicer if the result is of TStrings type? So there no problem if the result if very big data. What i fear is the response is big so string type is not big enough to hold.
Remy Lebeau
@rlebeau
@irawancepu TStrings takes up more memory than a single string, and would scatter the list entries all over memory as well. Most people don't need HTTP results in a TStrings, a string suffices. However, Post() does have other overloads to return data using TStream instead.
irawancepu
@irawancepu
@Remy As you can see from my code before and website i visited, one crucial network guy is to check a port is in open state or just closed. I did port forward some ports on my router to many devices like CCTV. Usually everything okay on high class devices. But now conditions change, many cheap models sold everywhere. They put logo like 'work on cloud directly'. On the other side, port on these cheap devices often get closed if not triggered by visiting website like yougetsignal.com, portchecker.co or canyouuseeme.org. Can i do what these website using Delphi and Indy? So i did not use these web service anymore. It is one of my dreams.
Remy Lebeau
@rlebeau
@irawancepu Indy lets you do just about anything, if you put in the work for it. What EXACTLY do you need to do?