I am writing a win32 service in Delphi (should be able to translate any other code if you don't know delphi) that needs to fetch the status of a website. I know how to do this in .NET but am not sure with normal windows based programming. So, I need to query a website and return the Status Code 200, 301 ect. My plan is then to parse the data returned and send an email should one of my sites go down.
Can someone lend a hand?
EDIT: This is the code I used in the end - using the TIDHttp Indy component.
IdHTTP.Get('http://www.example.com');
if IdHTTP.Connected then begin
ResponseCode := IntToStr(IdHTTP.ResponseCode);
ShowMessage(ResponseCode);
end;
Take Indy or Synapse library (both are free, indy is included with Delphi, synapse is found on google) and use their HTTP client class to do the job.
Related
I want to build an application that is listening to the "sent mail" event of Lotus Notes and process the sent mail.
I am developing that with Delphi and since there is nothing else out there I guess I am stuck with using OLE (already using OLE to access selected mail from Lotus Notes and processing it).
So, is there a way to subscribe to some of the events of Lotus Notes and get the appropriate data using OLE ? (in this particular case, I would like to subscribe to the "sent mail" event, and get the mail document). I am also open to suggestions if somebody, with more Lotus Notes experience, knows some other way of doing that, but in the end I have to access the mail with Delphi.
The application should run on the client machine and not on the server.
Thanks
I'm assuming you want to do this client-side. Unfortunately, there is no way to subscribe to Notes client events via the OLE or COM interfaces provided in Notes and Domino. The only way to do that is with the Notes C API's Extenstion Manager interface, but this is really low-level stuff that requires extensive knowledge of Notes.
There is, however, a ready-made piece of code built with the Extension Manager called TriggerHappy, which is available as open source on the OpenNTF site. It allows you to configure it to invoke LotusScript agents that are triggered by events. That (somewhat) lowers the learning curve around this.
Actually, the COM interface to Lotus Notes is pretty well documented, maybe because it has been owned by IBM for over a decade. You'll find one way into it here:http://www.ibm.com/support/knowledgecenter/SSVRGU_9.0.0/com.ibm.designer.domino.main.doc/H_ACCESSING_THE_DOMINO_OBJECTS_THROUGH_COM.html.
For Delphi, you'll need to create an import unit, Domino_Tlb.Pas for Notes' COM interface; it's a while since I did it but I think you do that by using Delphi's TypeLib Importer on the Notes NlsXbe.Dll, which is part of both the Notes client and server installs.
AFAIR, Notes' COM support doesn't expose any COM events though, so there is no support for "subscriptions" in the sense of an outbound, event-driven interface. However, it is a commonplace with Notes to use its VB-like LotusScript language to write "agents" which can monitor mailfiles to trigger whatever actions are appropriate to whatever the business requirement happens to be. Because there are no "events", agents implemented using the COM interface these have to work by periodically polling the Notes database of interest, and there are functions available to search for previously-unprocessed mail items (sent or arrived). For instance, you could poll a Notes db's Inbox with code like this:
View := DB.GetView('($Inbox)');
Res := View.FTSEARCH('FIELD PostedDate < ''01/05/2012'' or FIELD DeliveredDate < ''01/05/2012''', 0);
Doc := View.GetFirstDocument;
Done := Doc <> Nil;
while not Done do begin
vFrom := Doc.GetItemValue('INetFrom');
[...]
Doc := View.GetNextDocument(Doc);
if Doc = Nil then
Done := True;
end;
Update: Agents written in LotusScript have access to a built-in collection UnprocessedDocuments that is unique to an individual agent so it can tell whether it has already processed a document (see http://www-12.lotus.com/ldd/doc/lotusscript/lotusscript.nsf/1efb1287fc7c27388525642e0074f2b6/fa9dc4724dab0fed8525642e007702d6?OpenDocument). I don't recollect whether this would work for a COM agent, but I doubt it would matter if it didn't because a COM agent could always write a custom Item of its own to a document to indicate that it had processed it.
ISTR that it could be fairly irksome to find out what Notes fields are used for which purpose.
Working with Notes documents using the COM interface is pretty straightforward and when I was doing this sort of stuff a decade ago, I never came across any insurmountable hurdles to what I needed to do.
I doubt whether most Notes administrators would permit doing this sort of stuff on the Notes server, but it all works fine from a client machine and because of the built-in db replication support, you can do it either on the server version of the db or a local replica.
Essentially the same functionality as in LotusScript is available through the COM interface.
I'm afraid it had slipped my mind that you can install Java agents on the Domino server - see e.g. Running java agents in lotus notes. At my firm, we eliminated that as a possibility very early on because of the chaos-creating potential of a misbehaving agent on a live enterprise mail server.
I want to create an Exchange Web Services (EWS) client application using Delphi XE6.
I am using a THttpRio component with a wsdl. How do I set the user credentials? In other languages, the equivalent of the THttpRio component has a Credentials property (example).
But this is missing from the Delphi component.
The authentication mechanism (apart from impersonation) is not part of the ews wsdl. It is native to the SOAP layer.
Listing 1:
procedure TForm1.Button1Click( Sender: TObject);
var
lESB : ExchangeServicePortType;
request : GetServiceConfiguration;
Impersonation : ExchangeImpersonation;
RequestVersion: RequestServerVersion;
MailboxCulture1: MailboxCulture;
GetServiceConfigurationResult: GetServiceConfigurationResponse;
ServerVersion : ServerVersionInfo;
begin
lESB := HTTPRIO1 as ExchangeServicePortType;
request := GetServiceConfiguration.Create;
request.RequestedConfiguration := ArrayOfServiceConfigurationType.Create( 'UnifiedMessagingConfiguration');
Impersonation := ExchangeImpersonation.Create;
RequestVersion := RequestServerVersion.Create;
MailboxCulture1 := MailboxCulture.Create;
GetServiceConfigurationResult:= GetServiceConfigurationResponse.Create;
ServerVersion := ServerVersionInfo.Create;
try
lESB.GetServiceConfiguration(
request, Impersonation, RequestVersion, MailboxCulture1,
GetServiceConfigurationResult, ServerVersion)
finally
request.Free;
Impersonation.Free;
RequestVersion.Free;
MailboxCulture1.Free;
GetServiceConfigurationResult.Free;
ServerVersion.Free
end
end;
Listing 1 above, shows some sample code, that I have tried so far. The purpose of the function is to get the version information about the server. HTTPRIO1 is a THTTPRIO component with default properties, and hooked up to the standard wsdl for EWS. This doesn't work because user credentials are not set.
How to set the user credentials?
After a lot of trial and error, this is the solution that I came up with...
(1) Authentication
If using the THTTPRio component, the UserName/Password pair of properties of the HTTPWebNode property of the THHPRio can be used to identifiy the credentials of the user, from the perspective of establishing an internet connection through a proxy server.
If using the THTTPReqResp component, the same UserName/Password properties are directly owned by the component.
If using the TIdHTTP, there are proxy related properties to use.
If you want to use the credentials of the currently logged on, with explicitly passing the password onto the component, you can achieve this by leaving blank, the UserName and Password properties of the THTTPRio and THTTPReqResp components. Proxy information will be automatically picked up from the system registry. However TIdHTTP is different. This component required proxy configuration to be set up explicitly, including the credentials of the internet user.
(2) What component to use for EWS Soap transactions?
I could not get the standard soap solution, the THTTPRio component, to work. The problem was that the THTTPRio component did not produce the correct shape of request envelope. Without going into detail, there were numerous issues such as elements that should have been placed in the body, would appear in the header instead, and schema violations. If you can get this (THTTPRio based on the published wsdl) to work, (but I doubt it), it is worth noting that the wsdl needs to be tweeked to include the service node. Microsoft deliberately excluded the service node for security reasons, but it is needed for correct operation of the Delphi soap wizard.
Developing a solution based on TIdHTTP is a non-starter, if your application sits behind a firewall and must negotiate with a proxy server.
The simplest and best solution is to use the THTTPReqResp component. You don't even need the wisdl for this. You must craft your own xml request envelopes, but with Microsoft's excellent documentation, showing simple envelopes, this task is a doddle.
(3) On using THTTPReqResp to access EWS
EWS uses UTF-8, so set UseUTF8InHeader := True
Set InvokeOptions = [soIgnoreInvalidCerts, soAutoCheckAccessPointViaUDDI]
Set the URL to the service server URL, as required.
Set SoapAction to http://schemas.microsoft.com/exchange/services/2006/messages
Set UserName and Password as required, or leave empty to use the credentials of the logged-on user.
EWS uses soap 1.1, not 1.2, so exclude wnoSOAP12 from WebNodeOptions.
Leverage MSDN online. It's a superb resource with plenty of examples.
(4) On building XML documents.
Soap envelopes are XML documents following a specific published format, with your request data embedded. How to build these envelopes?
Here two possible ways that worked well for me:
Use a template software design pattern. For example I use a component very similar to the TPageProducer. The source your basic template, and you use tag replacement to achieve your desired result. My version of the PageProducer can define optional fragments, or fragments that are repeated n times (with different data per iteration), marked up within the one template.
Use XSLT. This is the simplest solution. It is almost code free.
Here are two possible ways, that you might use, but I recommend against. It is not that they do not work, but just that the techniques are too clumsy and take too much coding:
Manually construct the document as a string (or use string builder) part-by-part.
Build the document, part-by-part using the standard XML interfaces (IXMLNode etc), and then stream out the result.
We have a delphi XE application that uses SOAP (THTTPRIO etc) communications which (in delphi) works over WinInet.dll, by default. We fixed the authentication code so that it works, using https authentication, and when the user name and password for https are correct, everything is fine.
The problem is that when authentication details are incorrect, you get a message box from Windows, that is probably being popped up by WinInet.dll itself. I want to make that dialog box go away. I can't figure out how to change my Delphi SOAP so the password won't come up.
The situation is different than this question in the following ways:
I am doing all the things that he is doing, including calling InternetSetOption(...) to set the user name and password.
I am not using a server with a self-signed certificate, so the soIgnoreInvalidCerts flag is not applicable to my case.
Somehow, I think I need to get some API calls into WinInet to tell it not to pop up the InternetErrorDlg that it has (some versions of windows say Windows Security Options) that pops up to ask the user.
In my case the user name and password we have in our configuration file is being used, it is wrong (out of date) and so we want the WinInet code to simply return an error instead of popping up the dialog box.
Perhaps the other question the guy really did figure out how to do this, but the detail on that question is insufficient to see how he did it. The accepted answer does not work for me.
Some dead ends I've followed:
WinInet MSDN docs for PLUGIN_AUTH_FLAGS_CAN_HANDLE_UI - that doesn't appear to be applicable to a WinInet user, rather to a plugin.
WinInet MSDN docs discuss InternetSetOption, and some newsgroups have lead me to the following on-before-post event handler code:
procedure TMyDevice.HTTPWebNodeOnBeforePost(
const HTTPReqResp: SOAPHTTPTrans.THTTPReqResp; Data: Pointer);
var
SecurityFlagsLen:DWORD;
SecurityFlags:DWORD;
begin
{ authentication, NTLM+HTTPS, WinInet authentication set via WinInet SET INTERNET OPTION API.
This approach recommended on newsgroups for https basic authentication. }
if fUserName<>'' then
if not InternetSetOption(Data,
INTERNET_OPTION_USERNAME,
PChar(fUserName),
Length(fUserName)) then
raise EWebServiceAuthException.Create(SysErrorMessage(Windows.GetLastError));
if fPassword<>'' then
if not InternetSetOption(Data,
INTERNET_OPTION_PASSWORD,
PChar(fPassword),
Length (fPassword)) then
raise EWebServiceAuthException.Create(SysErrorMessage(Windows.GetLastError));
{ possible type of hackage: WinInet Security option flags to stop password box? }
SecurityFlagsLen := SizeOf(SecurityFlags);
InternetQueryOption({Request}data, INTERNET_OPTION_SECURITY_FLAGS,
Pointer(#SecurityFlags), SecurityFlagsLen);
SecurityFlags := SecurityFlags or SECURITY_FLAG_something;
InternetSetOption({Request}data, INTERNET_OPTION_SECURITY_FLAGS,
Pointer(#SecurityFlags), SecurityFlagsLen);
end;
This code makes the password work, but when the user's entered password is wrong, how do I get the SOAP call to fail, or raise an exception, instead of popping up a message box?
Replace WinINet by WinHTTP component. Both have very close APIs, and the 2nd does not create any UI interaction, but will return error codes, just like any other API. The UI part of WinINet may be a good idea for some software, but it sounds like if does not fit your needs.
See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384068(v=vs.85).aspx
Of course, HTTPS and authentication will be handled in a similar manner. But you'll have to prompt for the user name and password, and update the HTTP headers as requested. See this link.
From our tests, WinHTTP is much faster than WinINet (certainly because it does not implement any UI part, and is not linked to Internet Explorer libraries).
You can take a look at our Open Source classes to guess how small is the difference in the API between WinINet and WinHTTP (most code is shared in the linked unit).
Try modifying SOAPHTTPTrans to handle the error silently.
In THTTPReqResp.HandleWinInetError, there is ultimately a call to the error dialog:
Result := CallInternetErrorDlg
You can probably detect your particular error, you should be able to return a 0 from HandleWinInetError, or at least NOT make a call to CallInternetErrorDlg. See if that helps.
I am a new user in CBuilder Programming. I am writing HTTP Server application, which receives mixed data:both text and a binary data at a time. But I don't know which component and how to use to parse incoming request. My aim is to separate a text data from binary one. Can anybody show examples in Cbuilder or Delphi?
Try using indy, check the TIdHTTPServer component and the OnCommandGet event to process the GET, POST, and HEAD requests.
Trying to post data to https://www.facebook.com/login.php using synapse delphi library but without any result. The post data was got from mozila headers viewer.
Answers?
I assume you already know how to use HTTP Post with Synapse. If you also need HTTPS support, you will need at least release 36, and change some settings, such as port. Here is an example using TCP.