Site Map Contact Us Home
E-mail Newsletter
Subscribe to get informed about
Clever Components news.

Your Name:
Your Email:
 
SUBSCRIBE
 
Previous Newsletters
 




Products Articles Downloads Order Support
Customer Portal      

Write your own HTTPS Server in Delphi


HTTPS Server Component

Introduction

This is a second edition of the Multithreaded HTTP Server in Delphi article, which introduces a fully functional multithreaded HTTP server component for Delphi.

In this new article, we have added the SSL / TLS support to the TclHttpServer component, implemented server-side certificate management, and updated the HttpServerDemo project. Now, this demo program allows you to run simple static website and access it using a web browser via HTTP or HTTPS protocols.

The TclHttpServer component is built based on the Clever Internet Suite library and uses the fast and stable classes: TclTcpServer, TclUserConnection, and TclThreadPool.

 

HTTP Implementation

The previous version of the TclHttpServer component utilized the TclTcpServer class from the Clever Internet Suite library for implementing low-level Network communication. There is one more class, TclTcpServerTls, that uses Microsoft Schannel and implements the SSL / TLS protocol. All you need is to inherit from this basic class and override some virtual methods.

// [Delphi]
TclHttpServer = class(TclTcpServerTls)
protected
   function CreateDefaultConnection: TclUserConnection; override;
   procedure DoReadConnection(AConnection: TclUserConnection; AData: TStream); override;
end;

// [Delphi]
function TclHttpServer.CreateDefaultConnection: TclUserConnection;
begin
   Result := TclHttpUserConnection.Create(HttpVersion, CharSet);
end;

// [Delphi]
procedure TclHttpServer.DoReadConnection(AConnection: TclUserConnection; AData: TStream);
begin
   inherited DoReadConnection(AConnection, AData);

   //handle the request data here
end;

 

A class that introduces a user connection (TclHttpUserConnection) should be inherited from the TclUserConnectionTls class. TclHttpUserConnection keeps all requests and response-related data: a request URI, an HTTP method, headers, cookies, an HTTP version, and a request body, as well.

// [Delphi]
TclHttpUserConnection = class(TclUserConnectionTls)
public
   function AcceptRequestData(AData: TStream): Boolean;

   property RequestVersion: TclHttpVersion read FRequestVersion;
   property RequestMethod: string read FRequestMethod;
   property RequestUri: string read FRequestUri;
   property RequestHeader: TclHttpRequestHeader read FRequestHeader;
   property RequestCookies: TStrings read FRequestCookies;

   property ResponseVersion: TclHttpVersion read FResponseVersion write FResponseVersion;
   property ResponseHeader: TclHttpResponseHeader read FResponseHeader;
   property ResponseCookies: TStrings read FResponseCookies;

   property RequestBody: TStream read FRequestBody write SetRequestBody;
end;

 

Accepted requests are handled within the DoReadConnection overridden method. This code simply reads the request body from a socket, extracts headers and other request-related data, and finally, calls to the OnRequestReceived event of the TclHttpServer component. All further request processing is performed outside the component.

// [Delphi]
procedure TclHttpServer.DoReadConnection(AConnection: TclUserConnection; AData: TStream);
var
   conn: TclHttpUserConnection;
begin
   inherited DoReadConnection(AConnection, AData);

   conn := TclHttpUserConnection(AConnection);
   try
      if conn.AcceptRequestData(ARequest) then
      begin
         // raises the OnReceiveRequest event
         DoReceiveRequest(conn, conn.RequestMethod, conn.RequestUri,
            conn.RequestHeader, conn.RequestBody);
      end;
   except
      on E: EclHttpServerError do
      begin
         SendResponseAndClose(conn, E.ErrorCode, E.Message, E.Message);
      end;
   end;
end;

 

SSL / TLS Implementation

To enable the HTTPS protocol, you need to use the component in SSL / TLS mode. There is a special property that does all the work: TclHttpServer.UseTLS. You need to use the implicit flag to enable HTTPS. If this property equals to stNone, the component works in non-secure HTTP mode. The UseTLS property accepts two more flags: stExplicitAllow and stExplicitRequire. Both these flags are intended to explicitly start a secure connection, and they are not used in the TclHttpServer component. The TclTcpServerTls class represents a basic functionality for implementing different Network protocols, including IMAP and SMTP. The mentioned flags are used by these protocols to explicitly initialize a secure session after receiving a special command from a client. These flags are not used to start SSL / TLS since the HTTP protocol doesn’t support such a command.

After assigning an appropriate TLS mode, you need to set up the HTTP binding port. In case of non-secure HTTP protocol, the default port number equals to 80. For HTTPS, the port is 443.

 

The Server Certificate

The TclTcpServerTls class provides a special OnGetCertificate event that allows you to specify a server certificate, which will be used during the SSL / TLS handshake. You can use the TclCertificateStore component to load a certificate from a file or from the Windows registry:

// [Delphi]
procedure TForm1.HttpsServerGetCertificate(Sender: TObject;
   var ACertificate: TclCertificate; AExtraCerts: TclCertificateList;
   var Handled: Boolean);
begin
   if CertificateStore.Items.Count = 0 then
   begin
      CertificateStore.ImportFromPFX(edtCertificate.Text, edtPassword.Text);
   end;
   ACertificate := CertificateStore.Items[0];
   Handled := True;
end;

 

When a web browser opens an SSL-protected web site, server credentials are validated. A web server must provide its certificate to a client, and this certificate must satisfy strong requirements:

  • The certificate’s Common Name (CN) must correspond to a website’s domain;
  • A certificate must have a valid date period;
  • A certificate must support the SSL server authentication;
  • A certificate should be issued by a valid certificate authority.

 

For testing purposes, you can use a self-signed certificate. Usually, this causes problems and additional warnings from a web browser. E.g., Chrome shows a message that describes an error and provides two options: exit the website browsing, or continue at your own risk. If you want to test or debug the TclHttpServer component, you can go ahead and confirm further website browsing.

When running your app in production, you should obtain a corresponding certificate from one of the authority centers, such as Comodo, Thawte, etc.

If you are planning to use your solution locally within your own Network, you can generate a root certificate and install it on all website’s clients to the CA registry storage. Next, generate a new server certificate and sign it using this root certificate. This will allow you to pass the server validation process by web browsers and open the website. Check out the Certificate Manager program. This program allows you to list, manage, create, import, and export certificates. You can generate all required certificates using this simple app.

 

Other SSL / TLS Options

There are more several important options that allow you to set up the TLS protocol version, make the component to use strong cryptographic algorithms, change the security package being used, and require a client certificate when establishing a secure connection.

// [Delphi]
TclTcpServerTls = class(TclTcpServer)
...
published
   property UseTLS: TclServerTlsMode read FUseTLS write FUseTLS;
   property TLSFlags: TclTlsFlags read FTLSFlags write FTLSFlags default [tfUseTLS, tfUseTLS11, tfUseTLS12];
   property SendRootCertificate: Boolean read FSendRootCertificate write FSendRootCertificate;
   property UseStrongCryptoAlgorithms: Boolean read FUseStrongCryptoAlgorithms write FUseStrongCryptoAlgorithms;
   property SecurityPackage: string read FSecurityPackage write FSecurityPackage;
   property RequireClientCertificate: Boolean read FRequireClientCertificate write FRequireClientCertificate;

   property OnGetCertificate: TclGetCertificateEvent read FOnGetCertificate write FOnGetCertificate;
   property OnVerifyClient: TclVerifyClientEvent read FOnVerifyClient write FOnVerifyClient;
end;

 

Testing the HTTP Server

To test the TclHttpServer component, let’s write a simple app that keeps two instances of this component for both non-secure HTTP and SSL / TLS encrypted HTTPS bindings. The program allows you to import a server certificate from a .pfx file or generate a self-signed certificate for testing purposes.

This HttpServerDemo program can run a simple website, containing HTML documents, images, file downloads, and other static resources. You can load requested pages using the Delphi string list and send to a client using the TclHttpServer.SendResponse method. In case if a requested page does not exist, the server returns the 404’th response.

This program is mostly simple demos, and by no means, a completed application. It provides only basic functionality and can support static web pages or dynamic responses that were generated by your code in Delphi. If you need to run server-side scripting, you can consider incorporating a third-party solution, which can run JavaScript and supports server objects.

 

What’s Next

In the next version of the TclHttpServer component, we will add user authorization algorithms, such as Basic, Digest, NTLM, and Negotiate.

Support for multiple websites will require a CGI gateway to be implemented. CGI is a big standalone task that is out of the scope of this project. The server can accept any HTTP method. But the current version of the HttpServerDemo program implements the only one HTTP method - GET. To get a complete HTTP protocol support (see RFC 2616), we need to implement all declared methods, status code handling, and many more. In addition, we need to support the new HTTP 2.0, which was introduced several years ago. Future versions of the HTTP server project will include more supported features and examples of using. You are welcome to comment and suggest any improvements, new features, and bug fixes.

 

Downloads

Download HttpServer Component and Demo Program on GitHub

Clever Internet Suite Download

Learn more about Clever Internet Suite Library

Ask a Question

 

Sergey Shirokov
Clever Components team
www.clevercomponents.com

    Copyright © 2000-2024