\n\tAllowOverride none\n\tRequire all denied\n\n\n#===============================================================================================================\n\n# The following lines prevent .htaccess and .htpasswd files from being viewed by Web clients.\n# This is an extra setting in case the global access right was allowed.\n# ensure the .ht files are store with lower case file names.\n# Apache is case sensitive on non Windows OS.\n\n\tRequire all denied\n\n\n# See default httpd.conf for more explanation about the following settings\n\n\tRequestHeader unset Proxy early\n\n\n\n\tTypesConfig conf/mime.types\n\tAddType application/x-compress .Z\n\tAddType application/x-gzip .gz .tgz\n\n\n# Configure mod_proxy_html to understand HTML4/XHTML1\n\n\tInclude conf/extra/proxy-html.conf\n\n\n# Secure (SSL/TLS) connections\n\n\tSSLRandomSeed startup builtin\n\tSSLRandomSeed connect builtin\n\n\n#===============================================================================================================\n\n# Using a VirtualHost section to configure which domain to process.\n# Multiple similar sections could be configures to host multiple domains.\n\n\n# localhost is 127.0.0.1, which is the IP the server is \"Listen\"ing on\n\tServerName localhost\n\n# Folder to use for \"/\" requests. The \"Directory\" section below is used to setup behavior in the root URL.\n\tDocumentRoot \"C:/Apache64Root/\"\n\n# Setting two virtual folders, to different FastCGI apps.\n\tAlias /fcgi_echo/ \"C:/Harbour_websites/fcgi_echo/website/\"\n\tAlias /fcgi_localsandbox/ \"C:/Harbour_websites/fcgi_LocalSandbox/website/\"\n\n#----------------------------------------------------------------------------------\n\n\n\tRequire all granted\n\tRewriteEngine On\n\n\t\n# Method to tell which file to serve if not page name is provided. Similar to IIS\'s \"default document\" setting.\n\t\tDirectoryIndex welcome.html\n# Specifies it the above redirect is visible of not. Using \"off\" for not visible.\n\t\tDirectoryIndexRedirect off\n\t\n\n\n# The following is an example to change a request to a static web page (.html), where the extension (.html) was not included.\n# For example if you have a web page readme.html, you could call http://localhost:8164/readme\n# Following Works by doing URL Redirect !!!\n\t\n\t\tRewriteCond %{REQUEST_FILENAME} !-f\n\t\tRewriteCond %{REQUEST_FILENAME} !-d\n\t\tRewriteCond %{REQUEST_FILENAME}\\.html -f\n\t\tRewriteRule ^(.+)$ %{REQUEST_URI}.html [R=301,L]\n\t\n\n\n\n#----------------------------------------------------------------------------------\n\n# The following are the settings for the echo FastCGI app.\n# The default page can be called with: http://localhost:8164/fcgi_echo/\n\n\t\n# You will need to at least enabled FollowSymLinks and ExecCGI\n\t\tOptions -Indexes -Includes +FollowSymLinks -MultiViews +ExecCGI\n\n# Had to do this, since we are using the mod_rewrite to remap the file to access. The Require happens before rewrites, which is a major problem.\n# The access right to files is going to be handled by the mod_rewrite instructions\n\t\tRequire all granted\n\n# This means all files ending with lower case \".exe\" will be processed as FastCGI EXEs.\n# This will ensure other files extensions will not be processed as FastCGI.\n\t\t\n\t\t\tSetHandler fcgid-script\n\t\t\n\n# To allow settings in .htaccess to do mod_rewrite, IndexOptions (See https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride)\n\t\tAllowOverride Indexes FileInfo\n\n# See https://httpd.apache.org/docs/trunk/rewrite/intro.html for Documentation on mod_rewrite\n# See https://perldoc.perl.org/perlrequick.html for Regular Expressions used with mod_rewrite\n\n\t\tRewriteEngine On\n\n\t\n\n#----------------------------------------------------------------------------------\n\n# The following virtual folder is user for the LocalSandbox.exe FastCGI app.\n\n# It could be called using: http://localhost:8164/fcgi_localsandbox/\n\n\t\n\t\tOptions -Indexes -Includes +FollowSymLinks -MultiViews +ExecCGI\n\t\tRequire all granted\n\n\t\t\n\t\t\tSetHandler fcgid-script\n\t\t\n\n\t\tAllowOverride Indexes FileInfo\n\t\tRewriteEngine On\n\n\t\n\n#----------------------------------------------------------------------------------\n\n\n\n#===============================================================================================================\n';};
File: httpd.conf
# Specify the location of the Apache server itself.Define SRVROOT "C:/Apache24-64"ServerRoot "${SRVROOT}"# This will in Apache to bind (listen) to port 127.0.0.1 aka localhost, and port 8164Listen 127.0.0.1:8164LoadModule alias_module modules/mod_alias.soLoadModule authz_core_module modules/mod_authz_core.soLoadModule dir_module modules/mod_dir.soLoadModule env_module modules/mod_env.soLoadModule include_module modules/mod_include.soLoadModule mime_module modules/mod_mime.soLoadModule setenvif_module modules/mod_setenvif.so# To change page/file extensionsLoadModule rewrite_module modules/mod_rewrite.so# This is the FastCGI Apache module that will manage single threaded Harbour FastCGI EXEsLoadModule fcgid_module modules/mod_fcgid.so<IfModule unixd_module> User daemon Group daemon</IfModule># Configuration for any FastCGI executable.<IfModule mod_fcgid.c># Should set at least as many Processes as there are FastCGI apps,# meaning number for Virtual folders with fcgi handlers. FcgidMaxProcesses 10# Make the following value big enough so to have the debugger stay open long enough if needed.# 1800 means 30 minutes. FcgidIOTimeout 1800# Use smaller value in case of memory leaks# This setting would do a forceful shutdown of FastCGI EXEs.# See Harbour_FastCGI for a soft shutdown settings instead. FcgidMaxRequestsPerProcess 1000000#Example of setting up some Environment Variables FcgidInitialEnv HB_ACCOUNT_ID UserName FcgidInitialEnv HB_ACCOUNT_PASSWORD Password</IfModule># 'Main' server configurationServerAdmin me@mydomain.comServerName localhost-apache-64:8164# By default we will forbid the use of .htaccess and turn off all access rights from all IPs<Directory /> AllowOverride none Require all denied</Directory>#===============================================================================================================# The following lines prevent .htaccess and .htpasswd files from being viewed by Web clients.# This is an extra setting in case the global access right was allowed.# ensure the .ht files are store with lower case file names.# Apache is case sensitive on non Windows OS.<Files ".ht*"> Require all denied</Files># See default httpd.conf for more explanation about the following settings<IfModule headers_module> RequestHeader unset Proxy early</IfModule><IfModule mime_module> TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz</IfModule># Configure mod_proxy_html to understand HTML4/XHTML1<IfModule proxy_html_module> Include conf/extra/proxy-html.conf</IfModule># Secure (SSL/TLS) connections<IfModule ssl_module> SSLRandomSeed startup builtin SSLRandomSeed connect builtin</IfModule>#===============================================================================================================# Using a VirtualHost section to configure which domain to process.# Multiple similar sections could be configures to host multiple domains.<VirtualHost *:8164># localhost is 127.0.0.1, which is the IP the server is "Listen"ing on ServerName localhost# Folder to use for "/" requests. The "Directory" section below is used to setup behavior in the root URL. DocumentRoot "C:/Apache64Root/"# Setting two virtual folders, to different FastCGI apps. Alias /fcgi_echo/ "C:/Harbour_websites/fcgi_echo/website/" Alias /fcgi_localsandbox/ "C:/Harbour_websites/fcgi_LocalSandbox/website/"#----------------------------------------------------------------------------------<Directory "C:/Apache64Root/"> Require all granted RewriteEngine On <IfModule dir_module># Method to tell which file to serve if not page name is provided. Similar to IIS's "default document" setting. DirectoryIndex welcome.html# Specifies it the above redirect is visible of not. Using "off" for not visible. DirectoryIndexRedirect off </IfModule># The following is an example to change a request to a static web page (.html), where the extension (.html) was not included.# For example if you have a web page readme.html, you could call http://localhost:8164/readme# Following Works by doing URL Redirect !!! <IfModule mod_rewrite.c> RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.html -f RewriteRule ^(.+)$ %{REQUEST_URI}.html [R=301,L] </IfModule></Directory>#----------------------------------------------------------------------------------# The following are the settings for the echo FastCGI app.# The default page can be called with: http://localhost:8164/fcgi_echo/ <Directory "C:/Harbour_websites/fcgi_echo/website/"># You will need to at least enabled FollowSymLinks and ExecCGI Options -Indexes -Includes +FollowSymLinks -MultiViews +ExecCGI# Had to do this, since we are using the mod_rewrite to remap the file to access. The Require happens before rewrites, which is a major problem.# The access right to files is going to be handled by the mod_rewrite instructions Require all granted# This means all files ending with lower case ".exe" will be processed as FastCGI EXEs.# This will ensure other files extensions will not be processed as FastCGI. <FilesMatch "\.fcgiexe"> SetHandler fcgid-script </FilesMatch># To allow settings in .htaccess to do mod_rewrite, IndexOptions (See https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride) AllowOverride Indexes FileInfo# See https://httpd.apache.org/docs/trunk/rewrite/intro.html for Documentation on mod_rewrite# See https://perldoc.perl.org/perlrequick.html for Regular Expressions used with mod_rewrite RewriteEngine On </Directory>#----------------------------------------------------------------------------------# The following virtual folder is user for the LocalSandbox.exe FastCGI app.# It could be called using: http://localhost:8164/fcgi_localsandbox/ <Directory "C:/Harbour_websites/fcgi_localsandbox/website/"> Options -Indexes -Includes +FollowSymLinks -MultiViews +ExecCGI Require all granted <FilesMatch "\.fcgiexe"> SetHandler fcgid-script </FilesMatch> AllowOverride Indexes FileInfo RewriteEngine On </Directory>#----------------------------------------------------------------------------------</VirtualHost>#===============================================================================================================
For the Echo FastCGI app, you will need to create a ".htaccess" file in the "R:\Harbour_websites\fcgi_echo\website\" folder.
You can use the FCGITaskManager program, described further in this article, to automate its creation, or you could created it manually.
Under Windows, it's unlikely you can create the file from within "File Explorer". It does not allow you to create a file with no filename and just an extension.
The solution to creating a ".htaccess" file is to open a Command prompt, go to the "R:\Harbour_websites\fcgi_echo\website\" folder, for example, and run the following command:
# The content of this file was generated by FCGITaskManager.# Work around for request to root folder.DirectoryIndex default.htmlRewriteCond %{REQUEST_FILENAME} default\.html$RewriteRule "^" "AnyFile.fcgiexe" [END]# Non present files becides a FastCGI exe will be redirected to the FastCGI current version.RewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME} !\.fcgiexeRewriteRule "^" "AnyFile.fcgiexe" [END]# Prevent from downloading security files.RewriteCond %{REQUEST_URI} \.(htaccess|htpasswd)$RewriteRule "^" "AnyFile.fcgiexe" [END]FcgidWrapper "R:/Harbour_websites/fcgi_echo/backend/FCGIecho.exe" .fcgiexe virtual
Environment Variables
Using the GetEnv() or hb_GetEnv() from within your FastCGI app WILL NOT retrieve custom (user set) Environment Variables. Some like PATH will be available. The issue of getting Environment Variables is related to the fact that it is the Apache web server that is spanning a thread for your EXE, under the user account of Apache itself.
To work around this and to allow you to use Environment Variables you can create them as part of the mod_fcgid module configurations.
Under MS Windows, all of those variables are global to the entire server, unless configured at the level or a "VirtualHost". They can not be setup at a level of a <directory>.
Under Linux, each "sites-available", having its own ".conf" file can have different sets of Environment Variable settings.
As our first FastCGI web site, we will implement the Echo application. This will simply display whatever was sent to the server.
If you are using the previously defined "httpd.conf", you will notice I make reference to a "R:\Harbour_websites\" folder. Please change that reference to whatever location you intend to host your actual web sites.
Create a "fcgi_echo" sub-folder. Place into it the ".htaccess" file, and copy the "libfcgid.dll" file from the following location:
The repo also has the full Visual Studio Solution, and you could rebuild it yourself using Visual Studio 2019, for example.
Under the \Harbour_websites\fcgi_echo\ folder you need to create at least two sub-folder: "backend" and "website"
The "website" folder will have files published by Apache, and the .htaccess file.
The "backend" folder will have the actual FastCGI exe, a support dll and a "config.txt" file
The "config.txt" is a text file and is optional, but you could create it and place the following two lines:
ReloadConfigAtEveryRequest=true //"true" or "false"
MaxRequestPerFCGIProcess=0 //0 for Unlimited
The "MaxRequestPerFCGIProcess" setting will allow you to bring down on a regular basis your FastCGI EXE. This is a safer method than the one provided by the fcgid module of Apache.
The "down.html" file is a static page to display when the web app is down. Users will know they used a correct URL, and should try later.
The "default.html" files be used as a mechanism to handle calls to the root folder, meaning with no page name in the URL.
Both "down.html" and "default.html" will be created by the FastCGITaskManager program, described further.
The "FCGIecho.exe" will be created automatically from within VSCODE (Visual Studio Code), by a task I will describe later.
The following is an example of a "down.html" file you can create to let the user know when your website is under maintenance. This should happen very rarely, since our framework will make it very easy to switch versions. You may want to mark the website as "down" when changing database schemas.
File: down.html
<!DOCTYPE html><html><head><title>Website Under Maintenance</title></head><body><h1>Website is not available at this time. Try Later.</h1></body></html>
Next step is to start VSCODE using the fcgi-echo (Workspace) located in R:\Harbour_FastCGI\Examples\echo
If you installed the repo files in different locations, you may want to use notepad or notepad++ and adjust the following files:
\Examples\echo\fcgi-echo.code-workspace Several lines will need to be modified.
\Examples\echo\.vscode\launch.json Please see the "program" line.
\Examples\echo\.vscode\tasks.json Please see the "WebsiteDrive" and "WebsiteFolder" lines.
I added some keyboard shortcuts in my user settings in VSCODE. These settings will apply to all workspaces.
To be effective in following these instructions, you must be familiar with the VSCODE Prerequisite (see other article).
"CTRL+1" will call the VSCODE task to compile the current project in debug mode.
"CTRL+2" will call the VSCODE task to compile the current project in release mode.
Open the "fcgi-echo.code-workspace" file located in the "\Examples\echo\" folder with VSCODE.
Here is what your VSCODE workspace can look like once you open the "echo.prg" file:
In that VSCODE project, I also included the entire "libfcgi" and the Apache "conf" folders. These are not required for any other FastCGI projects you intend to create.
After you press "CTRL+2", or start the task "CompileRelease", the "echo.exe" file will be created and copied / renamed to FCGIecho.exe in your web site folder.
I purposely added the prefix "FCGI" to the executables, in case you need to taskill those programs and don't want to mistakenly shutdown any other exe also called echo.
If you need to debug the program, press instead "CTRL+1", or start the task "CompileDebug", and similar behavior to "CTRL+2" will happen. There will be more on "how to debug" later in this article.
The "httpd.conf" and ".htaccess" (Apache Configuration files) will redirect any call to FCGIecho.exe
The VSCODE build tasks (debug and release) will update the ".htaccess" file and compile and place a FCGIecho.exe file in the folder used by Apache.
Let's take a look at the VSCODE "task.json" file, located in the "\Examples\echo\.vscode\" folder.
We have 4 VSCODE tasks defined in the "tasks.json" file:
"CompileRelease", as the name implies, is used to build the "FCGIecho.exe". It will also place a copy in the folder published by the Apache server, in addition to updating the ".htacces" file.
"CompileDebug", as the name implies, is used to build the "FCGIecho.exe" in debug mode. It will do the same tasks as "CompileRelease"
"KillFcgiExe" is not needed, but left as an example of how to stop FastCGI apps. This is not the recommended way, since the cleanup code would not be executed.
"SoftKillFcgiExe" is called by "CompileRelease" and "CompileDebug". It is used to trigger a controlled shutdown (kill) of the FastCGI EXE to be replaced.
If you want to see the "echo" FastCGI working with POST requests, meaning submitting a form and / or uploading files, the easiest is to use the Postman app.
Postman is one of the most used tools for testing Rest API services. You can use the Harbour_FastCGI to create a Rest API of your own.
Postman is a commercial program but is free for "Individuals & Small Teams".
You will be asked to create an account, with an email address. A nice feature is that all your settings are stored on the Postman Inc. servers. But remember not to use any confidential data!
Here is a sample configuration you can use to test the Echo program. If you want to store uploaded files, please edit the "echo.prg" file to specify the location to store uploaded files.
Notes:
Switch between GET and POST request types
Enter a full URL
Toggle to "Body" and enter field (html) names and values. Switch to "form-data" if you also want to upload files
Enter any fields name (key) and values. Currently Harbour_FastCGI only supports "form-data" and "x-www-form-urlencoded"
In the Key column you can mark it to select a file, instead of a field name/value
You can switch between different display modes of the response, after you press "Send"
FCGITaskManager program
On the Harbour_FastCGI repo, you can also review and use the FCGITaskManager program.
Before I explain what FCGITaskManager does, let's look at how FastCGI apps are actually loaded in memory.
In the following image, we see 2 web apps, FCGIecho and FCGImod_harbour.
We have 2 instances of FCGIecho.exe and 3 other different versions, FCGIecho1.exe, FCGIecho2.exe and FCGIecho3.exe.
We also have a single version / instance of FCGImod_harbour.exe
In the Harbour_FastCGI framework, the "echo" app will have an executable formatted as "FCGI"+"echo"+"version text".exe
So here we have 2 instances with no version info: "FCGIecho.exe"
A version "1" as the file "FCGIecho1.exe" and so on for "2" and "3"
The reason we had 2 instances of "FCGIecho.exe", is that on this computer I purposely ran some "website stress loader" program to have the Apache server start a second instance.
The method to redirect requests to a particular version of your app is by updating the ".htaccess" file accordingly.
We should, simultaneously and properly, terminate all other versions.
As a result, we normally would, in the picture above, only have a single version of "echo" and "mod_harbour" apps.
And this where the will use the "FCGITaskManager.exe" program. It is a console app (Windows only for now) that will help you with the following tasks:
"kill" - stops all instances of a particular version of your app. It will not terminate other versions and will set the specified version as the "current version".
"activate" - makes the specified version the "current version". It will terminate all other running versions.
"down" - tops all instances of all versions of your app. It redirects all web page requests to a "down.html" page.
In production, usually the "down" and "activate" tasks would be used, while in development the "kill" should be called before your app is recompiled/published.
The concept of "stopping" refers to signalling the app to do a proper shutdown. This is achieved by creating a "marker file" with the same name as the executable, but with the extension ".kill", then calling that executable via web page request. The main request loop in the FastCGI app will detect the ".kill" file and execute the shutdown process and terminate. The shutdown process will call the "OnShutdown" method of the FastCGI main class, which you probably sub-classed to add your own code.
The following is a list of parameters the FCGITaskManager program is expecting:
Action to take. "kill", "activate" or "down"
Protocol. "http" or "https"
Host+Domain. For example "localhost", "www.mydomainname.com"
Port. For example "80" or "443"
Website Folder. For example "/", "/fcgi_echo/"
Fcgi Folder. Path where the FastCGI app is located. For example: "R:\Harbour_websites\fcgi_echo\"
Fcgi App Name. The app name, without the "FCGI" prefix. For example: "echo"
Fcgi App Version. Blank for no version (while developing), any text with no blanks when deploying on live server.
For example, in the "echo" application, there is a "fcgi-echo.code-workspace" VSCODE workspace definition file.
Using the VSCODE extension "VsCode Action Buttons", I added 3 buttons on the bottom on the VSCODE editor to manage the fcgi-echo web site.
The following is the entire command for the "<Down>" button (Had to use double "\" due to using a JSON file):
"R:\\Harbour_FastCGI\\FCGITaskManager\\msvc64\\release\\FCGITaskManager.exe down http localhost 8164 /fcgi_echo/ R:/Harbour_websites/fcgi_echo/ echo"
The following is an example of the ".htaccess" file when the website is marked as "down":
RewriteRule "^" "/fcgi_echo/down.html" [END]
The following is an example of the ".htaccess" file when the website has the "no version specific" "echo" app activated:
In VSCODE, we first have to setup a "launch.json" file.
Like all the other files, it is already in the repo.
The main difference with the most traditional way of debugging is that here, we need to "attach" to an already running program, instead of having the debugger start the exe to be debugged. Luckily the Harbour VSCODE extension by Antonino Perricone supports the "attach" method.
File: launch.json
{// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "harbour-dbg", "request": "attach", "name": "Attach Program echo.exe", "program": "R:\\Harbour_websites\\fcgi_echo\\backend\\FCGIecho.exe", "sourcePaths": [ "${workspaceFolder}" ] } ]}
For debugging to work, the program also needs to be compiled by Harbour with the "-B" flag. This will add line number references, among other things, inside the executable.
Also any "Altd()" function call will then pause the program and open that PRG file in VSCODE at the line following the "Altd()" call.
Because the debugger is used in "attach" mode, if you forget to start the debugger before you request a web page, which then would call your code, the program will not "hang" waiting for the debugger. This is a major advantage of the "attach" mode.
Also, if you have a run time error, unless you have an error handling process, the debugger will also pause in the correct file and line number.
To make it easy to compile and deploy your programs, I created the VSCODE tasks. Please refer to the section above, "Your First FastCGI Web Site" for the description of the "tasks.json" file.
Before you start the debugger (F5), run the "CompileDebug" task (CTRL+1) to rebuild your program in debug mode.
If no compilation occurred, you should see the following:
If you are updating the version of the Harbour Extension, please re-export its debugger to "...\hb_fcgi\vscode_debugger.prg". All the instructions about how use the debugger and how to export the prg is in the "Developing and Debugging Harbour Programs with VSCODE (Visual Studio Code)" article.
Extra Debugging Options under Windows
Under Windows, there is a way to display messages in a "Tracing" Window, called DebugView.
The purpose of this section is to only review the "echo.prg", not the internals of the hb_Fcgi class.
The entire concept of FastCGI is around its main request loop which starts at line 17 and ends at line 45.
All the APIs and functionality of the FastCGI interface is wrapped into a single class hb_Fcgi, and a single public variable oFcgi will have an object of that class or sub-class.
On line 14, we have an example of creating an object directly from the hb_Fcgi class. But since I wanted to demonstrate how to add your own code called at the first request and on shutdown, we needed to create a sub-class (line 53) and create the oFcgi from that sub-class (line 15). Lets call the sub-class MyFcgi.
The first major step the program does is call oFcgi:Wait() (line 17), and it waits until a web page request is received or a shutdown is requested.
Then all the code, until we reach the enddo (line 45), will be the actual code to create a response.
Calls to oFcgi:Print() is used to send html content out. In the hb_fcgi.ch file, I defined the "?" operator to behave as oFcgi:Print(). But for readability I continued to use the Print() method.
Lines 58 and 62 are examples of how to add code to the hooks of the sub-class.
See the for additional explanations.
File: echo.prg
#include "hb_fcgi.ch" //=================================================================================================================Function Main()local iInputLength := 0local cInput := ""local cQUERY_STRING := ""local cVarSendToDebugView("Starting echo")// oFcgi := hb_Fcgi():New() oFcgi := MyFcgi():New() // Used a subclass of hb_Fcgi do while oFcgi:Wait() SendToDebugView("Request Counter",oFcgi:RequestCount) oFcgi:Print("<h1>FastCGI echo</h1>")//altd() oFcgi:Print("<p>FastCGI EXE = "+oFcgi:FastCGIExeFullPath+"</p>") oFcgi:Print("<p>SCRIPT_NAME = "+oFcgi:GetEnvironment("SCRIPT_NAME")+"</p>") oFcgi:Print("<p>REQUEST_URI = "+oFcgi:GetEnvironment("REQUEST_URI")+"</p>") oFcgi:Print("<p>REDIRECT_URL = "+oFcgi:GetEnvironment("REDIRECT_URL")+"</p>") oFcgi:Print("<p>QUERY_STRING = "+oFcgi:GetEnvironment("QUERY_STRING")+"</p>") oFcgi:Print("<p>Request Count = "+Trans( oFcgi:RequestCount )+"</p>") oFcgi:Print("<p>Input Length = "+Trans( oFcgi:GetInputLength() )+"</p>") oFcgi:Print("<p>Request Environment:</p>") oFcgi:Print(oFcgi:ListEnvironment()) oFcgi:Print([<p>Input Field "FirstName" = ]+oFcgi:GetInputValue("FirstName")+[</p>]) oFcgi:Print([<p>Input Field "LastName" = ]+oFcgi:GetInputValue("LastName")+[</p>]) oFcgi:Print([<p>Input Field "NotExistingValue" = ]+oFcgi:GetInputValue("Bogus")+[</p>]) oFcgi:Print([<p>Uploaded File Name "File1" = ]+oFcgi:GetInputFileName("File1")+[</p>]) oFcgi:Print([<p>Uploaded File Content Type "File1" = ]+oFcgi:GetInputFileContentType("File1")+[</p>]) // oFcgi:SaveInputFileContent("File1","d:\MyFolder\"+oFcgi:GetInputFileName("File1")) // oFcgi:SaveInputFileContent("File2","d:\MyFolder\"+oFcgi:GetInputFileName("File2"))// oFcgi:SaveInputFileContent("File3","d:\MyFolder\"+oFcgi:GetInputFileName("File3"))// oFcgi:SaveInputFileContent("File4","d:\MyFolder\"+oFcgi:GetInputFileName("File4"))enddo SendToDebugView("Done")return nil//=================================================================================================================class MyFcgi from hb_Fcgi method OnFirstRequest() method OnShutdown()endclassmethod OnFirstRequest class MyFcgi SendToDebugView("Called from method OnFirstRequest") return nilmethod OnShutdown class MyFcgi SendToDebugView("Called from method OnShutdown") return nil//=================================================================================================================
Conclusion
Web development is not for the faint of heart; this FastCGI project is only the foundation for future web frameworks.
I hope you find this useful for converting your CGI app to FastCGI apps, or you at minimum use this information as a gateway to port your desktop applications to the web.