This question already exists:
Closed 10 years ago.
Possible Duplicate:
Without TWebBrowser input values in form on Button Click and get next webpage response
We are working with Delphi Xe2 and Indy 10 components.
We need to input the values in HTML page and click search button and get next result web page without using TWebBrowser. When We post the parameters on the URL, I am unable to get the result webpage.
On Post, we get the current page HTML code. How could we get the result web page in response?
Code we are using:
procedure TForm1.Button1Click(Sender: TObject);
Var
aStream : TStringStream;
data : TIdMultiPartFormDataStream;
begin
aStream := TStringStream.Create;
data := TIdMultiPartFormDataStream.Create;
try
with IdHTTP1 do
begin
data.AddFormField('DEP_PORT', 'Basel');
data.AddFormField('ARR_PORT', 'Gaziantep');
Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0';
Request.AcceptLanguage := 'en-US,en;q=0.5';
Request.Connection := 'keep-alive';
Request.Accept := 'text/html';
IOHandler := SSL;
try
Post('https://sun.sunexpress.com.tr/web/RezvEntry.xhtml?LANGUAGE=EN', data, aStream);
except
on E: Exception do
showmessage('Error encountered during POST: ' + E.Message);
end;
end;
Memo1.Lines.Add(aStream.DataString);
except
end;
end;
The web site you are referring to also adds a jsessionid to the post-url. Maybe you cannot post without a valid jsessionid?
Related
I am trying to do a simple IdHttp.get but the response i get gives me the page for CloudFlare which says Checking your browser before accessing...
How can i deal with this ?, i tried any option i could think of, i even tried doing an Sleep(6000) and repeating the IdHttp.get, since the CloudFlare message says wait for 5 second
Here is my code :
var
mIdHttp: TIdHttp;
URL: String;
memoryStream: TMemoryStream;
Begin
mIdHttp := TIdHttp.create(nil);
mIdHttp.AllowCookies := true;
mIdHttp.HandleRedirects := true;
mIdHttp.Request.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 OPR/44.0.2510.1457';
mIdHttp.Request.Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8';
mIdHttp.Request.AcceptEncoding := 'gzip, deflate';
mIdHttp.Request.AcceptLanguage := 'en-US,en;q=0.9';
mIdHttp.Request.Host := 'somesite.com/'';
URL := 'https://somesite.com'';
//Both ssleay32.dll and libeay32.dll are beside the application.
mIdHttp.get(URL, memoryStream);
memoryStream.saveToFile('response.txt');
End;
I solved this problem,first update the indy version to 10.6.2.0,then follow my request code below:
function Request(Method,URL:String;RequestHeaders,SendString:String;TreadTLog:TLogger;ContentType:string='application/x-www-form-urlencoded'
;SSLVersion:TIdSSLVersion=sslvSSLv23;UserAgent:string='Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0'):string;
var
SendStream,GetSStream: TStringStream;
IdHTTP:TIdHTTP;
List:TStringList;
LHandler: TIdSSLIOHandlerSocketOpenSSL;
EvHandler:TEventHandlers;
IdConnectionIntercept:TIdConnectionIntercept;
i:Integer;
RetStr,S,KEY,VALUE:string;
begin
Result:='';
if URL='' then Exit;
IdHTTP:=TIdHTTP.Create(nil);
List := TStringList.Create;
SendStream:=TStringStream.Create('');
GetSStream:=TStringStream.Create('');
try
ExtractStrings(['&'],[],pchar(RequestHeaders),List);
SendStream.WriteString(SendString);
try
IdConnectionIntercept:= TIdConnectionIntercept.Create(nil);
IdConnectionIntercept.OnReceive := EvHandler.IdConnectionInterceptReceive;
IdConnectionIntercept.OnSend := EvHandler.IdConnectionInterceptSend;
IDHTTP.Intercept := IdConnectionIntercept;
if (pos('HTTPS',UPPERCASE(URL))>0) then
begin
LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IDHTTP);
IdHTTP.IOHandler:=LHandler;
LHandler.OnVerifyPeer:=EvHandler.LHandlerVerifyPeer;
LHandler.SSLOptions.Method := SSLVersion;
LHandler.SSLOptions.SSLVersions:=[sslvSSLv23,sslvSSLv2, sslvSSLv3, sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2];
LHandler.SSLOptions.Mode := sslmUnassigned;
LHandler.SSLOptions.VerifyMode := LHandler.SSLOptions.VerifyMode + [sslvrfPeer];;
LHandler.SSLOptions.VerifyDepth := 0;
end
else IdHTTP.IOHandler:=nil;
for i:=0 to List.Count-1 do
begin
S:=Trim(List.Strings[i]);
if S<>'' then
begin
KEY:=Copy(S,1,Pos('=',S)-1);
VALUE:=Copy(S,Pos('=',S)+1,Length(S));
IdHTTP.Request.CustomHeaders.Add(KEY+':'+VALUE);
end;
end;
IdHTTP.Request.ContentType :=ContentType;
IdHTTP.Request.UserAgent:=UserAgent;
IdHTTP.HandleRedirects := True;
IdHTTP.AllowCookies := True;
IdHTTP.Request.Connection:='keep-alive';
IdHTTP.Request.BasicAuthentication := False;
IdHTTP.Request.Accept:='text/html, */*';
IdHTTP.Request.AcceptEncoding:='identity';
//IdHTTP.ReadTimeout:=MySysPM.PMA06;
//IdHTTP.ConnectTimeout:=MySysPM.PMA06;
IdHTTP.HTTPOptions:=IdHTTP.HTTPOptions+[hoKeepOrigProtocol];
IdHTTP.ProtocolVersion:=pv1_1;
IdHTTP.Request.Referer:='';
IF UpperCase(Method)='POST' then
BEGIN
IdHTTP.Post(URL,SendStream,GetSStream);
RetStr:=Utf8ToAnsi(GetSStream.DataString);
end
else if UpperCase(Method)='GET' then
begin
RetStr:=IdHTTP.Get(URL);
end
else begin
IdHTTP.Delete(URL);
end;
IdHTTP.Disconnect;
Result:=RetStr
except
on E:exception do
begin
TreadTLog.WriteLog('Request:'+e.Message,1);
end;
end;
finally
try
if Assigned(IdConnectionIntercept) then FreeAndNil(IdConnectionIntercept);
FreeAndNil(LHandler);
FreeAndNil(SendStream);
FreeAndNil(GetSStream);
FreeAndNil(List);
FreeAndNil(IdHTTP);
except
end;
end;
end;
Cloudflare implements protection against bots (DDoS attacks, etc), that is what the 5 second wait is about.
Redirect to a website with cloudflare 5 second protection C#
Your app is not a web browser that executes Javascript, so it gets treated as a bot instead.
Cloudflare sends a challenge in Javascript, which must be computed and sent back to Cloudflare in order to obtain a cookie that can then be used to bypass the protection on subsequent requests.
How can I get html from page with cloudflare ddos portection?
The above links are for C#. You will have to replicate a similar solution in Delphi using Indy and whatever Javascript/Regex library you want.
I'm trying to log in to Gmail (not the email) through Indy component using Delphi XE5,
Using this function:
procedure TForm1.Button1Click(Sender: TObject);
var
http : TIdHTTP;
S, GALX, Email, Pass : String;
lParam : TStringList;
begin
try
lParam := TStringList.Create;
try
http := TIdHTTP.Create(nil);
http.IOHandler := IOHandler;
http.CookieManager := Cookie;
http.AllowCookies := true;
http.HandleRedirects := true;
http.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0';
http.Request.Host := 'accounts.google.com';
http.Request.Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
http.Request.ContentType := 'application/x-www-form-urlencoded';
S := http.Get('https://accounts.google.com/ServiceLogin');
Delete(S, 1, Pos('GALX', S));
S := Copy(S, 1, Pos('">', S) - 1);
Delete(S, 1, Pos('value=', S) + length('value='));
GALX := S;
lParam.Add('GALX='+GALX);
lParam.Add('Email='+Email);
lParam.Add('Passwd='+Pass);
Memo1.Lines.Add(http.Post('http://accounts.google.com/ServiceLoginAuth', lParam));
finally
http.Free;
end;
finally
lParam.Free;
end;
end;
Now whenever i try to execute that i get:HTTP/1.0.405 Method Not Allowed.
and i only get this error when the email/pass are right, when the email/pass is wrong i get the usual error page, so i'm guessing it's not the POST Method that is not allowed.
What am i doing wrong here?
You are not submitting all of the input fields that /ServiceLoginAuth looks for. If you look at the HTML for /ServiceLogin, there are 8 other fields posted to /ServiceLoginAuth besides the 3 that you are already sending. When submitting data from an HTML form, you have to submit everything the HTML form wants to submit, you can't just pick and choose what you want. Try adding the other fields and see what happens.
You need to provide the /ServiceLogin URL in the TIdHTTP.Request.Referer property when posting to /ServiceLoginAuth so it thinks that the request is coming from /ServiceLogin.
You are retrieving /ServiceLogin using HTTPS, but you are posting to /ServiceLoginAuth using HTTP instead. You need to use HTTPS.
When the user has multiple Google accounts, /ServiceLogin posts to /AccountChooser, which then redirects back to /ServiceLogin with additional input parameters, so you might need to take that into account as well.
Posting to /ServiceLoginAuth redirects to /CheckCookie, which then redirects to /ManageAccount, so make sure those requests are complete and accurate at each step.
i have a problem i can connect using tIdhttp to the site i want without any problem but the problem is i cant connect from other button.
i have declared those variables outside the function .. tought this gonna help but it didnt
var
Form1: TForm1;
HTTP : TIDHTTP;
Cookie : TidCookieManager;
implementation
{$R *.dfm}
and this in the function
HTTP := TIDHTTP.Create(NIL);
Cookie := TidCookieManager.Create(nil);
HTTP.Request.UserAgent := 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; Acoo Browser 1.98.744; .NET CLR 3.5.30729)';
HTTP.Request.Accept := 'text/html, */*';
HTTP.Request.CacheControl := 'no-cache';
HTTP.AllowCookies := True;
HTTP.HandleRedirects := True;
HTTP.ProtocolVersion := pv1_1;
HTTP.CookieManager := Cookie;
HTTP.RedirectMaximum := 15;
Data := TStringList.Create;
Page := TStringList.Create;
Data.Add('LoginForm[username]=xxxLoginForm[password]=xxx&LoginForm[rememberMe]=0');
Page.Text := HTTP.Post('http://somesite.com/login.html',Data);
If Pos('>Logout', Page.Text) = 0 Then Result := False
else Result := True;
Page.Free;
Data.Free;
// HTTP.Free;
end;
button2
HTTP.Get('http://somesite.cc/info/523364d0/'); // this does not work it show that im not connected ..but the function already connected to the site.
in button1 i can connect(Logged in to a site) using my function successfully then i click in button2 using HTTP.get to get file but it fail it shows that im not logged in
so how i can keep my program connected so i can only call get page(in other buttons) wihtout logging in again .
sorry for my bad english.
Your login data is being formatted wrong. Not only are you missing a & between the username and password fields, but you should not be putting everything in a single TStringList entry to begin with. TIdHTTP expects each field to be its own entry in the TStringList, and then it will encode and concatenate the values together when formatting the HTTP request.
In other words, change this:
Data.Add('LoginForm[username]=xxxLoginForm[password]=xxx&LoginForm[rememberMe]=0');
to this:
Data.Add('LoginForm[username]=xxx');
Data.Add('LoginForm[password]=xxx');
Data.Add('LoginForm[rememberMe]=0');
If that still does not work, then the problem has to be related to the HTTP session. Either the server is sending a cookie upon login that TIdCookieManager is rejecting, or TIdCookieManager is not sending the cookie back on subsequent requests to the same HTTP server, or maybe subsequent requests need to specify a Referer that is set to the previous URL (some servers do require that).
I use this code to connect to fileserve.com using my premium account i want to share my program but they can easly snif username and password using "HTTP Analyzer" is there a way to hide my username and password from sniffing ?i use delphi 2007.
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
Data, Page : TStringList;
begin
IdHTTP1.OnRedirect := nil;
IdHTTP1.AllowCookies := True;
IdHTTP1.HandleRedirects := True;
IdHTTP1.ProtocolVersion := pv1_1;
IdHTTP1.CookieManager := IdCookieManager1;
IdHTTP1.RedirectMaximum := 15;
IdHTTP1.Request.UserAgent := 'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.1)';
Data := TStringList.Create;
try
Data.Add('loginUserName=[user]');
Data.Add('loginUserPassword=[pass]');
Data.Add('autoLogin=');
Data.Add('loginFormSubmit=Login');
IdHTTP1.Post('http://www.fileserve.com/login.php', Data);
finally
Data.Free;
end;
IdHTTP1.HandleRedirects := False;
IdHTTP1.OnRedirect := IdHTTP1Redirect;
IdHTTP1.Get('http://www.fileserve.com/file/aYkRqp3');
Edit1.Text := idHTTP1.Response.Location;
for i := 0 to IdCookieManager1.CookieCollection.Count - 1 do
Memo2.Lines.Add(IdCookieManager1.CookieCollection.Items[i].CookieText);
end;
There's no way to hide bits you're transmitting from sniffing. The only thing you can do is encrypt the bits so that even if someone gets ahold of them, they can't figure out what they mean. See if the website you're connecting to has an HTTPS version available, and try using that (and Indy's HTTPS protocol handlers) instead of the HTTP version.
I have been writing a Delphi library for StackApps API.
I have run into a problem with Indy. I am using the version that ships with Delphi 2010.
If you pass invalid parameters to one of the StackApps API it will return a HTTP Error Code 400 and then in the response it will contain a JSON object with more details.
By visiting http://api.stackoverflow.com/0.8/stats/?Key=BadOnPurpose in Chrome Browser you can see an Example. I.E. and Firefox hide the JSON.
Using WireShark I can see that the JSON object is returned using the code below, but I am unable to access it using Indy.
For this test code I dropped a TIdHttp component on the form and placed the following code in a button click.
procedure TForm10.Button2Click(Sender: TObject);
var
SS : TStringStream;
begin
SS := TStringStream.Create;
IdHTTP1.Get('http://api.stackoverflow.com/0.8/stats/?Key=BadOnPurpose',SS,[400]);
Memo1.Lines.Text := SS.DataString;
SS.Free;
end;
I passed [400] so that it would not raise the 400 exception. It is as if Indy stopped reading the response. As the contents of Memo1 are empty.
I am looking for a way to get the JSON Details.
Remove the AIgnoreReplies parameter value from your call to Get(). Let it raise the exception normally. The JSON text you are looking for is in the EIdHTTPProtocolException.ErrorMessage property. For example:
procedure TForm10.Button2Click(Sender: TObject);
begin
try
Memo1.Lines.Text := IdHTTP1.Get('http://api.stackoverflow.com/0.8/stats/?Key=BadOnPurpose');
except
on E: EIdHTTPProtocolException do begin
if E.ErrorCode = 400 then
Memo1.Lines.Text := E.ErrorMessage
else
raise;
end;
end;
end;