Files upload with Delphi 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, 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.

The application serve an html file with no java script that let the user upload on the server selected files in 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% 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 that binary but decoding all file assuming a binary encoding work for me and will likely work for you. It must be underlined that Indy Component 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

What would be the next step

The logical next step is to modify the server code and use javascript in the html page to provide a feed back to the user about the upload progress. This is of course much more complicate and beyond the scope of this blog post. A good starting point is to read look in the following blog post how the html5/javascript code could look like.

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.