I needed to download some files for personal use, but failed to login to the webpage. No matter if I used TFPHttpClient, THttpSend or TIdHTTP.
It really doesn't matter what library i choose, but for now lets lets talk about TFPHttpClient since thats FreePascals own lib.
There was a discussion earlier, but the OP switched to HTTPSend of Synapse instead and never got fphttpclient going:
https://forum.lazarus.freepascal.org/index.php/topic,35682.msg236310.htmlSSLI noticed that he had not included units for SSL in his code, but was trying to use HTTPS. Maybe that was the reason. I added opensslsockets, but there is also
ssockets,
sslsockets,
ssl_openssl,
ssl_openssl11 and
ssl_openssl3. Are any of them needed here?
URL EncodingSo if the url encoding is wrong it won't work. I use fphttp.FormPost for formdata together with a stringlist for login parameters, not single string. Reason be that the formdata must be urlencoded and
https://wiki.freepascal.org/fphttpclient says it is done automatically only if a stringlist is used.
I checked the returnvalues of HTTPEncode and EncodeURLElement and the dollar sign "$", "!" and "@" is not encoded but remains as is. Should it be like that? The login string 'ctl00$cph1$lg1$txtEmail' contains the "$".
On the other hand, the custom wiki functions found here encode all these signs:
https://wiki.freepascal.org/URL_encoding/decodingFor the formdata below, I'm also not sure if to use "&" signs in front of the strings after the first one or if that is handled automatically or not needed at all.
The result of my efforts is a HTTP 200 code and a not logged in webpage in the Response from fphttpclient.
Trial code looks like this:
uses
.. openssl, opensslsockets, fphttpclient, httpprotocol;
procedure TForm1.btnLoginFpHTTPClick(Sender: TObject);
const
URL = 'https://eoddata.com';
var
HTTP: TFPHTTPClient;
page: string;
formdata: TStrings;
s:string;
Response: TStringStream;
begin
formdata:= TStringList.Create;
formdata.values['ctl00$cph1$lg1$txtEmail'] := 'user@somemail.com'; //Username
formdata.values['ctl00$cph1$ls1$txtPassword'] := 'p@ss=w$rd!'; //Password
formdata.values['ctl00$cph1$ls1$chkRemember'] := '1'; //CheckBox, "Remember me"
formdata.values['ctl00$cph1$ls1$btnLogin'] := 'Login'; //Login Button
InitSSLInterface;
Response:= TStringStream.Create('');
HTTP:= TFPHTTPClient.Create(nil);
try
try
HTTP.AllowRedirect := True;
HTTP.AddHeader('User-Agent', 'Mozilla/5.0 (compatible; fpweb)'); //HTTP.UserAgent:='Mozilla/5.0 (X11; Linux x86_64; rv:129.0) Gecko/20100101 Firefox/129.0';
HTTP.AddHeader('Content-Type', 'application/x-www-form-urlencoded');
HTTP.KeepConnection:=True;
//HTTP.Headers.Add('Accept-Encoding: identity');
//HTTP.Protocol:='1.1';
//Call GET before FormPost?
//HTTP.Get(URL);
HTTP.FormPost(URL, formdata, Response);
Response.Position:=0; //Needed for Loading below.
Memo1.Lines.LoadFromStream(Response);
Memo1.Lines.Add(HTTP.ResponseHeaders.Text);
except
on E: EHttpClient do
ShowMessage(E.Message)
else
raise;
end;
finally
Response.Free;
HTTP.Free;
end;
Also got this:
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
Set-Cookie: ASP.NET_SessionId=qh5hpbbctlwlgngfh5jjvwfu; path=/; HttpOnly; SameSite=Lax
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Sat, 31 Aug 2024 01:24:42 GMT
Content-Length: 36362
HTML code from the webpage:
<div class="p">
<div id="ctl00_cph1_lg1_ch1_d1" class="rc_bg_bl"><div id="ctl00_cph1_lg1_ch1_d2" class="rc_tl_bl"><div id="ctl00_cph1_lg1_ch1_d3" class="rc_tr_bl"><div id="d4" class="rc_c">
<table class="rc_t">
<tr><td><div id="ctl00_cph1_lg1_ch1_divText">MEMBER LOGIN</div></td><td><div id="ctl00_cph1_lg1_ch1_divLink" class="hlink"></div></td><td align="right"><div id="ctl00_cph1_lg1_ch1_divIcon" class="hicon"></div></td></tr>
</table>
</div></div></div></div>
<div class="bbf" style="padding:6px;">
<div id="ctl00_cph1_lg1_pnlLogin">
<table cellpadding="4" cellspacing="0" width="100%" border="0" style="margin-bottom:10px;">
<tr>
<td>Email/Username:</td>
<td><input name="ctl00$cph1$lg1$txtEmail" type="text" id="ctl00_cph1_lg1_txtEmail" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input name="ctl00$cph1$lg1$txtPassword" type="password" id="ctl00_cph1_lg1_txtPassword" /></td>
</tr>
<tr>
<td></td>
<td><input id="ctl00_cph1_lg1_chkRemember" type="checkbox" name="ctl00$cph1$lg1$chkRemember" /><label for="ctl00_cph1_lg1_chkRemember">Remember Me</label></td>
</tr>
<tr><td colspan="2"><span id="ctl00_cph1_lg1_lblMessage"><font color="Red"></font></span></td></tr>
<tr>
<td></td>
<td><input type="submit" name="ctl00$cph1$lg1$btnLogin" value="Login" id="ctl00_cph1_lg1_btnLogin" class="fancy" with="80px;" /></td>
</tr>
</table>
<table cellpadding="4" cellspacing="0" width="100%" border="0">
<tr>
<td><a id="ctl00_cph1_lg1_lnkRegister" href="register.aspx">Register</a></td>
<td align="center"><a id="ctl00_cph1_lg1_btnResendEmail" href="javascript:__doPostBack('ctl00$cph1$lg1$btnResendEmail','')">Resend Confirmation</a></td>
<td align="right"><a id="ctl00_cph1_lg1_lnkForgot" href="support/Forgot.aspx">Forgot</a></td>
</tr>
</table>
</div>
</div>
</div>