File upload as stand alone application running on Linux beyond an Apache server

In the previous blog post, a stand alone application (server) running on windows has been developed that server html file to upload file on the server. The stand alone application was accessible from 127.0.0.1:8080. The objective is now to run the standalone back end beyond an apache server. The html file will be obtained by the web browser by doing a get request on upload.launchs.space URL. From within this html a post request with an action attribute embedded in the form pointing to the URL upload.launchs.space/api/ will upload the file on the server.

The following html file is put on the server into /var/www/MultipartUploadV1/html and will be served by the apache server

<!DOCTYPE HTML>
<html>
    <head>
        <title>Multipart Upload Example</title>
    </head>
    <body>
        <form action="/api/" method="post" enctype="multipart/form-data">
            <label>Wählen Sie die hochzuladenden Dateien von Ihrem Rechner aus: <input name="datei[]" type="file" multiple>
            </label>
            <button>hochladen</button>
        </form>
    </body>
</html>

The next step is to configure Linux to be aware of the domain name launchs.space and subdomain upload.launchs.space. Usually domain resolution is done by a DNS server, but at this point we do not own the domain name so we must rely of file base domain name resolution at the Linux machine level. This is done using /etc/hosts file in Linux:

The next step is to  to associate an URL to the specific location of the html file use to upload files. This is done by creating a Virtual Host in Apache.

This is done simply by adding a new file onto the Linux server in etc/apache2/sites-available:

Then we must activate the subdomaine (see Configuring a Subdomain in Apache2)

sudo a2ensite upload.launchs.space

The next step is to let run the sandalone application on the linux machine.

Prerequiste for preparing the development environement (see embarcadero docwiki).

Next step, is to prepare the linux machine (see embarcadero docwiki). The PAServer will be extracted in /home/jacquot/PAServer (see how-to).


sudo tar -xf LinuxPAServer22.0.tar.gz

The PAServer location is :
/home/jacquot/PAServer/PAServer-22.0/

Note : the application is deployed in

/home/jacquot/PAServer/scratch-dir/alexa-ASUS Desktop linux/StandaloneUploadApp

Note: do no start paserver ./paserver with sudo

Standalone application works on linux :

There is a bug that need to be corrected when the application is running on linux OS. In Linux directory separator are / but in windows it is \.

The next step is to redirect the post request to the standalone application URL using an URL rewrite or a pass proxy within the Virtual Host configuration file (see background information).

I will rather use the ProxyPass method because it seems easier and quite flexible to pass parameter (see background information). But I will not need to pass parameter at this point. It is not needed.

So my upload.launchs.space.conf will look like this:

Note about how to enable reverse proxy and mode rewrite in Apache:

Then enable mode_rewrite module (background information):

sudo a2enmod rewrite

Enable reverse proxy module (module needed):

sudo a2enmod proxy
sudo a2enmod proxy_html
sudo a2enmod proxy_http 

Finally I am giving a proof that the application run under Linux beyond the apache server properly. Screenshot after having request upload.launchs.space page, select the file and click on upload:

Download link of the source code of this project

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% 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