Files upload with Delphi as standalone application on the server and pure html on the internet browser side

Introduction

If you want to develop a content management system as a web application in Delphi on the server, you will almost inevitably need at some point to let the user upload files on the server from the internet browser. In this post we are providing the source code

of a minimalist fully functioning http server running on 127.0.0.1:8080 as a stand alone console application. Note at this point of time the server run under windows solely. But it will be adapt to run under Linux too in the next blog post.

The application serve a html file with no java script that let the user upload on the server selected files from within the browser. The application has been coded in Delphi 10.4. The free community edition is likely to be enough to compile and run the source code. You do not need a dedicated server. You can test the project on the local machine. At the core of the application is the socket library Internet Direct (Indy). The component are included in Delphi, so you do not need to install something else than Delphi (the components can also be downloaded separately on GitHup).

The application has been written based on the information provided on Stackoverflow. A blog post made me aware of the existence of the source code draft, but I find out that the source code provided was not enough to write a working application without further investigation.

Investigation and implementation

I find out that the files (a mp3, a jpg and text files) that were uploaded on the server using the code provided on Stackoverflow even with the patch proposed by Remi Lebeau were corrupted. But I have to underlined that Remi provides 99,5{010f809ad844fbb5e56f69c1d745ee36b243853a524a292b4c4e51d6a7e6b1fb} of the information to solve the problem. The problem was not only the CR and LF characters added at the end of the files but almost every byte of data were modified. The solution was to use a binary encoding (like 8 bit encoding but without the limit on the size of the attachments) for all content type with the exception of application/mac-binhex40 that remains encoded using binhex40. So in my source code 7 bit is never used.

There are maybe some use cases when 7 bit may be preferable than binary but decoding all files assuming a binary encoding work for me and will likely work for you. It must be underlined that Indy Components are used since very long time in many applications and it is a very bad practice to modify the components that are delivered in Delphi. It is also dangerous because the components may also fulfilled some specification even if these may be also outdated. So the component are not patched (must not be patched? will not be patched in future?). The solution that I did use is to derived a class (TIdMessageDecoderMIME2) based on the IdMessageCoderMIME found in

C:\Program Files (x86)\Embarcadero\Studio\21.0\source\Indy\IdMessageCoderMIME.pas

and to used the derived class in IndyMultipartUploadDemo.dpr. By doing so I am not touching the Delphi installation that stay intact.

I have also extend the html file to be able to selects multiple file to make sure that the upload works with all file formats at once.

Background information

HTML multipart/form-data

The blog post provides html snippets to up load file from within the internet browser using html only. Provide example for single and multiple files selection.

Useful tools

HexCmp2

HexCmp2 : Compare Hex values of two files.

WinMerge

WinMerge: return a more visual information about the comparison that is usefully when the files are larges.

Postman

Site to download Postman. Used to test Rest API.
Information about how to send application/json data along with file in postman multipart/form-data post request.
Information about how to allow specifying Content Type on single part of a Multipart request

Alternatives

Files upload with c# on the server and pure html in the internet browser.

Brook is a cross-platform microframework which helps to develop web Pascal applications built by Delphi or Lazarus IDE and Free Pascal. This framework support uploading files (using multipart/form-data). There nice code samples to learn using this powerful and light weight framework framework. You can install Brook from within Delphi IDE using the integrated GetIt package manager.

DMVCFramework is also quite well documented framework for developing REST server with code samples for uploading files.

What is be the next steps

The next step is to run the standalone application on Linux but beyond an Apache server. There are many advantages of running the the backend application for uploading files beyond an apache server:

The first advantage is that Apache can be configured to serve encrypted page (https). For the stand alone application serving uploading file, this is therefore not a must have requirement.

The second advantage is that is not good practice to expose other port than 80 (http) or 443 (https) to the outside world. This is because other port need to be allowed by the firewall. It is also much cleaner and maintainable to have one entry door.

The third advantage is that the static html file for the file upload can be served directly by the apache server. As a side effect, there is a better decoupling between the front end and back end programming. The result is projects that can be maintained by more specialized developer.


Next part