I'm having trouble consuming the google safe browsing api v4. I'm sure this should be easy but its already taking me some time. I always get error 400 bad request. here is my code :
var
idHttp : TIdHTTPEx;
url : string;
slTemp : TStringList;
memoryStream : TMemoryStream;
begin
idHttp := TIdHTTPEx.Create(nil); // parent class is TIdHTTP, inherited to be able to execute HTTPS
slTemp := TStringList.Create;
memoryStream := TStringStream.Create;
try
idHttp.Request.ContentType := 'application/json';
url := 'https://safebrowsing.googleapis.com/v4/threatMatches:find?key=' + GOOGLE_SAFE_BROWSING_API_KEY + ' HTTP/1.1';
slTemp.Text := '{"client":{"clientId":"iGame","clientVersion":"1.0.0"},"threatInfo":{"threatTypes":"MALWARE","platformTypes":"WINDOWS","threatEntryTypes":"URL","threatEntries":[{"url":"http://www.hyxyg.com/default.php"},{"url":"https://jsonlint.com/"}]}}';
idHttp.Post(url, slTemp, memoryStream);
memo1.Text := memoryStream.ToString;
finally
memoryStream.Free;
slTemp.Free;
idHttp.Free;
end;
end;
I tried checking this but it is using lower version. Where did I go wrong?
EDIT
I tried using this as suggested by one of the comment, but still the same error 400 bad request. the example was OK though.
var
idHttp : TIdHTTPEx; // parent class is TIdHTTP, inherited to be able to execute HTTPS
url : string;
requestBody : TStream;
sTemp : string;
begin
url := 'https://safebrowsing.googleapis.com/v4/threatMatches:find?key=' + GOOGLE_SAFE_BROWSING_API_KEY + ' HTTP/1.1';
//url := 'https://httpbin.org/post';
idHttp := TIdHTTPEx.Create(nil);
requestBody := nil;
try
idHttp.Request.Accept := 'application/json';
idHttp.Request.ContentType := 'application/json';
sTemp := '{"client":{"clientId":"iGame","clientVersion":"1.0.0"},"threatInfo":{"threatTypes":"MALWARE","platformTypes":"WINDOWS","threatEntryTypes":"URL","threatEntries":[{"url":"http://www.hyxyg.com/default.php"},{"url":"https://jsonlint.com/"}]}}';
//sTemp := '{"日本語":42}';
requestBody := TStringStream.Create(sTemp, TEncoding.UTF8);
sTemp := idHttp.Post(url, requestBody);
memo1.Text := sTemp + sLineBreak + sLineBreak + idHttp.ResponseText;
finally
requestBody.Free;
idHttp.Free;
end;
end;
The " HTTP/1.1" at the end of the URI must be an error, try without it.
Related
I'm doing a HTTPS post with this code to azurewebsites.
http://MYAPP.azurewebsites.net/api/MYFUNC
I'm currently using this code:
procedure TForm1.OriginalTest();
var
lHTTP: TIdHTTP;
HTTPResult: string;
RequestBody: TStream;
URL: String;
Body: string;
IOHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
lHTTP := TIdHTTP.Create;
try
Body := '{}';
RequestBody := TStringStream.Create(Body, TEncoding.UTF8);
lHTTP.Request.Accept := '';
lHTTP.Request.UserAgent := '';
lHTTP.Request.CustomHeaders.Add('x-functions-key:<your api key>');
lHTTP.ConnectTimeout := 24000;
lHTTP.ReadTimeout := 24000;
IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
IOHandler.SSLOptions.Method := sslvTLSv1_2;
lHTTP.IOHandler := IOHandler;
try
URL := 'https://<yourapp>.azurewebsites.net/api/<funcname>';
HTTPResult := lHTTP.Post(url, RequestBody);
Memo1.Lines.Add(HTTPResult);
except
on E:Exception do
begin
Memo1.Lines.Add(Format('Error sending data. Error: %s', [E.Message] ));
end;
end;
finally
lHTTP.Free;
RequestBody.Free;
end;
end;
For whatever reason, this code gives me the following error:
Error sending data. Error: Socket Error # 10054 Connection reset by peer.
I tried making a simple HTTPS Post using .NET with HttpWebRequest , and it works fine. What am I doing wrong here?
I just gave up and used WinApi.WinInet instead.
I have valid access token to Dropbox account (API v2), Delphi 7 and, Indy 10.
When I try to use this token I have exception 'HTTP/1.1 400 Bad Request'.
I look at Dropbox API v2 and can't understand:
what's wrong with the request?
procedure TDropboxSaveFilterForm.TestButtonClick(Sender: TObject);
const
AccessToken = 'Hq7XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
var
IdHTTP: TIdHTTP;
Source: TStringList;
Res, URL: WideString;
begin
Source := TStringList.Create;
IdHTTP := TIdHTTP.Create(nil);
IdHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
URL := 'https://api.dropboxapi.com/2/files/list_folder' + '?' +
'Authorization=Bearer ' + AccessToken;
Res := IdHTTP.Post(URL, Source);
Source.Free;
end;
New code with the header, error the same :-(.
According to Indy: Request Specifies the header values to send to the HTTP server.
procedure TDropboxSaveFilterForm.TestHeaderButtonClick(Sender: TObject);
const
AccessToken = 'Hq7XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
URL = 'https://api.dropboxapi.com/2/files/list_folder';
var
IdHTTP: TIdHTTP;
Source: TStringList;
Head, Res: WideString;
Stream: TMemoryStream;
begin
Source := TStringList.Create;
IdHTTP := TIdHTTP.Create(nil);
IdHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
Head := 'Authorization: Bearer ' + AccessToken;
Stream := TMemoryStream.Create;
Stream.Write(Head, Length(Head));
Stream.Position := 0;
IdHTTP.Request.Source := Stream;
Res := IdHTTP.Post(URL, Source);
Source.Free;
end;
You are trying to put the authorization data in the request URL and in the request body. You should put it in the request headers instead. Use the TIdHTTP.Request.CustomHeaders property to send a custom Authorization header value, eg:
procedure TDropboxSaveFilterForm.TestHeaderButtonClick(Sender: TObject);
const
AccessToken = 'Hq7XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
URL = 'https://api.dropboxapi.com/2/files/list_folder';
var
IdHTTP: TIdHTTP;
Source: TStringStream;
Res: String;
Stream: TMemoryStream;
begin
Source := TStringStream.Create('JsonParamsHere');
try
IdHTTP := TIdHTTP.Create(nil);
try
IdHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
IdHTTP.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + AccessToken;
IdHTTP.Request.BasicAuthentication := False;
IdHTTP.Request.ContentType := 'application/json';
Res := IdHTTP.Post(URL, Source);
finally
IdHTTP.Free;
end;
finally
Source.Free;
end;
end;
I am using indys idhttp to submit an URL (post)
Procedure submit_post(url_string,EncodedStr:string;amemo:TMemo);
var
aStream: TMemoryStream;
Params: TStringStream;
begin
aStream := TMemoryStream.create;
Params := TStringStream.create('');
try
with Fmain.IdHTTP1 do
begin
Params.WriteString(EncodedStr);
Request.ContentType := 'application/x-www-form-urlencoded';
Request.Charset := 'utf-8';
try
Response.KeepAlive := False;
Post(url_string, params, aStream);
except
on E: Exception do
begin
Screen.Cursor := crDefault;
exit;
end;
end;
end;
aStream.WriteBuffer(#0' ', 1);
aStream.Position := 0;
amemo.Lines.LoadFromStream(aStream);
Screen.Cursor := crDefault;
finally
aStream.Free;
Params.Free;
end;
end;
It works like a charm for me. I am trying to submit a URL (post) with a parameter containing 300 chars, but will be splittet automatically by adding an "&" every 90 chars. So the server only receives 90 chars instead of 300.
How can I submit an URL with a 300 character parameter without this automatic separation ?
function SubmitPost(Params:String): string;
const
URL= 'http://xxxx.com/register.php?';
var
lHTTP: TIdHTTP;
Source,
ResponseContent: TStringStream;
I:Integer;
begin
lHTTP := TIdHTTP.Create(nil);
lHTTP.Request.ContentType := 'text/xml';
lHTTP.Request.Accept := '*/*';
lHTTP.Request.Connection := 'Keep-Alive';
lHTTP.Request.Method := 'POST';
lHTTP.Request.UserAgent := 'OS Test User Agent';
Source := TStringStream.Create(nil);
ResponseContent:= TStringStream.Create;
try
try
lHTTP.Post(URL+Params, Source, ResponseContent);
Result := ResponseContent.DataString;
except
//your exception here
end;
finally
lHTTP.Free;
Source.Free;
ResponseContent.Free;
end;
end;
Usage
mmo1.Text := SubmitPost('Username=xxxx&Password=xxxx');
I found the mistake. My Post function works perfectly, but the URL is built by params coming from a memo line. With "WantReturns = FALSE", I can build a URL with the maximum line length of the memo. I guess 1024 characters per line which is okay for me.
I try to upload file into dropbox.
I use dropbox api https://www.dropbox.com/developers/reference/api#files-POST
procedure TDropbox.Upload2;
const
URL = 'https://api-content.dropbox.com/1/files/dropbox/';
var
Response: String;
Params: TIdMultipartFormDataStream;
https: TIdHTTP;
SslIoHandler: TIdSSLIOHandlerSocket;
begin
https := TIdHTTP.Create(nil);
Params := TIdMultipartFormDataStream.Create();
try
SslIoHandler := TIdSSLIOHandlerSocket.Create(https);
SslIoHandler.SSLOptions.Method := sslvTLSv1;
SslIoHandler.SSLOptions.Mode := sslmUnassigned;
https.IOHandler := SslIoHandler;
Params.AddFormField('oauth_signature_method', 'PLAINTEXT');
Params.AddFormField('oauth_consumer_key', FAppKey);
Params.AddFormField('oauth_token', FOAuth.AccessToken);
Params.AddFormField('oauth_signature', FAppSecret + '&' + FOAuth.AccessTokenSecret);
Params.AddFile('file', 'C:\test.txt', 'application/octet-stream');
https.Post(URL + 'test.txt', Params);
finally
FreeAndNil(https);
FreeAndNil(Params);
end;
end;
I got "400 Bad request".
All tokens are correct (other api works well).
How pass parameters for this api?
Try this instead:
procedure TDropbox.Upload(const AFileName: String);
const
API_URL = 'https://api-content.dropbox.com/1/files_put/sandbox/';
var
URL: String;
https: TIdHTTP;
SslIoHandler: TIdSSLIOHandlerSocket;
begin
URL := API_URL+ExtractFileName(AFileName)
+ '?oauth_signature_method=PLAINTEXT&oauth_consumer_key=' + FAppKey
+ '&oauth_token=' + FOAuth.AccessToken
+ '&oauth_signature=' + FAppSecret + '%26' + FOAuth.AccessTokenSecret;
https := TIdHTTP.Create(nil);
try
SslIoHandler := TIdSSLIOHandlerSocket.Create(https);
SslIoHandler.SSLOptions.Method := sslvTLSv1;
SslIoHandler.SSLOptions.Mode := sslmUnassigned;
https.IOHandler := SslIoHandler;
https.Post(URL, AFileName);
finally
FreeAndNil(https);
end;
end;
Use %26 instead & in oauth_signature parameter. There is two values in one parameter concated by & symbol.
Pass file via TMemoryStream.
procedure TDropbox.Upload(const AFileName: String);
const
API_URL = 'https://api-content.dropbox.com/1/files_put/sandbox/';
var
URL: String;
Stream: TMemoryStream;
ShortFileName: String;
https: TIdHTTP;
SslIoHandler: TIdSSLIOHandlerSocket;
begin
if not FileExists(AFileName) then
begin
raise EInOutError.CreateFmt('File %s not found', [AFileName]);
end;
ShortFileName := ExtractFileName(AFileName);
URL := API_URL+ShortFileName
+ '?oauth_signature_method=PLAINTEXT&oauth_consumer_key=' + FAppKey
+ '&oauth_token=' + FOAuth.AccessToken
+ '&oauth_signature=' + FAppSecret + '%26' + FOAuth.AccessTokenSecret;
https := TIdHTTP.Create(nil);
Stream := TMemoryStream.Create;
try
SslIoHandler := TIdSSLIOHandlerSocket.Create(https);
SslIoHandler.SSLOptions.Method := sslvTLSv1;
SslIoHandler.SSLOptions.Mode := sslmUnassigned;
https.IOHandler := SslIoHandler;
Stream.LoadFromFile(AFileName);
https.Post(URL, Stream);
finally
FreeAndNil(Stream);
FreeAndNil(https);
end;
end;
I would ask if someone was kind enough to explain to me how to login at webpage from Delphi app. All the examples I've found here have proved useless to me or I'm doing something wrong. I'm tired of the search and the code that does not work.
There is no error message, I even get page code into Memo but seems it's code from login page (not account [dashboard] page) - seems this code can't pass auth at all and I don't know why.
What is wrong in this code :
procedure Login;
var
HTTP: TIdHTTP;
Param: TStringList;
S: String;
begin
HTTP := TIdHTTP.Create(nil);
HTTP.CookieManager := Main_Form.CookieManager;
Param := TStringList.Create;
Param.Clear;
Param.Add('login=example');
Param.Add('password=example');
try
HTTP.Get ('http://www.filestrum.com/login.html');
HTTP.Post('http://www.filestrum.com/login.html', Param);
S := HTTP.Get ('http://www.filestrum.com/?op=my_account');
Main_Form.Memo2.Lines.Add(S);
finally
HTTP.Free;
Param.Free;
end;
end;
or with this version :
procedure Login;
var
HTTP: TIdHTTP;
S: String;
begin
HTTP := TIdHTTP.Create(nil);
HTTP.CookieManager := Main_Form.CookieManager;
HTTP.Request.BasicAuthentication := True;
HTTP.Request.Username := 'example';
HTTP.Request.Password := 'example';
HTTP.AllowCookies := True;
HTTP.HandleRedirects := True;
S := HTTP.Get ('http://www.filestrum.com/?op=my_account');
Main_Form.Memo2.Lines.Add(S);
end;
Used Delphi XE2 and there is no way to make this code running and login. It's same with XE3 demo. As I said, I'm really tired searching some solution, waste days into it and nothing.
Please guys, some help here. Really need it.
Try something like this:
function Login: string;
var
IdHTTP: TIdHTTP;
Request: TStringList;
Response: TMemoryStream;
begin
Result := '';
try
Response := TMemoryStream.Create;
try
Request := TStringList.Create;
try
Request.Add('op=login');
Request.Add('redirect=http://www.filestrum.com');
Request.Add('login=example');
Request.Add('password=example');
IdHTTP := TIdHTTP.Create;
try
IdHTTP.AllowCookies := True;
IdHTTP.HandleRedirects := True;
IdHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
IdHTTP.Post('http://www.filestrum.com/', Request, Response);
Result := IdHTTP.Get('http://www.filestrum.com/?op=my_account');
finally
IdHTTP.Free;
end;
finally
Request.Free;
end;
finally
Response.Free;
end;
except
on E: Exception do
ShowMessage(E.Message);
end;
end;