************************************** * Apache Installation Instructions * * for Mac OS X using a shebang line * * last checked: April 16, 2020 * * for Mac Os Catalina v10.15.4 * ************************************** After building diaperglu, copy the new diaperglu to the cgi-bin directory of your website. On my Mac this is at /Library/WebServer/CGI-Executables If you have an older Mac, you should be able to browse to http://localhost/cgi-bin/diaperglu and see the no script file found page. On Mac Os Catalina, you may need to edit the Apache configuration file. The Apache configuration file is called httpd.conf and is located in /etc/Apache2/ You can't just open this directory in Finder. If you want to use Finder, open Finder then do this: Finder -> Go -> Go to folder... then type /etc/Apache2 into the popup. Once there, I would make a backup copy of httpd.conf just in case you mess it up. In order to enable cgi, you need to uncomment two lines. They look like this: #LoadModule cgid_module libexec/apache2/mod_cgid.so #LoadModule cgi_module libexec/apache2/mod_cgi.so You need to remove the beginning # so they look like this: LoadModule cgid_module libexec/apache2/mod_cgid.so LoadModule cgi_module libexec/apache2/mod_cgi.so In any case, now you need to start Apache. It doesn't start by itself by default anymore so you need to enter this command: sudo apachectl start Now you should be able to browse to http://localhost/cgi-bin/diaperglu and see the no script file found page. On older versions of Mac OS you may need to enable sharing and/or change the permissions on the diaperglu file. To enable sharing do this: Apple Icon -> System Preferences... -> put a check in the Web Sharing box. To enable execute permissions for diaperglu do this: open a terminal change to the /Library/WebServer/CGI-Executables directory and do chmod +x diaperglu (this give execute permissions to everyone, you may just want to give permissions to you and group) Now make a file helloworld.dglu and save it to the /Library/WebServer/CGI-Executables folder with this in it: #! diaperglu ." CONTENT-TYPE: text/html" CRLF CRLF ." <html><body>Hello Apache on Mac OS X</body></html>" CRLF Note: You need a space after #! and #! must be the first thing on the first line of the file. If you cut and paste this example from the browser you may get ctl-m at the end of each line which causes problems for Mac Os X. If you type this example in using TextEdit, it should be ok except that TextEdit will append a .txt to your filename which may not show up in Finder unless you uncheck the please add .txt to my filename box. It seems for Apache on Monterey, the CONTENT-TYPE line must be immediately after the #! line. You may need to change the permissions of the helloworld.dglu to execute. (I didn't need to do this on Catalina.) (I did need to do this on Ventura.) open a terminal change to the /Library/WebServer/CGI-Executables directory and do chmod +x helloworld.dglu (this give execute permissions to everyone, you may just want to give permissions to you and group) At this point you should be able to browse to http://localhost/cgi-bin/diaperglu?helloworld.dglu This should show a 'Hello Apache on Mac OS X' page. You should also be able to browse to this: http://localhost/cgi-bin/helloworld.dglu If you see the message diaperglu^M bad interpreter message with the /cgi-bin/helloworld.dglu way of running it, that means your script file has the control m characters at the end of the lines. If you see a message about a problem loading the page and to contact your system administrator, you may need to give execute permissions to helloworld.dglu If you want your page to load faster, you can try using nodiaperglu instead of diaperglu For more information on how to configure Apache to use cgi, you can look here: https://httpd.apache.org/docs/2.4/howto/cgi.html (link checked April 16, 2020)
************************************** * IIS Installation Instructions * * for Windows 10 * * last checked: October 3, 2020 * ************************************** The default web server directory for IIS is C:\inetpub\wwwroot\ These instructions are for the default server directory. First you need to make sure IIS is installed and CGI and/or ISAPI is enabled. To do this, go to: Start -> Windows System -> Control Panel -> Programs -> Turn Windows Features On and Off Then make sure the Internet Information Services box has the black square in it. Then make sure the cgi and/or isapi boxes have the black square in them. The cgi and isapi boxes can be found at this position in the heirarchical list: Internet Information Services World Wide Web Services Application Developement Features ... CGI ISAPI Extensions Then change the authentication of the website to a user that can access the website directory. I recommend not using pass through authentication unless you know how to give permissions to all the different parts of IIS that need access to your website directory. I couldn't figure it out for both ISAPI and CGI so I just used my administrator account. Using the administrator account is probably also a bad idea, you should probably make a new user just for your website and limit which folders this user can access to just the website folder. To change the authentication of the website, go to: Start -> Windows Administrative Tools -> Internet Information Services (IIS) Manager Under connections on the left, expand the hierarchical list so that Computer -> Sites -> Default Web Site is visible and left click on the Default Web Site to hilight it. Then under Actions on the right, choose Basic Settings. In the Edit Site pop up, choose Connect As, then select specific user and choose Set... In the Set Credentials pop up, put in the user name and password of a user on your computer that can access the default website directory. For security reasons, it's probably a bad idea to use an administrator account, but you could make a new user, and give the new user access to the directory. (I didn't test the new user case...) Click on Test Settings. Both Authentication and Authorization should be green with a checkmark. If not, things aren't going to work. Next, build diaperglu if you need to, then copy diaperglu.exe and/or libdiaperglu.dll to the website directory. You only need to copy one of these. But you can do both if you want. You'll need to use different file name extensions for each mode if you do both. diaperglu.exe is for cgi mode and libdiaperglu.dll is for isapi mode. Next you will need to add a folder (subdirectory) to the default website. I tried to get things work in the default web site folder, but due to permissions issues, I think you have to make a virtual directory so that you can give permissions to a user account. Also, when I tried to assign a virtual directory to the default website directory, it broke IIS and I had reinstall IIS. To do this: open file explorer, browse to your default website directory, (on my computer it's C:\inetpub\wwwroot\) right click on the directory and choose Folder in the text edit box for the folder, enter your folder name. For this example I'm using myphysicaldirectory. Next copy diaperglu.exe and/or libdiaperglu.dll to your new website directory. Next copy a script file to the website directory. You can use helloworld.dglu and or helloworld.asdglu in the samplescript/CGIScripts/ subdirectory. If you are installing both diaperglu.exe and libdiaperglu.dll you will need to use different file name extensions for cgi and isapi mode. For example, .dglu can be for diaperglu.exe and .asdglu can be for libdiaperglu.dll. If you want to make your own file, it needs to be an html file including the response header. This looks like: ." Content-type: text/html" CRLF CRLF ." <html><head></head><body>" CRLF ." Hello World on CGI!" CRLF ." </body></html>" CRLF Next, make sure the user you chose as the user for the website has access to the web site directory and the files. In file explorer, right click on the directory each file and choose properties. Then select the security tab. If your user falls into one of the categories listed, you are ok. For instance, if your user is an administrator and administrators are listed, then you are ok. If not, you will need to add the user to the list. Next you need to make a virtual directory for your physical website directory. To do this, go to: Start -> Windows Administrative Tools -> Internet Information Services (IIS) Manager Under connections on the left, expand the hierarchical list so that Computer -> Sites -> Default Web Site is visible and left click on the Default Web Site to hilight it. Right click on the Default Web Site and choose Add Virtual Directory... In the pop up: for Alias: choose your virtual directory name. I'm using myvirtualdirectory for this example. for Physical Path: choose your websites physical directory. For this example it's C:\inetpub\wwwroot\myphysicaldirectory click Connect as... to get the Connect As pop up choose Specific User: click Set... to get the set Credentials pop up use the same user name and password that you chose for the Default Web Site basic settings click Test Settings... Both Authentication and Authorization should be green with a checkmark. If not, things aren't going to work. Now you need to associate your script file name extensions with the script engine. For this example I'm going to associate .dglu with diaperglu.exe and .asdglu with libdiaperglu.dll To do CGI do this, go to: Start -> Windows Administrative Tools -> Internet Information Services (IIS) Manager Under connections on the left, expand the hierarchical list so that Computer -> Sites -> Default Web Site is visible and left click on the Default Web Site to hilight it. The box in the middle should say something like Default Web Site Home Double click Handler Mappings Under actions on the right, choose Add Script Map In the Add Script Map dialog do this: for Request path: *.dglu for Executable: browse to C:\inetpub\wwwroot\myphysicaldirectory\diaperglu.exe and choose it for Name: put whatever you want, just not the same name as something else. I used dotdglucgi3 A pop up will ask you if you want to allow this cgi extension, If you do, say yes. Left click on your computer name under Connections on the left In the box on the right under Manage Server choose restart You should now be able to open a browser and run the script file. To do this, open a brower and enter this URL: http://localhost/myvirtualdirectory/helloworld.dglu If it worked, you should see "Hello World on CGI!" To do ISAPI do this, go to: Start -> Windows Administrative Tools -> Internet Information Services (IIS) Manager Under connections on the left, expand the hierarchical list so that Computer -> Sites -> Default Web Site is visible and left click on the Default Web Site to hilight it. The box in the middle should say something like Default Web Site Home Double click Handler Mappings Under actions on the right, choose Add Script Map In the Add Script Map dialog do this: for Request path: *.asdglu for Executable: browse to C:\inetpub\wwwroot\myphysicaldirectory\libdiaperglu.dll and choose it for Name: put whatever you want, just not the same name as something else. I used dotasdgluisapi3 A pop up will ask you if you want to allow this isapi extension, If you do, say yes. Left click on your computer name under Connections on the left In the box on the right under Manage Server choose restart You should now be able to open a browser and run the script file. To do this, open a brower and enter this URL: http://localhost/myvirtualdirectory/helloworld.asdglu If it worked, you should see "Hello World on ISAPI!" If you want to support the diaperglu.exe?myscriptfilename.dglu run mode, do this: Start -> Windows Administrative Tools -> Internet Information Services (IIS) Manager Under connections on the left, expand the hierarchical list so that Computer -> Sites -> Default Web Site is visible and left click on the Default Web Site to hilight it. The box in the middle should say something like Default Web Site Home Double click Handler Mappings The top of the middle section should say Handler Mappings Left click on the *.dglu CgiModule entry to highlight it. On the right under Actions choose Edit Feature Permissions. In the pop up, make sure Execute has a check. Left click on your computer name under Connections on the left In the box on the right under Manage Server choose restart You should now be able to open a browser and run diaperglu to get the no script found page. http://localhost/myvirtualdirectory/diaperglu.exe You should also be able to use diaperglu to run script files this way.... on Windows you need to have the physical path relative to the web site root to the script file after the ? http://localhost/myvirtualdirectory/diaperglu.exe?myphysicaldirectory/helloworld.dglu If you want to support the libdiaperglu.dll?myscriptfilename run mode, in addition to enabling execute for the handler mapping, you also have to give user anonymous access to the physical website folder. Do this: Start -> Windows Administrative Tools -> Internet Information Services (IIS) Manager Under connections on the left, expand the hierarchical list so that Computer -> Sites -> Default Web Site is visible and left click on the Default Web Site to hilight it. The box in the middle should say something like Default Web Site Home Double click Handler Mappings The top of the middle section should say Handler Mappings Left click on the *.asdglu IsapiModule entry to highlight it. On the right under Actions choose Edit Feature Permissions. In the pop up, make sure Execute has a check. Left click on your computer name under Connections on the left In the box on the right under Manage Server choose restart Open file explore and browse to your website's physical folder. Right click on your website's physical folder and choose properties. On the properties pop up, go to the security tab and choose Advanced. On the Advanced pop up, choose Change Permissions After the popup changes, choose Add On the permission pop up choose Select a principal On the Select User or Group pop up, type anonymous in the box and choose Check Names The name should change to ANONYMOUS_LOGON or something like that. Choose ok. I would restart IIS just in case. You should now be able to open a browser and run libdiaperglu to get the no script found page. http://localhost/myvirtualdirectory/libdiaperglu.dll You should also be able to use libdiaperglu to run script files this way.... on Windows you need to have the physical path relative to the web site root to the script file after the ? http://localhost/myvirtualdirectory/libdiaperglu.dll?myphysicaldirectory/helloworld.asdglu
Browser Cache Problem
Browsers cache pages to speed up loading. You probably don't want this for any of your pages which have content that changes, which is probably all of them if you are using a script engine like DiaperGlu to generate them. It took me awhile to find a header that worked on different browsers and here it is:
." CONTENT-TYPE: text/html" CRLF
." Cache-Control: no-cache, must-revalidate" CRLF
." Expires: Mon, 12 Jul 1997 05:00:00 GMT" CRLF
CRLF
HTML Form Variables
HTML Forms pass their variables in a form string containing a series of name$=value$ pairs. Each name$=value$ pair is separated with the & character. Each name$ is separated from it's value$ with the = character. Each name string and value string is url encoded, which means any spaces are converted to the + character and certain control characters are converted to %xx where xx is the hexadecimal ascii code for the character.
HTML Forms have two methods for passing form strings called 'get' and 'post'. The get method appends a ? character to the URL with the form string after that. The post method passes the form string in a way that does not show up in the url. It's been a long time since I wrote the code, but it looks like sometimes post passes the form string in a method similar to a file download.
ISAPI and Apache have different methods for getting the get and post strings. DiaperGlu deals with all the different ways they are passed in a platform independent way. For the post method, DiaperGlu copies the post method's form string to a buffer with a buffer id named POSTBUFFERID. Or you can use GETPOST$ to push a copy of the post buffer to the string stack. For the get method, the get method's form string is available as an environment variable. GETQUERY$ will push a copy of the get method's form string to the string stack.
DiaperGlu has a few words to help deal with form strings. Here are some of them:
- NEW-HLISTWITHROOT>EH will make a new hlist, and a root element, and push the elementid hlistid of the root element to the EH stack.
- GETQUERY$ will push a copy of the form variable string passed using the get method to the string stack.
- GETPOST$ will push a copy of the form variable string passed using the get method to the string stack.
- FORM$>VALUE$NAME$U will break a form string up into u value$ name$ pairs and URLDECODE$ them.
- EH-NEW-ELEMENTS will add u value$ name$ pairs as children to an element in an hlist.
- QUERY-POST-EH-NEW-ELEMENTS will decode both the get and post form strings, and add the extracted name$ value$ pairs as children to the element and hlist on top of the EH stack.
- EH FIND-ELEMENT-CHILD-BY-NAME$ ENDOFWORDLIST <> will determine if a child element with the given name$ exists in the child list of the element and hlist on top of the EH stack.
- EH-NAME$>VALUE$ gets the value$ for a given name$ in the child list of the element and hlist on top of the EH stack. If a child with that name does not exist, an error is pushed to the error stack. You will probably want to use FIND-ELEMENT-CHILD-BY-NAME$ to determine if the child exists first before using this word, or just use ?NAME$>VALUE$.
- EH-?NAME$>VALUE$ gets the value$ for a given name$ in the child list of the element and hlist on top of the EH stack. If a child with that name does not exist, FALSE is pushed to the data stack and no value$ is pushed. If a child with that name exists, then TRUE is pushed to the data stack, and the value$ of the newest child with that name is pushed to the string stack.
You might also be able to deal with the get and post method's form strings directly.
File Dowload
Here is a page that downloads the file downloaded.txt with the contents 'I was downloaded':
$" I was downloaded!"
." Content-Type: application/octet-stream" CRLF
." Content-Length: " LENGTH$ DECIMAL 0 <#$ #S$ #>$ .$ CRLF
." Content-Disposition: attachment; filename=downloaded.txt" CRLF
CRLF
.$
File Upload
HTML form file upload is supported for cgi; however, I have not yet written a script to make it convenient for you. When your script gets control, the header is already loaded into the post buffer. The file may or may not still be loading. To determine this you have to do a blocking read from stdin until the os returns 0 characters. This means your script may be at the mercy of the OS and could hang if the OS never returns. This will wait for all characters and append them to what is already loaded in the post buffer:
HEX : readstdin ( -- ) BEGIN GETHSTDIN 1000 70000000 POSTBUFFERID WAITREADN>BUF 0= UNTIL ;
You will need to get the boundary marker from the 'CONTENT-TYPE' environment variable and parse the post buffer data yourself.
Different Ways to Run Diaperglu
You can put Diaperglu in your cgi-bin directory and use it to run script files directly. I added this for those cases where your ISP does not allow you to associate a file extension with a script engine. If you do this, the script engine supports the following:
http://www.yourwebsite.com/cgi-bin/diaperglu
If you browse to just the script engine, it will try to execute the script 'noscript.dglu'. If it can not find that file, it will show a default page letting you know no script file was specified.
http://www.yourwebsite.com/cgi-bin/diaperglu?scriptfilename.dglu
If you browse to the script engine and pass in a filename as a parameter, it will try to execute the script with that filename. If it can not find that script or you do not have permissions it will show a default page letting you know it could not find the script file.
In this mode, only the first parameter's value is used as the script file name. This allows you to pass other parameters in to Diaperglu, and even do something like this:
http://www.yourwebsite.com/cgi-bin/diaperglu?MYSCRIPT=scriptfilename.dglu&MYPARAMETER=awesome
Under Apache and diaperglu?scriptfilename.dglu in CGI mode, Diaperglu also tries to build the full path for you, but takes the path information from SCRIPT_FILENAME. This means scriptfilename.dglu's path has to be relative to the directory containing Diaperglu. You may run into some security issues on Catalina if you try to put the script files in a directory different from Diaperglu...
Under Apache and Ventura using the default Apache configuration with cgi enabled, files in the cgi-bin directory are not directly accessible from the browser. This means you can't put things like audio files in the cgi-bin directory and have the audio tag or a direct url load them. The documents directory is accessible though, and data files will work there. The URL do the documents directory is http://localhost/