Open source REST client libraries for Delphi

delphi-oop

delphi-oop includes a REST client to consume RESTful web services using your own annotated class (similar to JAX-RS). It supports Google OAuth 2.0 authentication. The library is mostly tested with Delphi XE and hosted on Google Code at https://code.google.com/p/delphi-oop/

Code example: (more examples on the project page)

TODataNorthwindClient = class(TSvRESTClient)
  public
    [GET] [Path('/Customers')] [Consumes(MEDIA_TYPE.JSON)]
    function GetCustomers(): TCustomers; virtual;
  end;

delphi-rest-client-api

This library by Fabricio Colombo to consume RESTful web services supports two implementations, using Indy 10 and WinHTTP. The API was tested in Delphi XE, XE2 and XE3 and is hosted on Github at https://github.com/fabriciocolombo/delphi-rest-client-api

Code example:

var
  vPerson : TPerson;
begin
  vPerson := RestClient.Resource('http://localhost:8080/java-rest-server/rest/person/1')
                     .Accept(RestUtils.MediaType_Json)
                     .Get<TPerson>();

Open source SAX parsers for Delphi and Free Pascal

SAX (Simple API for XML) provides a mechanism for reading data from an XML document that is an alternative to that provided by the Document Object Model (DOM). Where the DOM operates on the document as a whole, SAX parsers operate on each piece of the XML document sequentially.

SAX is supported by several libraries for Delphi and Free Pascal, some open source libraries are:

WMF to PNG conversion support in ScroogeXHTML for the Java platform 4.4

The RTF to HTML / XHTML library ScroogeXHTML for the Java™ platfom introduces support for embedded WMF images in the upcoming 4.4 release. The conversion uses the Apache Batik transcoder to generate PNG files for all embedded WMF files of type EM_ANISOTROPIC.

ScroogeXHTML is also available for Delphi and Free Pascal.

Habarisoft on-line demo pages migrate to secure domain

Habarisoft started migrating demo web pages for its libraries to the secure domain https://secure.habariwebcomponents.de.

*) the Habari Web Components demo pages include links to non-secure resources (http instead of https) so they may cause browser security warnings.

 

ScroogeXHTML 6.7 – fast RTF to HTML / XHTML converter

Habarisoft is pleased to announce the release of ScroogeXHTML 6.7, a fast RTF to HTML / XHTML converter library for Delphi and Free Pascal. This is mainly a bug fix release.

New in release 6.7

  • Support for mixed case RTF tokens
  • Fixed support for output without indentation (SCROOGE_NO_INDENT option)
  • Updated documentation
  • Removed debug mode (replaced by unit tests)
  • Removed incomplete Linux support code
  • Fixed conditional DecimalSeparator unit reference
  • Minor changes, cleanup and fixes

A off-line demo version, the “Getting Started” guide (PDF) and the complete API documentation are available. An interactive on-line demo is available for the ScroogeXHTML library for the Java™ platform.

 

Websocket client and server library for Delphi

Andre Mussche, author of AsmProfiler, has released a WebSocket implementation for Delphi, based on Internet Direct (Indy). It includes both client and server code and is available on Github at https://github.com/andremussche/DelphiWebsockets.

WebSocket is a web technology providing for bi-directional, full-duplex communications channels over a single TCP connection.

Send secure SMTP email from Delphi applications

Introduction

Sending email from Windows, Android and iOS Delphi applications over public SMTP servers requires an encrypted connection. Internet Direct (Indy) configuration for SSL/TLS connections is shown in this example source code.

Disclaimer

This code is mostly based on code posted in the Embarcadero forum and here.

Example usage

procedure TFormMailDemo.ButtonSendClick(Sender: TObject);
var
  Mail: TSSLEmail;
begin
  if EditToEmail.Text <> '' then
  begin
    Mail := TSSLEmail.Create('mail.example.com', 465,
      'me@example.com', '***');

    try
      Mail.edSenderName := 'ABC Inc.';
      Mail.edSenderEmail := 'abc@example.com';
      Mail.edToEmail := EditToEmail.Text;
      Mail.edSubject := EditSubject.Text;
      Mail.edBody := MemoBody.Lines;

      Mail.SendEmail;

      EditToEmail.Text:='';
      EditSubject.Text:='';
      MemoBody.Clear;
    finally
      Mail.Free;
    end;
  end;
end;

Requirements

The code requires Internet Direct (Indy) version 10.6.
Note that the application needs the SSL dynamic link libraries, which can be found at indy.fulgan.com/SSL.

Supported platforms

The code has been tested with Delphi 2009 on Windows. The original code in the linked article reportedly works with Android.
For iOS, please also read this article.

Feedback and support

Feedback is welcome, please visit Habarisoft web page to find contact information. The source code is unsupported example code, use it at your own risk.

Source code

The source code for the SSL mail unit is shown below.

unit IndySecureMailClient;

interface

uses
  IdMessage, Classes, IdSMTP;

const
  SMTP_PORT_EXPLICIT_TLS = 587;

type
  TSSLEmail = class(TObject)
  private
    IdMessage: TIdMessage;
    SMTP: TIdSMTP;

    FedBody: TStrings;
    FedSMTPPort: Integer;
    FedToEmail: string;
    FedSubject: string;
    FedSMTPServer: string;
    FedCCEmail: string;
    FedPassword: string;
    FedBCCEmail: string;
    FedSenderName: string;
    FedUserName: string;
    FedPriority: TIdMessagePriority;
    FedSenderEmail: string;
    FedSSLConnection: Boolean;

    // Getter / Setter
    procedure SetBody(const Value: TStrings);

    procedure Init;
    procedure InitMailMessage;
    procedure InitSASL;
    procedure AddSSLHandler;

  public
    constructor Create; overload;
    constructor Create(const ASMTPServer: string;
      const ASMTPPort: Integer;
      const AUserName, APassword: string); overload;

    destructor Destroy; override;

    procedure SendEmail;

    // Properties
    property edBCCEmail: string read FedBCCEmail write FedBCCEmail;
    property edBody: TStrings read FedBody write SetBody;
    property edCCEmail: string read FedCCEmail write FedCCEmail;
    property edPassword: string read FedPassword write FedPassword;
    property edPriority: TIdMessagePriority read FedPriority write FedPriority;
    property edSenderEmail: string read FedSenderEmail write FedSenderEmail;
    property edSenderName: string read FedSenderName write FedSenderName;
    property edSMTPServer: string read FedSMTPServer write FedSMTPServer;
    property edSMTPPort: Integer read FedSMTPPort write FedSMTPPort;
    property edSSLConnection: Boolean read FedSSLConnection write FedSSLConnection;
    property edToEmail: string read FedToEmail write FedToEmail;
    property edUserName: string read FedUserName write FedUserName;
    property edSubject: string read FedSubject write FedSubject;

  end;

implementation

uses
  IdComponent, IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase,
  IdMessageClient, IdSMTPBase, IdBaseComponent, IdIOHandler,
  IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdSASLLogin,
  IdSASL_CRAM_SHA1, IdSASL, IdSASLUserPass, IdSASL_CRAMBase, IdSASL_CRAM_MD5,
  IdSASLSKey, IdSASLPlain, IdSASLOTP, IdSASLExternal, IdSASLDigest,
  IdSASLAnonymous, IdUserPassProvider;

constructor TSSLEmail.Create;
begin
  inherited;

  Init;

  FedBody := TStringList.Create;
end;

procedure TSSLEmail.Init;
begin
  edSSLConnection := True;
  edPriority := TIdMessagePriority.mpNormal;
end;

constructor TSSLEmail.Create(const ASMTPServer: string;
  const ASMTPPort: Integer; const AUserName, APassword: string);
begin
  Create;

  edSMTPServer := ASMTPServer;
  edSMTPPort := ASMTPPort;
  edUserName := AUserName;
  edPassword := APassword;
end;

destructor TSSLEmail.Destroy;
begin
  edBody.Free;

  inherited;
end;

// Setter / Getter -----------------------------------------------------------

procedure TSSLEmail.SetBody(const Value: TStrings);
begin
  FedBody.Assign(Value);
end;

// Send the mail -------------------------------------------------------------

procedure TSSLEmail.SendEmail;
begin
  IdMessage := TIdMessage.Create;
  try
    InitMailMessage;

    SMTP := TIdSMTP.Create;
    try
      if edSSLConnection then
      begin
        AddSSLHandler;

        if edSMTPPort = SMTP_PORT_EXPLICIT_TLS then
          SMTP.UseTLS := utUseExplicitTLS
        else
          SMTP.UseTLS := utUseImplicitTLS;
      end;

      if (edUserName<>'') or (edPassword<>'') then
      begin
        SMTP.AuthType := satSASL;
        InitSASL;
      end
      else
      begin
        SMTP.AuthType := satNone;
      end;

      SMTP.Host := edSMTPServer;
      SMTP.Port := edSMTPPort;
      SMTP.ConnectTimeout := 30000;
      SMTP.UseEHLO := True;
      SMTP.Connect;

      try
        SMTP.Send(IdMessage);
      finally
        SMTP.Disconnect;
      end;
    finally
      SMTP.Free;
    end;
  finally
    IdMessage.Free;
  end;
end;

// Prepare the mail ----------------------------------------------------------

procedure TSSLEmail.InitMailMessage;
begin
  IdMessage.ContentType := 'text/plain';
  IdMessage.Charset := 'UTF-8';
  IdMessage.Body := edBody;
  IdMessage.Sender.Text := edSenderEMail;
  IdMessage.From.Name := edSenderName;
  IdMessage.From.Address := edSenderEMail;
  IdMessage.ReplyTo.EMailAddresses := edSenderEmail;
  IdMessage.Recipients.EMailAddresses := edToEmail;
  IdMessage.Subject := edSubject;
  IdMessage.Priority := edPriority;
  IdMessage.CCList.EMailAddresses := edCCEMail;
  IdMessage.ReceiptRecipient.Text := '';
  IdMessage.BccList.EMailAddresses := edBCCEMail;
end;

procedure TSSLEmail.AddSSLHandler;
var
  SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
  SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(SMTP);
  // SSL/TLS handshake determines the highest available SSL/TLS version dynamically
  SSLHandler.SSLOptions.Method := sslvSSLv23;
  SSLHandler.SSLOptions.Mode := sslmClient;
  SSLHandler.SSLOptions.VerifyMode := [];
  SSLHandler.SSLOptions.VerifyDepth := 0;
  SMTP.IOHandler := SSLHandler;
end;

procedure TSSLEmail.InitSASL;
var
  IdUserPassProvider: TIdUserPassProvider;
  IdSASLCRAMMD5: TIdSASLCRAMMD5;
  IdSASLCRAMSHA1: TIdSASLCRAMSHA1;
  IdSASLPlain: TIdSASLPlain;
  IdSASLLogin: TIdSASLLogin;
  IdSASLSKey: TIdSASLSKey;
  IdSASLOTP: TIdSASLOTP;
  IdSASLAnonymous: TIdSASLAnonymous;
  IdSASLExternal: TIdSASLExternal;
begin
  IdUserPassProvider := TIdUserPassProvider.Create(SMTP);
  IdUserPassProvider.Username := edUserName;
  IdUserPassProvider.Password:= edPassword;

  IdSASLCRAMSHA1 := TIdSASLCRAMSHA1.Create(SMTP);
  IdSASLCRAMSHA1.UserPassProvider := IdUserPassProvider;
  IdSASLCRAMMD5 := TIdSASLCRAMMD5.Create(SMTP);
  IdSASLCRAMMD5.UserPassProvider := IdUserPassProvider;
  IdSASLSKey := TIdSASLSKey.Create(SMTP);
  IdSASLSKey.UserPassProvider := IdUserPassProvider;
  IdSASLOTP := TIdSASLOTP.Create(SMTP);
  IdSASLOTP.UserPassProvider := IdUserPassProvider;
  IdSASLAnonymous := TIdSASLAnonymous.Create(SMTP);
  IdSASLExternal := TIdSASLExternal.Create(SMTP);
  IdSASLLogin := TIdSASLLogin.Create(SMTP);
  IdSASLLogin.UserPassProvider := IdUserPassProvider;
  IdSASLPlain := TIdSASLPlain.Create(SMTP);
  IdSASLPlain.UserPassProvider := IdUserPassProvider;

  SMTP.SASLMechanisms.Add.SASL := IdSASLCRAMSHA1;
  SMTP.SASLMechanisms.Add.SASL := IdSASLCRAMMD5;
  SMTP.SASLMechanisms.Add.SASL := IdSASLSKey;
  SMTP.SASLMechanisms.Add.SASL := IdSASLOTP;
  SMTP.SASLMechanisms.Add.SASL := IdSASLAnonymous;
  SMTP.SASLMechanisms.Add.SASL := IdSASLExternal;
  SMTP.SASLMechanisms.Add.SASL := IdSASLLogin;
  SMTP.SASLMechanisms.Add.SASL := IdSASLPlain;
end;

end.