How can I connect to the database and PHPMyAdmin in Delphi - delphi

I want to make the registration process a user name and password. I use Delphi 7. Component which can be done? (I know very little english, sorry.)

http request is easiest method (with GET, or POST), but preferred you'll want to use SSL if you dont want passwords/usernames passed along to your webserver un-encrypted.
Example of using POST request:
uses
IdHTTP;
function PostData(const URL: string; Params: TStrings): string;
var
IdHTTP: TIdHTTP;
begin
Result := '';
IdHTTP := TIDHttp.Create(nil);
try
IdHTTP.HandleRedirects := True;
IdHTTP.ReadTimeout := 5000;
Result := IdHTTP.Post(URL, Params);
finally
IdHTTP.Free;
end;
end;
Optionally you can write your own socket, but that will be more difficult because you'll have to write your own listener. (Which is usually not allowed on most shared hosting plans.)

Related

How to download a very simple HTTPS page in Delphi?

I tried a code I saw here but it didn't work for HTTPS. I need to download this page as a String, and add some Break lines on it to put the informations in order in a TMemo.
How to do it? I tried to use Indy but I failed because of the SSL.
I tried the solutions of this page: How to download a web page into a variable?
How to download this page https://api.rastrearpedidos.com.br/api/rastreio/v1?codigo=OP133496280BR thats just pure text and put in in a String? and also format it like that, in the lines of a TMemo:
"Objeto em trĂ¢nsito - por favor aguarde"
"cidade":"SAO JOSE DOS CAMPOS"
"uf":"SP"
"dataHora":"18/06/2021 16:53"
"descricao":"Objeto postado","cidade":"SAO JOSE DOS CAMPOS","uf":"SP"
It's portuguese, English isn't my first language. Thanks if you guys could help me. I Use the Embarcadero Delphi 10.2 Tokyo.
When using Indy, assuming you are using Indy's default TIdSSLIOHandlerSocketOpenSSL component for SSL/TLS support, then make sure you put the 2 OpenSSL DLLs, ssleay32.dll and libeay32.dll, in the same folder as your EXE. You can get them from here:
https://github.com/IndySockets/OpenSSL-Binaries
Note that TIdSSLIOHandlerSocketOpenSSL only supports up to OpenSSL 1.0.2. If you need to use OpenSSL 1.1.x instead (for TLS 1.3+, etc), then use this SSLIOHandler instead. You will have to obtain the relevant OpenSSL DLLs from elsewhere, or compile them yourself.
Either way, once you decide which SSLIOHandler you want to use, the code is fairly simple:
var
HTTP: TIdHTTP;
SSL: TIdSSLIOHandlerSocketOpenSSL;
Response: string;
begin
HTTP := TIdHTTP.Create(nil);
try
// configure HTTP as needed (version, headers, etc)...
SSL := TIdSSLIOHandlerSocketOpenSSL.Create(HTTP);
// configure SSL as needed (TLS versions, certificates, etc)...
HTTP.IOHandler := SSL;
Response := HTTP.Get('https://api.rastrearpedidos.com.br/api/rastreio/v1?codigo=OP133496280BR');
finally
HTTP.Free;
end;
// use Response as needed...
end;
You also can use:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
Request: TScHttpWebRequest;
Response: TScHttpWebResponse;
ResponseStr: String;
JSonValue: TJSonValue;
JsonArray: TJsonArray;
Name: String;
UserName: String;
Email: String;
begin
Request := TScHttpWebRequest.Create('https://jsonplaceholder.typicode.com/users');
try
Response := Request.GetResponse;
try
if Request.IsSecure then begin
ResponseStr := Response.ReadAsString;
JsonArray := TJSonObject.ParseJSONValue(ResponseStr) as TJsonArray;
try
for i:=0 to JsonArray.Count - 1 do begin
JsonValue := JsonArray.Items[i];
Name := JsonValue.GetValue('name');
UserName := JsonValue.GetValue('username');
Email := JsonValue.GetValue('email');
Memo1.Lines.Add('Name: ' + Name + ' - UserName: ' + UserName + ' - Email: ' + Email);
end;
finally
JsonArray.Free;
end;
end;
finally
Response.Free;
end;
finally
Request.Free;
end;
end;

How to call an iOS scheme

Trying to call an iOS scheme for iOS printing with Star printers and Delphi, and I am not sure how to call it or what component should I use, I am using iDHTTP to make the call. Star Printing Documentation: (http://www.starmicronics.com/support/sdkdocumentation.aspx) http://www.starmicronics.com/support/ZipFile.aspx?sat2=242&id=242&type=4&referrer=http://www.starmicronics.com/support/sdkdocumentation.aspx&tabText, Here is the code:
function PostExample: string;
var
server: TIdHttp;
Parameters,response: TStringStream;
begin
server := TIdHTTP.Create(nil);
response := TStringStream.Create;
Parameters := TStringStream.Create('=<PrintingData>&size=3&drawer=ahead&back= <Callback URL scheme>', TEncoding.UTF8);
server.Post('starpassprnt://v1/print/nopreview?html',Parameters,response);
end;
Thank you for your help!

Download a html page using url with parameters [duplicate]

There's a web services I want to call in my application, I can use it with importing the WSDL or by just use "HTTP GET" with the URL and parameters, so I prefer the later because it's simple thing.
I know I can use indy idhttp.get, to do the job, but this is very simple thing and I don't want to add complex indy code to my application.
UPDATE: sorry if I was not clear, I meant by "not to add complex indy code", that I don't want add indy components for just this simple task, and prefer more lighter way for that.
Calling a RESTful web service using Indy is pretty straight forward.
Add IdHTTP to your uses clause. Remember that IdHTTP needs the "HTTP://" prefix on your URLs.
function GetURLAsString(const aURL: string): string;
var
lHTTP: TIdHTTP;
begin
lHTTP := TIdHTTP.Create;
try
Result := lHTTP.Get(aURL);
finally
lHTTP.Free;
end;
end;
You could use the WinINet API like this:
uses WinInet;
function GetUrlContent(const Url: string): string;
var
NetHandle: HINTERNET;
UrlHandle: HINTERNET;
Buffer: array[0..1024] of Char;
BytesRead: dWord;
begin
Result := '';
NetHandle := InternetOpen('Delphi 5.x', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if Assigned(NetHandle) then
begin
UrlHandle := InternetOpenUrl(NetHandle, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0);
if Assigned(UrlHandle) then
{ UrlHandle valid? Proceed with download }
begin
FillChar(Buffer, SizeOf(Buffer), 0);
repeat
Result := Result + Buffer;
FillChar(Buffer, SizeOf(Buffer), 0);
InternetReadFile(UrlHandle, #Buffer, SizeOf(Buffer), BytesRead);
until BytesRead = 0;
InternetCloseHandle(UrlHandle);
end
else
{ UrlHandle is not valid. Raise an exception. }
raise Exception.CreateFmt('Cannot open URL %s', [Url]);
InternetCloseHandle(NetHandle);
end
else
{ NetHandle is not valid. Raise an exception }
raise Exception.Create('Unable to initialize Wininet');
end;
source: http://www.scalabium.com/faq/dct0080.htm
The WinINet API uses the same stuff InternetExplorer is using so you also get any connection and proxy settings set by InternetExplorer for free.
Actually code in accepted answer did't work for me. So I modified it a little bit so it actually returns String and gracefully closes everything after execution. Example returns retrieved data as UTF8String so it will work well for ASCII as well as for UTF8 pages.
uses WinInet;
function GetUrlContent(const Url: string): UTF8String;
var
NetHandle: HINTERNET;
UrlHandle: HINTERNET;
Buffer: array[0..1023] of byte;
BytesRead: dWord;
StrBuffer: UTF8String;
begin
Result := '';
NetHandle := InternetOpen('Delphi 2009', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if Assigned(NetHandle) then
try
UrlHandle := InternetOpenUrl(NetHandle, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0);
if Assigned(UrlHandle) then
try
repeat
InternetReadFile(UrlHandle, #Buffer, SizeOf(Buffer), BytesRead);
SetString(StrBuffer, PAnsiChar(#Buffer[0]), BytesRead);
Result := Result + StrBuffer;
until BytesRead = 0;
finally
InternetCloseHandle(UrlHandle);
end
else
raise Exception.CreateFmt('Cannot open URL %s', [Url]);
finally
InternetCloseHandle(NetHandle);
end
else
raise Exception.Create('Unable to initialize Wininet');
end;
Hope it helps for somebody like me who was looking for easy code how to retrieve page content in Delphi.
Cheers, Aldis :)
In newer Delphi versions it is better to use THTTPClient from System.Net.HttpClient unit, since it is standard and cross-platform. Simple example is
function GetURL(const AURL: string): string;
var
HttpClient: THttpClient;
HttpResponse: IHttpResponse;
begin
HttpClient := THTTPClient.Create;
try
HttpResponse := HttpClient.Get(AURL);
Result := HttpResponse.ContentAsString();
finally
HttpClient.Free;
end;
end;
If it's okay to download to a file, you can use TDownloadURL from the ExtActns unit. Much simpler than using WinInet directly.
procedure TMainForm.DownloadFile(URL: string; Dest: string);
var
dl: TDownloadURL;
begin
dl := TDownloadURL.Create(self);
try
dl.URL := URL;
dl.FileName := Dest;
dl.ExecuteTarget(nil); //this downloads the file
finally
dl.Free;
end;
end;
It's also possible to get progress notifications when using this. Simply assign an event handler to TDownloadURL's OnDownloadProgress event.
Using Windows HTTP API might be easy too.
procedure TForm1.Button1Click(Sender: TObject);
var http: variant;
begin
http:=createoleobject('WinHttp.WinHttpRequest.5.1');
http.open('GET', 'http://lazarus.freepascal.org', false);
http.send;
showmessage(http.responsetext);
end;
https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa382925.aspx
http://forum.lazarus.freepascal.org/index.php?topic=14609.0
Save a file downloaded via WinHTTP to disk, using Delphi XE
How to use "WinHttp.WinHttpRequest.5.1" asynchronously?
http://www.delphigroups.info/2/4/217167.html
https://github.com/fabriciocolombo/delphi-rest-client-api/blob/master/src/HttpConnectionWinHttp.pas
In the code above I imply that COM was already initialized for the main VCL thread. Reportedly it might not be always the case for simplistic apps or for LCL apps. Also it would definitely not be the case for async (multithread) work.
Below is the snippet from a real code running. Note - the functionality is bonus. It is not required to work. So while I do issue requests, I do not care about their results, that result is ignored and dumped.
procedure TfmHaspList.YieldBlinkHTTP(const LED: boolean; const Key_Hardware_ID: cardinal);
var URL: WideString;
begin
URL := 'http://127.0.0.1:1947/action.html?blink' +
IfThen( LED, 'on', 'off') + '=' + IntToStr(Key_Hardware_ID);
TThread.CreateAnonymousThread(
procedure
var Request: OleVariant;
begin
// COM library initialization for the current thread
CoInitialize(nil);
try
// create the WinHttpRequest object instance
Request := CreateOleObject('WinHttp.WinHttpRequest.5.1');
// open HTTP connection with GET method in synchronous mode
Request.Open('GET', URL, False);
// set the User-Agent header value
// Request.SetRequestHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0');
// sends the HTTP request to the server, the Send method does not return
// until WinHTTP completely receives the response (synchronous mode)
Request.Send;
// // store the response into the field for synchronization
// FResponseText := Request.ResponseText;
// // execute the SynchronizeResult method within the main thread context
// Synchronize(SynchronizeResult);
finally
// release the WinHttpRequest object instance
Request := Unassigned;
// uninitialize COM library with all resources
CoUninitialize;
end;
end
).Start;
end;
Use the Synapse TCP/IP function in the HTTPSEND unit (HTTPGetText, HTTPGetBinary). It will do the HTTP pull for you and doesn't require any external DLL's other than Winsock. The latest SVN release works perfectly well in Delphi 2009. This uses blocking function calls, so no events to program.
Update: The units are very light, and are not component based. The latest version from SVN runs perfectly well in Delphi XE4 also.
If your application is Windows-only, I would suggest using WinSock. It's simple enough, allows to execute any HTTP request, can work both synchronously and asynchronously (using non-blocking WSASend/WSARecv with callbacks or good old send/recv in a dedicated thread).

Seeing Indy Traffic in Fiddler

I think this is an easy question for someone familiar with Indy. I'm using Delphi 2010 and Indy 10. I am trying to get off the ground accessing an SSL web service. I think it will be a lot easier if I can get Fiddler to see my HTTP traffic. I have seen posts on StackOverflow that indicate it's no big thing to get Fiddler to see your Indy traffic, that you just have to configure the port to make it work. My question is how do you do that?
Here is my code so far:
procedure TForm1.Button1Click(Sender: TObject);
var slRequest: TStringList;
sResponse,
sFileName: String;
lHTTP: TIdHTTP;
lIOHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
sFileName := 'Ping.xml';
slRequest := TStringList.Create;
try
slRequest.LoadFromFile(sFileName);
lHTTP := TIdHTTP.Create(nil);
lHTTP.Intercept := IdLogDebug1;
lIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
lHTTP.IOHandler := lIOHandler;
sResponse := lHTTP.Post('https://FSETTESTPROD.EDD.CA.GOV/fsetservice', slRequest);
Memo1.Lines.Text := sResponse;
finally
lIOHandler.Free;
end;
finally
slRequest.Free;
end;
end;
Edit: If I don't use the proxy for Fiddler and click the button while Wireshark is running, I get this traffic in Wireshark.
You can set Indy to use the proxy fiddler provides easily by setting the ProxyParams:
try
lHTTP.IOHandler := lIOHandler;
lHTTP.ProxyParams.ProxyServer := '127.0.0.1';
lHTTP.ProxyParams.ProxyPort := 8888;
sResponse := lHTTP.Post('<URL>', slRequest);
Memo1.Lines.Text := sResponse;
finally
lIOHandler.Free;
end;
You should be able to see all traffic in Fiddler then.
Edit: If that does not work you can add a TIdLogDebug component and add it as interceptor (like you did in your question).
The OnReceive and OnSend events contain the complete headers sent and received aswell as the reply data:
procedure TForm10.captureTraffic(ASender: TIdConnectionIntercept;
var ABuffer: TArray<Byte>);
var
i: Integer;
s: String;
begin
s := '';
for i := Low(ABuffer) to High(ABuffer) do
s := s + chr(ABuffer[i]);
Memo1.Lines.Add(s);
end;

Download CSV in Delphi 5 with Indy

I know there's alot of Indy threads but I can't get one to match my case.
I have been given a URL with a username and password form. this then actions to a URL/reports.php on which there are multiple hyperlinks.
Each of these links will direct to a page with URL variables e.g. reports.php?report=variablename where a download will immediately start.
My thinking so far:
procedure TForm1.PostData(Sender: TObject);
var
paramList:TStringList;
url,text:string;
// IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocket1: TIdSSLIOHandlerSocket;
idLogFile1 : TidLogFile;
begin
idLogFile1 := TidLogFile.Create(nil);
with idLogFile1 do
begin
idLogFile1.Filename := 'C:\HTTPSlogfile.txt';
idLogFile1.active := True;
end;
IdHTTP1 := TIdHTTP.Create(nil);
IdSSLIOHandlerSocket1 := TIdSSLIOHandlerSocket.Create(nil);
IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv23;
IdHTTP1.IOHandler := IdSSLIOHandlerSocket1;
IdHTTP1.HandleRedirects := true;
IdHTTP1.ReadTimeout := 5000;
IdHTTP1.Intercept := idLogFile1;
paramList:=TStringList.create;
paramList.Clear;
paramList.Add('loguser=testuser');
paramList.Add('logpass=duke7aunt');
paramList.Add('logclub=8005');
url := 'https://www.dfcdata.co.uk/integration/reports.php?report=live';
try
IdHTTP1.Post(url,paramList);
except
on E:Exception do
begin
showMessage('failed to post to: '+url);
ShowMessage('Exception message = '+E.Message);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
reportType : String;
begin
PostData(Self);
reportType := 'live';
GetUrlToFile('',reportType+'.csv');
end;
procedure TForm1.GetUrlToFile(AURL, AFile : String);
var
Output : TMemoryStream;
success : Boolean;
begin
success := True;
Output := TMemoryStream.Create;
try
try
IdHTTP1.Get(AURL, Output);
IdHTTP1.Disconnect;
except
on E : Exception do
begin
ShowMessage('Get failed to GET from '+IdHTTP1.GetNamePath +'. Exception message = '+E.Message);
success := False;
end;
end;
if success = True then
begin
showMessage('Filed saved');
Output.SaveToFile(AFile);
end;
finally
Output.Free;
end;
end;
On each try I get "IOHandler is not valid" error. Obviously I'm not posting correctly to the initial page but can anyone advise me on what I'm missing? Also can I simply then hit the download URL after login or will I have to use cookies?
Thanks
There are several bugs in your code:
1) PostData() is requesting an HTTPS URL, but it is not assigning an SSL-enabled IOHandler to the TIdHTTP.IOHandler property. You need to do so.
2) Button1Click() is passing a URL to GetUrlToFile() that does not specify any protocol, so TIdHTTP will end up treating that URL as relative to its existing URL, and thus try to download from https://www.testurl.com/test/testurl.com/test/reports.phpinstead of https://testurl.com/test/reports.php. If you want to request a relative URL, don't include the hostname (or even the path in this case, since you are sending multiple requests to the same path, just different documents).
3) you are leaking the TIdHTTP object.
Issue 1) has now been resolved in another post:
Delphi 5 Indy/ics SSL workaround?
However I would greatly appreciate help on the rest, as follows.
Would I need to make a GET call with the same IdHTTP object and additional URL variable? or should I create a new IdHTTP object?
Would I need to record the session using cookies or can all of this be done with the same call?
Is the GET call above actually what I need to save a csv to file? I may also choose to handle it directly as the data will need importing anyway.
Currently the code gets the error: EIdHTTPProtocolException

Resources