Monte Carver
2008-06-27 05:32:25 UTC
Indy Gurus,
I'm having a tough time of pushing a post from Indy (10.1.5).
BACKGROUND
The following code produces the error HTTP/1.1 422. However the bottom html code, if
saved to an HTML file and submitted (after inserting a valid "authenticity_token"), will
successfully login. An "authenticity_token" can easily be extracted by simply reviewing
the source of the login site:
'http://proac1.securesites.net:4102/account/login';
My suspicion of the problem is that I am currently extracting the "authenticity_token" by
using IHTMLDocument2, which is of course based on IE. I find that if I extract an
"authenticity_token" from IE but launch the below HTML code with the newly acquired token
using FireFox, I receive a Ruby authentication failure. As long as I use the same browser
from which the token was acquired, the manual post seems to work. It does not even have
to be the same browser window.
QUESTION
1) So, if this indeed is the problem, is it solved by simply performing a idHTTP.Get and
parsing out the "authentication_token". Then submitting the below code using idHTTP.Post?
2) If this solves the problem, what is it about the "GET" and "POST" that the Ruby server
uses to discern that the browser is the same? How can it tell?
3) Lastly, the reason I used IHTMLDocument2, is because it appears that all html parsing
engines are 3rd party. Is this the only "easy" option. Does Delphi 2007 not have a built
in parser. I am not opposed to 3rd party (believe me), its just that I don't need anymore. :)
Please advise. I have done consider research on the subject, and I am still somehow
missing some detail.
Regards,
Monte Carver
########################################################
lResStream := TMemoryStream.Create;
lParams := TIdMultiPartFormDataStream.Create;
try
with idHTTP do
begin
ProxyParams.BasicAuthentication := False;
Request.Accept := 'text/html, */*';
Request.BasicAuthentication := False;
Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
HTTPOptions := [hoForceEncodeParams];
Request.ContentType := 'application/x-www-form-urlencoded';
lParams.AddFormField('authenticity_token', 'f559a86c343ab98b4547770d65e881c848c4484d'));
lParams.AddFormField('account', HTTPEncode('1'));
lParams.AddFormField('login', HTTPEncode('test_ch'));
lParams.AddFormField('password', HTTPEncode('12345'));
lParams.AddFormField('lodge', HTTPEncode('1'));
try
idHttp.Post(lPostURL, lParams, lResStream);
#####################################################
myTest.html
#####################################################
<html>
<head></head>
<body>
<form action="http://proac1.securesites.net:4102/account/login" method="post" name='f'>
<input name="authenticity_token" value="e8ac1f2a2960209168e3a28ba2067faaee8edb69" />
<label>Account</label><input name="account" value="1" type="text"><br>
<label>Login</label><input name="login" value="test_ch" type="text"><br>
<label>Password</label><input name="password" value="12345" type="text"><br>
<label>Password</label><input name="lodge" value="1"type="text"><br>
<input name="commit" type="submit" value="Do It">
</form>
</body>
</html>
I'm having a tough time of pushing a post from Indy (10.1.5).
BACKGROUND
The following code produces the error HTTP/1.1 422. However the bottom html code, if
saved to an HTML file and submitted (after inserting a valid "authenticity_token"), will
successfully login. An "authenticity_token" can easily be extracted by simply reviewing
the source of the login site:
'http://proac1.securesites.net:4102/account/login';
My suspicion of the problem is that I am currently extracting the "authenticity_token" by
using IHTMLDocument2, which is of course based on IE. I find that if I extract an
"authenticity_token" from IE but launch the below HTML code with the newly acquired token
using FireFox, I receive a Ruby authentication failure. As long as I use the same browser
from which the token was acquired, the manual post seems to work. It does not even have
to be the same browser window.
QUESTION
1) So, if this indeed is the problem, is it solved by simply performing a idHTTP.Get and
parsing out the "authentication_token". Then submitting the below code using idHTTP.Post?
2) If this solves the problem, what is it about the "GET" and "POST" that the Ruby server
uses to discern that the browser is the same? How can it tell?
3) Lastly, the reason I used IHTMLDocument2, is because it appears that all html parsing
engines are 3rd party. Is this the only "easy" option. Does Delphi 2007 not have a built
in parser. I am not opposed to 3rd party (believe me), its just that I don't need anymore. :)
Please advise. I have done consider research on the subject, and I am still somehow
missing some detail.
Regards,
Monte Carver
########################################################
lResStream := TMemoryStream.Create;
lParams := TIdMultiPartFormDataStream.Create;
try
with idHTTP do
begin
ProxyParams.BasicAuthentication := False;
Request.Accept := 'text/html, */*';
Request.BasicAuthentication := False;
Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
HTTPOptions := [hoForceEncodeParams];
Request.ContentType := 'application/x-www-form-urlencoded';
lParams.AddFormField('authenticity_token', 'f559a86c343ab98b4547770d65e881c848c4484d'));
lParams.AddFormField('account', HTTPEncode('1'));
lParams.AddFormField('login', HTTPEncode('test_ch'));
lParams.AddFormField('password', HTTPEncode('12345'));
lParams.AddFormField('lodge', HTTPEncode('1'));
try
idHttp.Post(lPostURL, lParams, lResStream);
#####################################################
myTest.html
#####################################################
<html>
<head></head>
<body>
<form action="http://proac1.securesites.net:4102/account/login" method="post" name='f'>
<input name="authenticity_token" value="e8ac1f2a2960209168e3a28ba2067faaee8edb69" />
<label>Account</label><input name="account" value="1" type="text"><br>
<label>Login</label><input name="login" value="test_ch" type="text"><br>
<label>Password</label><input name="password" value="12345" type="text"><br>
<label>Password</label><input name="lodge" value="1"type="text"><br>
<input name="commit" type="submit" value="Do It">
</form>
</body>
</html>