I'm trying to upload a file to oboom.com i logged in successfully but when try to post the file i get that error
HTTP/1.1500 Internal Server Error.
with this respose text
[500,"illegal post header","Content-Transfer-Encoding"]
procedure TForm1.Button1Click(Sender: TObject);
var
S: tstringlist;
html: string;
clHttpRequest1: tclHttpRequest;
SSLIOHandlerSocketOpenSSL: TIdSSLIOHandlerSocketOpenSSL;
params: TIdMultiPartFormDataStream;
HTTP, HTTP2: tidhttp;
begin
params := TIdMultiPartFormDataStream.Create;
S := tstringlist.Create;
HTTP2 := tidhttp.Create(nil);
try
cookie := tidcookiemanager.Create(nil);
SSLIOHandlerSocketOpenSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
HTTP2.IOHandler := SSLIOHandlerSocketOpenSSL;
HTTP2.HandleRedirects := False;
HTTP2.ConnectTimeout := 10000;
HTTP2.ReadTimeout := 10000;
HTTP2.CookieManager := cookie;
HTTP2.AllowCookies := True;
HTTP2.Request.UserAgent :=
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36';
HTTP2.Request.ContentType := 'application/x-www-form-urlencoded';
HTTP2.Request.ContentEncoding := 'gzip, deflate';
HTTP2.Request.Accept := '*/*';
HTTP2.Request.Connection := 'Keep-Alive';
S.Values['auth'] := 'email#gmail.com';
S.Values['pass'] := 'password';
S.Values['app_id'] := '5hwaJUcDicXprlV3gjaB';
S.Values['app_session'] := '288196272';
html := HTTP2.Post('https://www.oboom.com/1.0/login', S);
finally
HTTP2.Free;
S.Free;
end;
token := ExtractBetween(html, 'session":"', '"');
try
HTTP := tidhttp.Create;
HTTP.HandleRedirects := True;
HTTP.Request.Connection := 'keep-alive';
HTTP.AllowCookies := True;
HTTP.CookieManager := cookie;
HTTP.Request.Referer := 'http://upload.oboom.com';
HTTP.Request.ContentType :=
'multipart/form-data; boundary=----------GI3Ef1cH2GI3gL6ae0Ef1KM7Ef1gL6';
HTTP.Request.Accept := '*/*';
HTTP.Request.AcceptEncoding := 'gzip,deflate';
HTTP.ConnectTimeout := 20000;
HTTP.ReadTimeout := 20000;
HTTP.Request.UserAgent :=
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36';
params.AddFile('file', 'C:\Users\M\Pictures\Martin.jpg', );
HTTP.Post('http://upload.oboom.com/1.0/ul?token=' + token +
'&parent=1&name_policy=rename', params);
finally
HTTP.Free;
params.Free;
cookie.Free;
end;
memo1.Text := html;
end;
i have googled hours for a solution but no luck :/
tried this way :
Params.AddFile('file', 'C:\Users\M\Pictures\Martin.jpg','application/octet-stream');
Params.AddFile('file', 'C:\Users\M\Pictures\Martin.jpg','multipart/form-data');
but same error
i have tried clever internet compenent and succeeded uploading the file but i would like to use indy ..
i use delphi X3
You need to get rid of these lines:
HTTP2.Request.ContentEncoding := 'gzip, deflate';
HTTP.Request.AcceptEncoding := 'gzip,deflate';
TIdHTTP manages those values for you based on whether its Compressor property is assigned and enabled. And, you are not sending a compressed request, so those values should not be used anyway.
Also, you need to get rid of this line:
HTTP.Request.ContentType :=
'multipart/form-data; boundary=----------GI3Ef1cH2GI3gL6ae0Ef1KM7Ef1gL6';
Post() manages that value for you, especially the boundary, which TIdMultipartFormDtaStream generates dynamically.
Update the only other place that Content-Transfer-Encoding is used is on the individual fields of the TIdMultipartFormDataStream. Each TIdFormDataField has a ContentTransfer property. AddFile() initializes it to 'binary', but you can also set it to a blank string to disable the header:
params.AddFile(...).ContentTransfer := '';
Related
I have Delphi 10.3.2
I do not understand this situations:
1)
Uploading photo about 1M
image1.Bitmap.LoadFromFile('test.jpg');
Then I save the same photo
image1.Bitmap.SaveToFile('test_new.jpg');
and test_new.jpg is about 3M. Why ???
2)
I want to send a photo from the TImage (test1.jpg - 1MB) object using IdHTTP and POST request to server.
I use the function Base64_Encoding_stream to encode image.
Image size (string) after encoding the function is 20 MB! ? Why if the original file has 1MB ?
function Base64_Encoding_stream(_image:Timage): string;
var
base64: TIdEncoderMIME;
output: string;
stream_image : TStream;
begin
try
begin
base64 := TIdEncoderMIME.Create(nil);
stream_image := TMemoryStream.Create;
_image.Bitmap.SaveToStream(stream_image);
stream_image.Position := 0;
output := TIdEncoderMIME.EncodeStream(stream_image);
stream_image.Free;
base64.Free;
if not(output = '') then
begin
Result := output;
end
else
begin
Result := 'Error';
end;
end;
except
begin
Result := 'Error'
end;
end;
end;
....
img_encoded := Base64_Encoding_stream(Image1);
.....
procedure Send(_json:String );
var
lHTTP : TIdHTTP;
PostData : TStringList;
begin
PostData := TStringList.Create;
lHTTP := TIdHTTP.Create(nil);
try
PostData.Add('dane=' + _json );
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
lHTTP.Request.Connection := 'keep-alive';
lHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
lHTTP.Request.Charset := 'utf-8';
lHTTP.Request.Method := 'POST';
_dane := lHTTP.Post('http://......./add_photo.php',PostData);
finally
lHTTP.Free;
PostData.Free;
end;
To post your original file using base64 you can basically use your own code. You only need to change the used stream inside your base64 encoding routine like this:
function Base64_Encoding_stream(const filename: string): string;
var
stream_image : TStream;
begin
try
// create read-only stream to access the file data
stream_image := TFileStream.Create(filename, fmOpenRead or fmShareDenyWrite);
// the stream position will be ‘0’, so no need to set that
Try
Result := TIdEncoderMIME.EncodeStream(stream_image);
Finally
stream_image.Free;
End;
if length(result) = 0 then
begin
Result := 'Error';
end;
except
Result := 'Error'
end;
end;
Also, I refactored your code a bit with some try/finally sections, to ensure no memory leaks when errors occur. And I removed the begin/end inside the try/except as those are not needed.
Also removed the local string variable to avoid double string allocation and the unnecessary construction of the TIdEncoderMIME base64 object.
I am using Delphi 10.2.3.
I want to download daily exchange rates from http://www.boi.org.il/currency.xml
My design time component setup:
NetHTTPClient1.AllowCookies := True;
NetHTTPClient1.HandleRedirects := True;
NetHTTPClient1.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36';
NetHTTPRequest1.MethodString := 'GET';
NetHTTPRequest1.URL := 'http://www.boi.org.il/currency.xml';
My code is very simple:
XML := NetHTTPRequest1.Execute().ContentAsString();
What I get back in XML variable is:
<html><body><script>document.cookie='sssssss=6ed9ca3asssssss_6ed9ca3a; path=/';window.location.href=window.location.href;</script></body></html>
When I try to use a web browser (Opera in my case) I can see correct XML using same URL as above. I could not see what the problem is.
Any help is appreciated.
Edit:
After reading #NineBerry comments, I used Fiddler to watch each and every packet to the site. That showed me that browser is doing a request for three times before it can actually download XML. Second request, browser adding cookie reference in the response to first request. 3rd request is same as 2ns request.
After investigating below is a working code for me and I am not changing any TNetHTTPClient.UserAgent parameter:
function DownloadExchangeRates(const URL: string; out XML: string): Boolean;
var
Cookie: string;
Path: string;
AURI: TURI;
AClient: TNetHTTPClient;
ARequest: TNetHTTPRequest;
begin
AClient := nil;
ARequest := nil;
try
AClient := TNetHTTPClient.Create(nil);
AClient.AllowCookies := True;
AClient.HandleRedirects := True;
ARequest := TNetHTTPRequest.Create(nil);
ARequest.Client := AClient;
ARequest.Asynchronous := False;
ARequest.MethodString := 'GET';
ARequest.URL := URL;
ARequest.CustomHeaders['Pragma'] := 'no-cache';
try
XML := ARequest.Execute().ContentAsString();
if XML.Length > 5 then
begin
if UpperCase(XML.Substring(0, 6)) = '<HTML>' then
begin
Cookie := GetCookie(XML);
AURI := TURI.Create(URL);
Path := AURI.SCHEME_HTTP + '://' + AURI.Host + '/';
AClient.CookieManager.AddServerCookie(Cookie, Path);
AClient.CookieManager.AddServerCookie(Cookie, URL);
ARequest.CustomHeaders['Referer'] := URL;
XML := ARequest.Execute().ContentAsString();
if XML.Length > 5 then
begin
if UpperCase(XML.Substring(0, 6)) = '<HTML>' then
begin
XML := ARequest.Execute().ContentAsString();
end;
end;
end;
end;
except
on E: Exception do
begin
Exit(False);
end;
end;
finally
ARequest.Free();
AClient.Free();
end;
Result := (XML.Length > 2) and (XML[2] = '?');
end;
uses
System.Net.HttpClient;
function TUpdater.DownloadFile(const aURL: string; aStream: TStream): boolean;
var
vHTTP: THTTPClient;
begin
Assert(aStream <> nil);
vHTTP := THTTPClient.Create;
try
Result := vHTTP.Get(aURL, aStream).StatusCode = 200;
finally
vHTTP.Free;
end;
end;
I have code that I copied from here:
How to login to Instagram website using IdHTTP in delphi10
procedure Tinstfrm.Button1Click(Sender: TObject);
var
lHTTP: TIdHTTP;
IdSSL: TIdSSLIOHandlerSocketOpenSSL;
Params : TStrings;
Reply, Token: string;
Cookie: TIdCookie;
begin
Params := TStringList.Create;
try
Params.Add('username=' + Edit1.Text);
Params.Add('password=' + Edit2.Text);
lHTTP := TIdHTTP.Create(nil);
try
IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
IdSSL.SSLOptions.Method := sslvTLSv1;
IdSSL.SSLOptions.Mode := sslmClient;
lHTTP.IOHandler := IdSSL;
lHTTP.ReadTimeout := 30000;
lHTTP.HandleRedirects := True;
// capture cookies first...
// passing nil to ignore any response body data and not waste memory for it...
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36';
lHTTP.Get('https://www.instagram.com', TStream(nil));
Cookie := lHTTP.CookieManager.CookieCollection.Cookie['csrftoken', 'www.instagram.com'];
if Cookie <> nil then
Token := Cookie.Value;
// now submit the login webform...
lHTTP.Request.CustomHeaders.Values['X-CSRFToken'] := Token;
lHTTP.Request.CustomHeaders.Values['X-Instagram-AJAX'] := '1';
lHTTP.Request.CustomHeaders.Values['X-Requested-With'] := 'XMLHttpRequest';
lHTTP.Request.Referer := 'https://www.instagram.com/';
lHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36';
Reply := lHTTP.Post('https://www.instagram.com/accounts/login/ajax/', Params);
Memo1.Lines.add(Reply);
Reply := lHTTP.Get('https://www.instagram.com/web/friendships/Value/follow/');
Memo1.Lines.add(Reply);
finally
lHTTP.Free;
end;
finally
Params.Free;
end;
end;
I use it to login into my Instagram account and it is successful, but now I want to Follow some user on Instagram. How can I do that?
Lets say I have this URL call:
lHTTP.Get('https://www.instagram.com/web/friendships/21193118/follow/');
I try to use TIdHTTP.Post() like this:
Reply := lHTTP.Post('https://www.instagram.com/web/friendships/21193118/follow/', ...);
Here I should use a parameter but what should I use?
What should I add to the Post params to get the follow to work?
Added some code
I searched in other questions and came up with this code:
procedure Tinstfrm.Button1Click(Sender: TObject);
var
lHTTP: TIdHTTP;
IdSSL: TIdSSLIOHandlerSocketOpenSSL;
Params : TStrings;
Reply, Token: string;
Cookie: TIdCookie;
begin
Params := TStringList.Create;
try
Params.Add('username=' + Edit1.Text);
Params.Add('password=' + Edit2.Text);
lHTTP := TIdHTTP.Create(nil);
try
IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
IdSSL.SSLOptions.Method := sslvTLSv1;
IdSSL.SSLOptions.Mode := sslmClient;
lHTTP.IOHandler := IdSSL;
lHTTP.ReadTimeout := 30000;
lHTTP.HandleRedirects := True;
// capture cookies first...
// passing nil to ignore any response body data and not waste memory for it...
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36';
lHTTP.Get('https://www.instagram.com', TStream(nil));
Cookie := lHTTP.CookieManager.CookieCollection.Cookie['csrftoken', 'www.instagram.com'];
if Cookie <> nil then
Token := Cookie.Value;
// now submit the login webform...
lHTTP.Request.CustomHeaders.Values['X-CSRFToken'] := Token;
lHTTP.Request.CustomHeaders.Values['X-Instagram-AJAX'] := '1';
lHTTP.Request.CustomHeaders.Values['X-Requested-With'] := 'XMLHttpRequest';
lHTTP.Request.Referer := 'https://www.instagram.com/';
lHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36';
Reply := lHTTP.Post('https://www.instagram.com/accounts/login/ajax/', Params);
Memo1.Lines.add(Reply);
// after your AJAX login...
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36';
lHTTP.Request.Connection := 'keep-alive';
lHTTP.Get('https://www.instagram.com/web/friendships/21193118/follow/', TStream(nil));
cookie := lHTTP.CookieManager.CookieCollection.Cookie['csrftoken', 'www.instagram.com'];
if cookie <> nil then
token := cookie.Value
else
token := '';
// then i dont know what to do
Memo1.Lines.add(Reply);
finally
lHTTP.Free;
end;
finally
Params.Free;
end;
end;
Here is the HTTP request that I am targeting:
Request URL:https://www.instagram.com/web/friendships/21193118/follow/
Request Method:POST
Status Code:200
Remote Address:31.13.93.52:443
Header response
cache-control:private, no-cache, no-store, must-revalidate
content-language:en
content-length:39
content-type:application/json
date:Mon, 11 Jul 2016 10:37:37 GMT
expires:Sat, 01 Jan 2000 00:00:00 GMT
pragma:no-cache
set-cookie:csrftoken=ilINmCvcI2X1X5l2ckJ2wgv6nk9Dlmhx; expires=Mon, 10-Jul-2017 10:37:37 GMT; Max-Age=31449600; Path=/
set-cookie:s_network=; expires=Mon, 11-Jul-2016 11:37:37 GMT; Max-Age=3600; Path=/
set-cookie:ds_user_id=3523180621; expires=Sun, 09-Oct-2016 10:37:37 GMT; Max-Age=7776000; Path=/
status:200
strict-transport-security:max-age=86400
vary:Cookie, Accept-Language
Header request
:authority:www.instagram.com
:method:POST
:path:/web/friendships/21193118/follow/
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, br
accept-language:en-US,en;q=0.8
content-length:0
content-type:application/x-www-form-urlencoded
cookie:mid=V3lV5AAEAAF6YI60VulF4Nh4TdmX; sessionid=IGSC0e057587ba07cd4ead550197071f14d12080d91ab64704da189632ff0a3a86e5%3ApNr5RyGSRcCfUXfhbWRVMf5QJmNhMuHO%3A%7B%22_token_ver%22%3A2%2C%22_auth_user_id%22%3A3523180621%2C%22_token%22%3A%223523180621%3AbQbg9P4AtN5pDpi9ecPcm4wCA7pLSZoz%3A9629557a5546b220841ceaf5ac65b6e867bff0e489651b5892608da6520a3453%22%2C%22asns%22%3A%7B%2245.243.46.26%22%3A24863%2C%22time%22%3A1468232916%7D%2C%22_auth_user_backend%22%3A%22accounts.backends.CaseInsensitiveModelBackend%22%2C%22last_refreshed%22%3A1468232915.569637%2C%22_platform%22%3A4%2C%22_auth_user_hash%22%3A%22%22%7D; ig_pr=1; ig_vw=1440; s_network=; csrftoken=ilINmCvcI2X1X5l2ckJ2wgv6nk9Dlmhx; ds_user_id=3523180621
origin:https://www.instagram.com
referer:https://www.instagram.com/50cent/
user-agent:Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
x-csrftoken:ilINmCvcI2X1X5l2ckJ2wgv6nk9Dlmhx
x-instagram-ajax:1
x-requested-with:XMLHttpRequest
I don't want to use the Instagram API, I would like to stimulate this with TIdHTTP.
I tried the following:
Reply := lHTTP.post('https://www.instagram.com/web/friendships/21193118/follow/', token);
But I got this error:
Cannot open file
"C:\Users\usr\Desktop\app\Win32\Release\L7jHk1Oxrp5kFZcPxew63xzvhyEasA9Y". The system cannot find the file specified.
I'm trying to get my instagram "following" list using only http component. I've tried to use lHTTP.Get('https://www.instagram.com/Myusername/following/'); but there are no usernames in the decrypted html. However, I saw some guys using it without instagram api, just http response in VB.Net. I'm using Delphi 10.
UPDATE
procedure TForm1.Button4Click(Sender: TObject);
var
lHTTP: TIdHTTP;
IdSSL: TIdSSLIOHandlerSocketOpenSSL;
Params, login : TStrings;
Reply, Token, X: string;
Cookie: TIdCookie;
begin
try
Params := TStringList.Create;
Params.Add('username=' + Edit1.Text);
Params.Add('password=' + Edit2.Text);
lHTTP := TIdHTTP.Create(nil);
try
IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
IdSSL.SSLOptions.Method := sslvTLSv1;
IdSSL.SSLOptions.Mode := sslmClient;
lHTTP.IOHandler := IdSSL;
lHTTP.ReadTimeout := 30000;
lHTTP.HandleRedirects := True;
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36';
lHTTP.Get('https://www.instagram.com', TStream(nil));
Cookie := lHTTP.CookieManager.CookieCollection.Cookie['csrftoken', 'www.instagram.com'];
if Cookie <> nil then
Token := Cookie.Value;
try
lHTTP.Request.CustomHeaders.Values['X-CSRFToken'] := Token;
lHTTP.Request.CustomHeaders.Values['X-Instagram-AJAX'] := '1';
lHTTP.Request.CustomHeaders.Values['X-Requested-With'] := 'XMLHttpRequest';
lHTTP.Request.Referer := 'https://www.instagram.com/';
lHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36';
Reply := lHTTP.Post('https://www.instagram.com/accounts/login/ajax/', Params);
finally
end;
finally
end;
Finally
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36';
lHTTP.Get('https://www.instagram.com/myusername/following/', TStream(nil));
Memo1.Lines.Add(Reply);
Finally
end;
end;
end;
On this line:
lHTTP.Get('https://www.instagram.com/myusername/following/', TStream(nil));
You are telling Get() to ignore the response body (AResponseContent=nil), and then you are not assigning the new response to your Reply variable, so you are displaying the old Reply value from the earlier login response.
To get the HTML of the /following page, use this instead
Reply := lHTTP.Get('https://www.instagram.com/myusername/following/');
However, if you look at the actual HTTP requests that a web browser makes, you will see that clicking on the Following link on your profile page actually sends an AJAX POST request to the following URL to receive a JSON document listing the followers:
https://www.instagram.com/query/
Containing a query string in the POST body. You need to replicate that AJAX request, eg:
var
//...
userid: string; // <-- add this
begin
// after your AJAX login...
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36';
lHTTP.Request.Connection := 'keep-alive';
lHTTP.Get('https://www.instagram.com/myusername/', TStream(nil));
cookie := lHTTP.CookieManager.CookieCollection.Cookie['csrftoken', 'www.instagram.com'];
if cookie <> nil then
token := cookie.Value
else
token := '';
cookie := lHTTP.CookieManager.CookieCollection.Cookie['ds_user_id', 'www.instagram.com'];
if cookie <> nil then
userid := cookie.Value; // <-- add this
Params.Clear;
Params.Add('q=ig_user(' + userid + ') {'+LF+
' follows.first(10) {'+LF+
' count,'+LF+
' page_info {'+LF+
' end_cursor,'+LF+
' has_next_page'+LF+
' },'+LF+
' nodes {'+LF+
' id,'+LF+
' is_verified,'+LF+
' followed_by_viewer,'+LF+
' requested_by_viewer,'+LF+
' full_name,'+LF+
' profile_pic_url,'+LF+
' username'+LF+
' }'+LF+
' }'+LF+
'}'+LF);
Params.Add('ref=relationships::follow_list');
lHTTP.Request.CustomHeaders.Values['X-CSRFToken'] := token;
lHTTP.Request.CustomHeaders.Values['X-Instagram-AJAX'] := '1';
lHTTP.Request.CustomHeaders.Values['X-Requested-With'] := 'XMLHttpRequest';
lHTTP.Request.Referer := 'https://www.instagram.com/myusername/';
lHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36';
Reply := lHTTP.Post('https://www.instagram.com/query/', Params);
// process Reply as needed ...
Now Reply should receive JSON containing the first 10 followers in your list.
I have the following problem: when I click a button on a site (http://domain-location.com) I receive information back to me and the url is changed to http://domain-location.com?key=value.
I want to create a sample http client to receive information easily. Here is my code:
function DoRequest(aVal: string): string;
const DOMAIN = 'http://domain-location.com';
var
request: TIdHTTP;
responseStream: TMemoryStream;
responseLoader: TStringList;
urlRequest: string;
begin
request := TIdHTTP.Create(nil);
responseStream := TMemoryStream.Create;
responseLoader := TStringList.Create;
try
try
// accept ranges didn't help
// request.Response.AcceptRanges := 'text/json';
// request.Response.AcceptRanges := 'text/xml';
urlRequest := DOMAIN + '?key=' + aVal;
request.Get(urlRequest, responseStream);
responseStream.Position := 0;
responseLoader.LoadFromStream(responseStream);
Result := responseLoader.Text;
except on E: Exception do
Result := e.Message;
end;
finally
responseLoader.Free;
responseStream.Free;
request.Free;
end;
end;
EDIT After the first answer I edited my function (still not working):
function DoRequest(aVal: string): string;
const DOMAIN = 'http://domain-location.com';
var
request: TIdHTTP;
responseStream: TMemoryStream;
responseLoader: TStringList;
urlRequest: string;
uri: TIdURI;
begin
request := TIdHTTP.Create(nil);
responseStream := TMemoryStream.Create;
responseLoader := TStringList.Create;
request.CookieManager := TIdCookieManager.Create(request);
uri := TIdURI.Create(DOMAIN);
try
try
// accept ranges didn't help
// request.Response.AcceptRanges := 'text/json';
// request.Response.AcceptRanges := 'text/xml';
urlRequest := DOMAIN + '?key=' + aVal;
request.CookieManager.AddServerCookie('cookie1', uri);
request.CookieManager.AddServerCookie('cookie2', uri);
request.CookieManager.AddServerCookie('cookie3', uri);
request.Get(urlRequest, responseStream);
responseStream.Position := 0;
responseLoader.LoadFromStream(responseStream);
Result := responseLoader.Text;
except on E: Exception do
Result := e.Message;
end;
finally
responseLoader.Free;
responseStream.Free;
request.Free;
end;
end;
And after I do the request the result is: HTTP1.1 403 Forbidden.
I inspected the page and the button I click is in a form like this:
<form action="http:/domiain.com" method="GET">
<input type="text" name="key">
<input type="submit" value="Click">
</form>
When I type http://domain-location.com?key=value there is no problem.
Any idea how to fix it?
The problem was with the UserAgent:
function DoRequest(aVal: string): string;
const DOMAIN = 'http://domain-location.com';
var
request: TIdHTTP;
urlRequest: string;
begin
request := TIdHTTP.Create(nil);
try
try
request.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36';
urlRequest := DOMAIN + '?key=' + aVal;
Result := request.Get(urlRequest);
except on E: Exception do
Result := e.Message;
end;
finally
request.Free;
end;
end;
If cookies are involved, then you should GET the original HTML page first so the server can send whatever cookies it needs to be posted back when the button is "clicked", then you can GET the next page and let TIdHTTP post whatever cookies it had received.
Try this:
function DoRequest(const aVal: string): string;
const
DOMAIN = 'http://domain-location.com';
var
request: TIdHTTP;
begin
try
request := TIdHTTP.Create(nil);
try
request.Get(DOMAIN, TStream(nil)); // get cookies, discard HTML
Result := request.Get(DOMAIN + '?key=' + TIdURI.ParamsEncode(aVal));
finally
request.Free;
end;
except
on E: Exception do
Result := e.Message;
end;
end;
Check the actual request that is sent by your browser. 403 suggests that there is some sort of authentication going on. This might be a token or a cookie that your browser has, and sends with the request, but your sample client application may not have. Open the browser debugging panel to check the get request made by your browser, and compare it to the one made by your application. I bet there will be some difference.