"You take the best computer people on the planet and let them collaborate in a world wide public forum (the internet) to produce a product that is better than any commercial variety"
According to www.netcraft.com approximately 65% of the web servers in the world are based upon Apache
Package | Apache | OpenSSL | Notes |
---|---|---|---|
CSWS-1.2 | Apache 1.3.20 | OpenSSL 0.9.5a | minimum OS: OpenVMS-7.2 Alpha |
CSMS-1.3 | Apache 1.3.26 | OpenSSL 0.9.6b | higher levels of OpenSSL with patches |
SWS-2.0 | Apache 2.0.47 | OpenSSL 0.9.6g | minimum OS: OpenVMS-7.3 Alpha higher levels of OpenSSL with patches |
SWS-2.1 | Apache 2.0.52 | OpenSSL 0.9.7d | higher levels of OpenSSL with patches |
SWS-2.2 | Apache 2.0.63 | OpenSSL 0.9.8h | higher levels of OpenSSL with patches |
While quite a bit of Apache documentation exists, CGI information is sparse but some can be found here
Be careful when Googling the phrase CGI because you might accidentally end up at www.cgi.com which happens to be the name of a computer services company headquartered in Montreal, Quebec, Canada.
Many older VMS programmers begin developing CGI-based web applications using this inefficient model:
Quick Blurb about HTTP + HTML
Your server-side program should send something like this back to Apache: Status: 200 Content-Type: text/html <!DOCTYPE html> <html> <head> <title>bla bla bla</title> </head> <body>bla bla bla </body> </html> Begin with (mostly) HTTP directives then use a blank line before sending HTML Apache will translate "Status: 200" into something like "HTTP/1.1 200"
Example DCL-based CGI script which must located in one of Apache's script directories
(this script invokes two executable images)
$ set noon ! do not stop on errors $ say :== write sys$output ! $ debug = f$trnlnm("NEIL$DEBUG","LNM$SYSTEM_TABLE") $ if (debug .eqs. "Y") ! if CGI debugging is desired $ then ! $ say "Status: 200" ! start of document header $ say "Content-Type: text/html" ! mime type declaration $ say "" ! end of document header $ say "<html><head></head>" ! start of HTML $ say "<body><pre>" ! $ endif $! temps = "''WWW_REQUEST_METHOD'" ! purveyor method $ temps = "''REQUEST_METHOD'" ! apache method $ if (temps .eqs. "POST") .or. - (temps .eqs. "GET") ! $ then ! $ run csmis$exe:read_html_apache.exe ! create DCL symbols (and sets $status to 1 if ok) $ endif ! $ run csmis$exe:desired_application.exe ! this is our desired web application $ if debug .eqs. "Y" ! $ then ! $ say "</pre>" ! $ say "</body></html>" ! $ endif !
As your platform begins to serve hundreds of hits per hour you can reduce overhead by moving "symbol reading logic" from "read_html_apache.exe" into your application.
$ set noon ! do not stop on errors
$ say :== write sys$output !
$ debug = f$trnlnm("NEIL$DEBUG","LNM$SYSTEM_TABLE")
$ if (debug .eqs. "Y") ! if CGI debugging is desired
$ then !
$ say "Status: 200" ! start of document header
$ say "Content-Type: text/html" ! mime type declaration
$ say "" ! end of document header
$ say "<html><head></head>" ! start of HTML
$ say "<body><pre>" !
$ endif !
$ run csmis$exe:desired_application.exe ! this is our desired application
$ if debug .eqs. "Y" !
$ then !
$ say "</pre>" !
$ say "</body></html>" !
$ endif !
or this:
$ set noon ! do not stop on errors
$ run csmis$exe:desired_application.exe ! this is our desired application (should return 1)
$ rc = f$integer($STATUS) !
$ if ((rc .and. 7) .neq. 1) ! 1=success, 2=error, 4=fatal
$ then !
$ say :== write sys$output !
$ say "Status: 500" ! start of document header
$ say "Content-Type: text/html" ! mime type declaration
$ say "" ! end of document header
$ say "<html><head></head>" ! start of HTML
$ say "<body><pre>" !
$ say "Script: 2001" !
$ say "error: ",rc !
$ say "</pre></body></html>" !
$ endif !
or this:
$ run csmis$exe:desired_application.exe ! note: "csmis$exe" is a directory on my platform
Because your ultimate goal is to run the binary application directly from a specially configured Apache directory. This can be done my enabling one, or more, directories to run executable binaries. In the NCSA web server, some directories were enabled to run applications by default. In Apache the default settings for scripting and running applications are disabled for security reasons. You turn them on my creating/modifying <Directory> declarations in a file named APACHE$COMMON:[000000.CONF]HTTPD.CONF
If you're familiar with writing CGI's for either Purveyor (Process Software Corporation) or OSU DECthreads then you'll probably recognize the "show symbol" and "show logical" lines in the following CGI script.
$ set noon ! do not stop on errors $ say :== write sys$output ! $ say "Status: 200" ! start of document header $ say "Content-Type: text/html" ! $ say "" ! end of document header $ say "<html><head></head>" ! start of HTML $ say "<body><pre>" ! $ show symbol /local/all ! show web-server process-level local symbols $ show symbol /global/all ! show web-server process-level global symbols $ show logical/proc/job ! show web-server job-level logical names $! temps = "''WWW_REQUEST_METHOD'" x purveyor method $ temps = "''REQUEST_METHOD'" ! apache method $ if (temps .eqs. "POST") .or. - (temps .eqs. "GET") $ then $ run csmis$exe:read_html_apache.exe ! create DCL symbols (and sets $status to 1 if ok) $ endif $ show symbol /local/all ! show all process-level local symbols $ show symbol /global/all ! show all process-level global symbols $ show logical/proc/job ! show all job-level logical names $ say "</pre></body></html>" ! end of HTML
The program just listed will not work properly with CSWS because the interface has been locked down to limit hacking. This means that "$show symbol /all" statement won't display any environment variables passed to the CGI by the server. (but you will see FORM variables which were created by your application). To view server-created variables you must explicitly request them by name like this:
$ show symbol/local SYMBOL-NAME $ show symbol/global SYMBOL-NAME
... which means you need to know their names ahead of time. Inspect the contents of script "TEST-CGI-VMS.COM" to see what I mean. Note that this incomplete file is missing environment variables AUTH_TYPE, HTTP_COOKIE, REMOTE_USER (and probably a few more).
Starting CSWS with "certain system-level logical names" will modify Apache's operation. Put these declarations in script sys$manager:SYSTARTUP_VMS.COM just before you invoke @sys$startup:APACHE$STARTUP.COM
This table was copied from Compaq's "V2.1-1 Installation and Configuration Guide" (more logical names were added with 2.2)
Table 3-5 User Defined Logical Names | |||||||||
---|---|---|---|---|---|---|---|---|---|
Logical Name | Description | ||||||||
APACHE$BG_PIPE_BUFFER_SIZE (New in Version 2.0) |
System logical name that is used to set the socket pipe buffer size for exec functions. If this logical is not set, the default is 32767. |
||||||||
APACHE$CGI_BYPASS_OWNER_CHECK (Obsolete in V2.x) |
If defined to any value, this logical name causes the Secure Web Server to bypass the file owner check of the CGI script file. The default is to enforce the owner check on CGI script files for security purposes. |
||||||||
APACHE$CGI_MODE | System logical name that controls how CGI environment variables are defined in the executing CGI process. There are three different options. Note that only one option is available at a time.
|
||||||||
APACHE$CREATE_SYMBOLS_GLOBAL | If defined, this system logical name causes CGI environment symbols to be defined globally. They are defined locally by default. |
||||||||
APACHE$DAV_DBM_TYPE (New in Version 2.0) |
Used to define the desired DBM organization to use for MOD_DAV. The valid options for this logical are: GDBM, SDBM, VDBM. If this logical is not set, the default is VDBM. |
||||||||
APACHE$DEBUG_DCL_CGI | If defined, this system logical name enables APACHE$VERIFY_DCL_CGI and APACHE$SHOW_CGI_SYMBOL. | ||||||||
APACHE$DL_CASE (New in Version 2.0) |
System logical name that controls how Apache will locate shareable entry points. There are four different options. Note that only one option is available at a time.
|
||||||||
APACHE$DL_FORCE_UPPERCASE (Obsolete in Version 2.x) |
If defined to be true (1, T, or Y), this system logical name forces case-sensitive dynamic image activation symbol lookups. By default, symbol lookups are first done in a case-sensitive manner and then, if failed, a second attempt is made using case-insensitive symbol lookups. This fallback behavior can be disabled with APACHE$DL_NO_UPPERCASE_FALLBACK. | ||||||||
APACHE$DL_NO_UPPERCASE_FALLBACK (Obsolete in Version 2.x) |
If defined to be true (1, T, or Y), this system logical name disables case-insensitive symbol name lookups whenever case-sensitive lookups fail. See APACHE$DL_FORCE_UPPERCASE | ||||||||
APACHE$FIXBG (Obsolete in Version 2.x) |
System executive mode logical name pointing to installed, shareable images. Not intended to be modified by the user. Replaced by APACHE$SET_CCL.EXE | ||||||||
APACHE$FLIP_CCL (New in Version 2.0) | Used by APACHE$SET_CCL.EXE, which replaces APACHE$FIXBG.EXE | ||||||||
APACHE$INPUT | Used by CGI programs for PUT/POST methods of reading the input stream. (question: did the HP author mean "GET/POST"?) | ||||||||
APACHE$MB_PIPE_BUFFER_SIZE (New in Version 2.0) |
Used to set the mailbox pipe buffer size for exec functions. If this logical is not set, the default is 4096. | ||||||||
APACHE$PLV_ENABLE_<username> (Obsolete in Version 2.x) |
System executive mode logical name defined during startup and used to control access to the services provided by the APACHE$PRIVILEGED image. Not intended to be modified by the user. | ||||||||
APACHE$PLV_LOGICAL (Obsolete in Version 2.x) |
System executive mode logical name defined during startup and used to control access to the services provided by the APACHE$PRIVILEGED image. Not intended to be modified by the user. | ||||||||
APACHE$PREFIX_DCL_CGI_SYMBOLS_WWW | If defined, this system logical name prefixes all CGI environment variable symbols with "WWW_". By default, no prefix is used. |
||||||||
APACHE$PRIVILEGED (Obsolete in Version 2.x) |
System executive mode logical name pointing to installed, shareable images. Not intended to be modified by the user. |
||||||||
APACHE$READDIR_NO_DOT_FILES (New in Version 2.0) |
Used to disable the simulating of dot files when processing directories. There is no default value. |
||||||||
APACHE$READDIR_NO_NULL_TYPE (New in Version 2.0) |
Used to disable the elimination of the null type which contains a single dot when processing directories. There is no default value. |
||||||||
APACHE$READDIR_NO_UNIX_OPEN (New in Version 2.0) |
Used to disable the processing of unix files when processing directories. There is no default value. | ||||||||
APACHE$SET_CCL (New in Version 2.0) | Used by APACHE$SET_CCL.EXE, which replaces APACHE$FIXBG.EXE | ||||||||
APACHE$SHOW_CGI_SYMBOL | If defined, this system logical name provides information for troubleshooting the CGI environment by dumping all of the symbols and logicals (job/process) for a given CGI. Use with APACHE$DEBUG_DCL_CGI. | ||||||||
APACHE$SSL_DBM_TYPE (New in Version 2.0) |
Used to define the desired DBM organization to use for MOD_SSL. The valid options for this logical are: GDBM, SDBM, VDBM. If this logical is not set, the default is VDBM. |
||||||||
APACHE$SPL_DISABLED (New in Version 2.0) |
Used to determine whether Shared Process Logging is to be disabled. There is no default value. |
||||||||
APACHE$SPL_MAX_BUFFERS (New in Version 2.0) |
Used to determine the maximum buffer quota for each Shared Process Logging mailbox. If this logical is not set, the default is 10. |
||||||||
APACHE$SPL_MAX_MESSAGE (New in Version 2.0) |
Used to determine the maximum message size for each Shared Process Logging mailbox. If this logical is not set, the default is 1024. |
||||||||
APACHE$SPL_FLUSH_INTERVAL (New in Version 2.0) |
Used to determine the maximum message count per Shared Process Logging file before data is flushed to disk. If this logical is not set, the default is 256. |
||||||||
APACHE$USE_CUSTOM_STAT (New in Version 2.0) |
System logical name that is used to indicate that the custom apache stat function should be used rather than the run-time stat function. | ||||||||
APACHE$USER_HOME_PATH_UPPERCASE (Obsolete in Version 2.x) |
If defined to be true (1, T, or Y), this system logical name uppercases device and directory components for user home directories when matching pathnames in <DIRECTORY> containers. This provides backward compatibility for sites that specify these components in uppercase within <DIRECTORY> containers. See the UserDir directive in Modules and Directives section for more information. | ||||||||
APACHE$VERIFY_DCL_CGI | If defined, this system logical name provides information for troubleshooting DCL command procedure CGIs by forcing a SET VERIFY before executing any DCL CGI. Use with APACHE$DEBUG_DCL_CGI. (did the author mean "Use with APACHE$SHOW_CGI_SYMBOL"?) |
I was recently working on an CSWS application for my employer to do the following:
First off, I enabled these two lines in HTTPD.CONF
LoadModule auth_module modules/mod_auth.exe LoadModule auth_openvms_module modules/mod_auth_openvms.exe
...then restarted the server. Everything seemed to work as expected except that I couldn't get any USERNAME info to show up in the DCL script. Furthermore, the DCL version of CGI debugging script "TEST-CGI-VMS.COM" seems to be missing some environmental variables like REMOTE_USER. To make matters worse, the otherwise excellent book OpenVMS with Apache, OSU, and WASD states that variable HTTP_AUTHORIZATION should be available in all servers including CSWS.
I was looking for this environmental as a sign that the base64 encoded username and password (Basic access authentication) were making it through to my CGI; I have since discovered that neither CSWS nor "Apache on UNIX" ever passed HTTP_AUTHORIZATION to a CGI program. I suppose this is so some evil programmer couldn't harvest usernames and passwords.
According to some helpful folks at Compaq (now HP), in order to get authorization information like REMOTE_USER transferred to the CGI you must do the following:
ServerRoot "/apache$root" DocumentRoot "/apache$common/main" LoadModule auth_openvms_module /apache$common/modules/mod_auth_openvms.exe_alpha ScriptAlias /cgi-bin/ "/apache$root/cgi-bin/" ScriptAlias /scripts/ "/apache$root/scripts/" ScriptAlias /bell_private_scripts/ "/apache$root/bell_private_scripts/" ScriptAlias /ics_private_scripts/ "/apache$root/ics_private_scripts/" Alias /bell_private/ "/apache$root/bell_private/" <Directory "/apache$root/bell_private"> Options FollowSymLinks AllowOverride All # enable .HTACCESS (do not insert these remarks) Order allow,deny Allow from all </Directory> Alias /ics_private/ "/apache$root/ics_private/" <Directory "/apache$root/ics_private"> Options Indexes FollowSymLinks Multiviews AllowOverride All # enable .HTACCESS Order allow,deny Allow from all </Directory> <Directory "/apache$root/bell_private_scripts"> AllowOverride AuthConfig # enable .HTACCESS Options ExecCGI Order allow,deny Allow from all </Directory> <Directory "/apache$root/ics_private_scripts"> AllowOverride AuthConfig # enable .HTACCESS Options ExecCGI Order allow,deny Allow from all </Directory>
AuthType Basic AuthAuthoritative On AuthName "ICSIS Bell-ATS Authentication" AuthOpenVMSUser On AuthOpenVMSAuthoritative On require valid-user
# ScriptAlias /cgi-bin/ "/apache$documents/cgi-bin/" <-- enable scripting ScriptAlias /scripts/ "/apache$documents/scripts/" <-- enable scripting ScriptAlias /ics_private_scripts/ "/apache$documents/ics_private_scripts/" <-- enable scripting # <Directory "/apache$documents/cgi-bin"> AllowOverride None Options None Order allow,deny Allow from all </Directory> # <Directory "/apache$documents/scripts"> AllowOverride None Options None Order allow,deny Allow from all </Directory> # <Directory "/apache$documents/ics_private_scripts"> AllowOverride AuthConfig <-- enable authorization Options None Order allow,deny Allow from all </Directory> #
Most form data sent to Apache will be less than or equal to 32,767 bytes. But if you are supporting file-upload like so:
<form method="post" enctype="multipart/form-data" action="/scripts/upload_test_neil"> <input type="text" name="textline"> <input type="file" name="datafile"> <input type="submit" name="Send"> </form>...then you might experience uploads larger than 32,767 bytes. Okay so what's the big deal? Well, if your CGI program was written in "C" then it would be no big deal to read Apache symbol "CONTENT_LENGTH" then malloc that amount (if you have enough memory). Next, you would call fopen(fname,"rb") then read the whole amount all in one operation.
This is not possible if your CGI program was written in BASIC since that language limits strings to a maximum size of 32,767. This means you would need to do multiple reads until you have extracted CONTENT_LENGTH bytes.
Telnet www.bellics.net 80 <<<--- type this then hit <enter> (or "telnet 127.0.0.1 80") HEAD / HTTP/1.0 <<<--- type this then hit <enter> <<<--- hit <enter> (a blank line to end the HTTP request header) HTTP/1.1 200 OK <<<--- start of the HTML response header Date: Mon, 08 Jun 2009 20:17:47 GMT <<<--- server's current time stamp Server: Apache/2.0.52 (OpenVMS) mod_ssl/2.0.52 OpenSSL/0.9.7d <<<--- web server flavor and version; ssl version Last-Modified: Thu, 13 Aug 2009 16:59:51 GMT <<<--- web page time stamp (for receiver's caching logic) Accept-Ranges: bytes <<<--- server accepts "bytes" Connection: close <<<--- one request and one response Content-Type: text/html <<<--- the following document is HTML formatted <<<--- notice the blank line to end the HTTP response header
Telnet www.bellics.net 80 <<<--- type this then hit <enter> (or "telnet 127.0.0.1 80") GET / HTTP/1.0 <<<--- type this then hit <enter> <<<--- hit <enter> (a blank line to end the HTTP request header) HTTP/1.1 200 OK <<<--- start of the HTML response header Date: Mon, 08 Jun 2009 20:17:47 GMT <<<--- server's current time stamp Server: Apache/2.0.52 (OpenVMS) mod_ssl/2.0.52 OpenSSL/0.9.7d <<<--- web server flavor and version; ssl version Last-Modified: Thu, 13 Aug 2009 16:59:51 GMT <<<--- web page time stamp (for receiver's caching logic) Accept-Ranges: bytes <<<--- server accepts "bytes" Content-Length: 982 bytes <<<--- the HTML content block is 982 bytes Connection: close <<<--- one request and one response Content-Type: text/html <<<--- the following document is HTML formatted <<<--- notice the blank line to end the HTTP response header <html> <<<--- start of HTML content (the web page) <head> <title>Integrated Convergence Support Information System</title>
line | notes |
---|---|
1 | telnet to "www.bellics.net" using TCP/IP port 80 (telnet defaults to port 23) |
2 | GET will pull back the whole web page; use HEAD or OPTIONS to only pull back server data |
"/" requests the server's default document found in the root directory; you could have also entered something like: "/default.htm" or "/login.html" or "/scripts/whatever" | |
HTTP/1.0 indicates we do not want a persistent connection etc. (keep things really simple in this demo) | |
3 | a blank line indicates the end of the sender's HTML request block |
line | data | description |
---|---|---|
1 | HTTP/1.1 | I am able to support HTTP version 1.1 (persistent connections, etc.) |
200 OK | HTTP status message indicating that everything went as planned | |
2 | Date ... | server's current date + time usually in international format |
3 | Server ... | Server software and installed security modules |
4 | Last-Modified | last modified date of the file I am sending you (for your cache) |
Telnet www.bellics.net 80 <<<--- type this then hit <enter> (or "telnet 127.0.0.1 80") GET / HTTP/1.1 <<<--- type this then hit <enter> host: www.bellics.net <<<--- host is mandatory with HTTP/1.1 content-type: text/html <<<--- optional: says "I can process HTML documents" connection: close <<<--- optional: return a page then close (do not persist) <<<--- hit <enter> (a blank line to end the HTTP request header) HTTP/1.1 200 OK <<<--- start of the HTML response header Date: Mon, 08 Jun 2009 20:17:47 GMT <<<--- server's current time stamp Server: Apache/2.0.52 (OpenVMS) mod_ssl/2.0.52 OpenSSL/0.9.7d <<<--- web server flavor and version; ssl version Last-Modified: Thu, 13 Aug 2009 16:59:51 GMT <<<--- web page time stamp (for receiver's caching logic) Accept-Ranges: bytes <<<--- server accepts "bytes" Content-Length: 982 bytes <<<--- the HTML content block is 982 bytes Connection: close <<<--- one request and one response Content-Type: text/html <<<--- the following document is HTML formatted <<<--- notice the blank line to end the HTTP response header <html> <<<--- start of HTML content (the web page) <head> <title>Integrated Convergence Support Information System</title>
Caveats:
Legend: <ur> user response <sr> system response -------------------------------------------------------------------------------- <sr> $ ! default DCL prompt <ur> Telnet 192.168.210.220 80 !connect to proxy server on port 80 <sr> %TCPWARE_TELNET-I-TRYING, trying concealed.ca,http (192.168.210.220,80) ...
%TCPWARE_TELNET-I-ESCCHR, escape (attention) character is "^\" <ur> CONNECT www.bellics.com:80 HTTP/1.1 ! connect to node on port 80 using HTTP1.1 ! blank line ends HTTP connect header <sr> HTTP/1.1 200 Connection established ! proxy has connected <ur> GET / HTTP/1.1 !
host: www.bellics.com !
content-type: text/html !
connection: close ! ! blank line ends HTTP request header <sr> HTTP/1.1 200 OK ! start of HTTP response header
Date: Mon, 08 Jun 2009 20:17:47 GMT
Server: Apache/2.0.52 (OpenVMS) mod_ssl/2.0.52 OpenSSL/0.9.7d
Last-Modified: Thu, 13 Aug 2009 16:59:51 GMT
Accept-Ranges: bytes
Content-Length: 982 bytes
Connection: close
Content-Type: text/html
<html> ! start of HTTP payload
<head>
<title>Integrated Convergence Support Information System</title>
$PRODUCT INSTALL /destination=disk$user1:[000000]
Compaq states that an ODS-5 volume is not required for a non-JAVA installation of CSWS, but I've found that the online documentation for "mod ssl User" will be corrupt due to the presence of filenames with multiple dots (which is supported in the optional ODS-5 but not the standard ODS-2). What's worse is that you won't see any error messages during installation to an ODS-2 disk. Because I thought that other things could have become compromised, I decided to only install to ODS-5 volumes.
This paragraph has nothing to do with the web servers but I decided to mention it here anyway. If you've enabled ODS-5 then you might notice a few strange changes:
If a file is created by an application program written in a high level language (e.g. BASIC, C, C++, etc.) and the file name was defined using lower case characters, and the file doesn't yet exist, then when the file is created you will see a lower case name in the associated directory. If the file already exists, a new file of the same name and location will match the case of the original file.
This DCL command (in effect by default) will make your interactive session work the ODS-2 way on an ODS-5 system.
$set proc/parse_style=traditional/case_lookup=blind
This command will allow you to make your process case-sensitive (so you can rename a file changing its case):
$set proc/parse_style=extended/case_lookup=sensitive
CAVEAT: If your system has been running for years in case-blind mode, then it would be a real bad idea to place this case-sensitive entry into system file "SYS$MANAGER:SYLOGIN.COM". However, it is a completely different situation if your system is new AND all users will be running in case-sensitive mode. Consult HP OpenVMS System Manager's Manual, Volume 1: Essentials before you make any changes affecting more than one account. I have encountered situations were a user couldn't even log off.
HP released SWS-2.0 (which is based upon Apache 2.0.47) in December of 2003. One shocking change is that all served up web pages (text files) must be first converted to STREAM_LF before they can be used. There were several reasons given in newsgroup: comp.os.vms (and archived here www.deja.com ) which included:
IMHO, they should have created an Apache plug-in (mod_rms ?) to allow backward compatibility when desired. A good work around for this restriction involves setting up PHP to pickup and process unconverted HTML files.
EnableMMAP Off DefaultType text/plain
Analyzing Apache log files will show a huge number of references to a missing file named favicon.ico
# # file: [.conf]httpd.conf # { ...snip... } # need this next line for favicon.ico (NSR - 2012-08-09) # AddType image/x-icon .ico
# # file: [.conf]ssl.conf # { ...snip... } # # this old Apache declaration is no long 100% true (why treat all IE browsers badly?) # #SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown # # experimental hack to speed up SSL for IE users - NSR (2012-08-13) # #BrowserMatch "MSIE [1-4]" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0 #BrowserMatch "MSIE [5-9]" ssl-unclean-shutdown # # experimental hack to speed up SSL for IE users - NSR (2012-08-14) # # note: "MSIE 1" (above) didn't support SSL so it is superfluous # Meanwhile, "MSIE 1" probably break MSIE 10 when it finally appears) # BrowserMatch ".*MSIE [2-5].*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
Our intranet site employs AJAX and certain apps continually (every minute) pull back three little gifs. What is worse is this: these gifs are sent over the encrypted channel (which adds additional overhead) and the problem is multiplied by the fact that more than 120 employees are using the app at the same time. You can't control how a user sets up his browser "cache-wise", but the following tweak has greatly reduced the problem on my system:
Caveats:# # file: [.conf]httpd.conf # [...snip...] #---------------------------------------------------------------------------------------- # 2014 tweak to reduce data sent to the browser # # send less text to the browser (repeated for every page component) # # (default) send: Server: Apache/2.0.63 (OpenVMS) mod_ssl/2.0.63 OpenSSL/0.9.8w # ServerTokens OS send: Server: Apache/2.0.63 (OpenVMS) # ServerTokens Min send: Server: Apache/2.0.63 # ServerTokens Prod send: Server: Apache # #---------------------------------------------------------------------------------------- #ServerTokens Min ServerTokens Prod #---------------------------------------------------------------------------------------- # consider sending less caching information to the browser # note: ETag is not sent with dynamic content # # FileETag All sends something like this: "8f0101a-ec2-2de84100" # FileETag MTime Size sends something like this: "ec2-2de84100" #---------------------------------------------------------------------------------------- FileETag All #---------------------------------------------------------------------------------------- # force browsers to cache more stuff but don't go crazy # # notes: # 1) verified with Apache/2.0.63 on OpenVMS # 2) Expires directives were removed so don't load mod_expire # 3) Header directives require mod_header # 4) Reduce the size of each response header as much as possible # 5) typing CTRL-R or clicking page reload will force browsers to do cache revalidation #---------------------------------------------------------------------------------------- #ExpiresActive On # bowsers after IE7 prefer Cache-Control rather than Expires #ExpiresDefault now # bowsers after IE7 prefer Cache-Control rather than Expires # # note: when enabled, this next line blocks IE8 from downloading DOCX files # Header set Cache-Control "no-cache, max-age=0, s-maxage=0" # # this next line is for all documents (dynamic and static) so... # always use a small value (good) or disable the directive (better) # # Header set Cache-Control "public, max-age=0" #---------------------------------------------------------------------- # this will override (if a static file) something set above #---------------------------------------------------------------------- # a-block <FilesMatch "\.(ico|gif|jpg|jpeg|png|pdf)$"> Header unset Cache-Control Header set Cache-Control "max-age=86400, public" # note: the next line must not be used in production # Header set MyHeader "trigged Neil's a-block" </FilesMatch> #---------------------------------------------------------------------- # this will override (if a static file) something set above #---------------------------------------------------------------------- # b-block <FilesMatch "\.(htm|html|js|css)$"> Header unset Cache-Control Header set Cache-Control "max-age=3600, public" # note: the next line must not be used in production # Header set MyHeader "trigged Neil's b-block" </FilesMatch> #---------------------------------------------------------------------- # this will override (if a static file) something set above #---------------------------------------------------------------------- # c-block # comments: # 1) we are trying to better support the client-server model for clients around the world # (some of the clients to this Canadian system are in India; others are across Canada) # 2) really big files that don't change much should be cached for 24-hours # 3) experiments with regex wildcarding # regex reference: The wildcard . matches any character. For example, # a.b matches any string that contains an "a", then any other character and then a "b" # while a.*b matches any string that contains an "a" and a "b" at some later point. <FilesMatch "(jquery|angular|ddsmooth).*\.(css|js)$"> Header unset Cache-Control Header set Cache-Control "max-age=86400, public" # note: the next line must not be used in production # Header set MyHeader "trigged Neil's c-block" </FilesMatch> #----------------------------------------------------------------------------------------- { ...snip... }
# # file: [.conf]httpd.conf # { ...snip... } # # enable HTTP/1.1 keepalives so clients do not open/close on every page component # KeepAlive On # # more efficient than the default of 15 (should never exceed 60 seconds) # KeepAliveTimeout 30 # # more efficient than the default of 100 # MaxKeepAliveRequests 999 # # since Apache only grows once per second, start off with MaxSpareServers # StartServers 9 MinSpareServers 6 MaxSpareServers 12 # # you will never have more server processes than MaxClients # # If you set MaxClients too large then you might run out of VMS process slots when # hackers use Apache to probe our system (I have seen this happen). # Consider using SYSGEN to increase MaxProcessCnt when you increase MaxClients # MaxClients 100 # MaxRequestsPerChild defaults to 0 (which is good when there are no memory leaks) # MaxRequestsPerChild 999 # # send less text on the server line (affects every web page, and page component) # # "ServerTokens Full" (default) sends this: # Server: Apache/2.0.63 (OpenVMS) mod_ssl/2.0.63 OpenSSL/0.9.8w # "ServerTokens Min" sends this: # Server: Apache/2.0.63 # "ServerTokens Prod" sends this: # Server: Apache # ServerTokens Prod [...snip...]
Apache needs resources for interprocess communications (VMS mailboxes are like UNIX pipes)
legend: <sr> = system response <ur> = user response ------------------------------------------------------------------------- recording your current sysgen settings to a file <sr> $ <ur> def/user sys$output sysgen_20131031.txt ! output will be diverted <sr> $ <ur> mcr sysgen <sr> SYSGEN> <ur> sho /all ! output goes to file <sr> SYSGEN> <ur> exit <sr> $ <ur> type sysgen_20131031.txt <sr> ...file contents are displayed... ------------------------------------------------------------------------- making changes to your running system (DANGER) <sr> $ <ur> mcr sysgen <sr> SYSGEN> <ur> sho maxbuf <sr> Parameter Name Current Default Min. Max. Unit Dynamic -------------- ------- ------- ------- ------- ---- ------- MAXBUF 8192 8192 4096 64000 Bytes D <ur> set maxbuf 64000 <sr> SYSGEN> <ur> set defmbxbufquo 64000 <sr> SYSGEN> <ur> set defmbxmxmsg 64000 <sr> SYSGEN> <ur> write current <sr> SYSGEN> <ur> write active <sr> SYSGEN> <ur> exit <sr> $ -------------------------------------------------------------------------- ensure you add these overrides to file sys$system:modparams.dat
Image-based Counters
These seem to be the gold-standard in counters. Between 1995 and 2000 (when web servers were powerful platforms serving up mostly static webpages to underpowered desktop PCs sporting Pentium-2 or Pentium-3 processors) most sites used a bit of freeware written by Muhammad Muquit named "count". Needless to say, I am envious of his programming skills. But this solution places a more-than-a-trivial computational burden on the server. Why? Updating a count-file is the easy part so no problem here. However, using the count-file digits to reference a library of individual digits graphics then assemble binary slices scan-line by scan-line into a resultant GIF is the harder part.
Needless to say that Muquit's program works on many webserver flavors including those for OpenVMS. Some of those distributions can be found hereText-based Counters (2013-11-xx)
I'm running an overworked decade-old server (an AlphaServer DS20e installed in 2002) and now think the time has come to shift the computational burden from the server to the client's browser. I have a little "C" program ready which increments the counter file then sends back the plain-text result. The calling webpage uses a small amount of AJAX (~20 lines) to send the increment request, receive the plain-text count, then inject the value into the browser's DOM for rendering. The browser may not have access to all the cool image libraries seen in Muhammad's offering but that may not be as big a deal as you might think. At least your boss (and user community) will get instant feedback.
On my systems, most users can't tell one font from another so never noticed anything other than a faster response.
Okay so it looks like IE-11 is always asking for file browserconfig.xml from your server root directory
So the best way forward is to create a minimal version of this file in the server root (on my system we have "/" mapped to "/apache$Documents/main/")
<?xml version="1.0" encoding="utf-8"?> <browserconfig> <msapplication> </msapplication> </browserconfig>
$ dir/full APACHE$HTTPD.EXE
Directory APACHE$COMMON:[000000]
APACHE$HTTPD.EXE;5 File ID: (13942,118,0)
Size: 25/32 Owner: [AP_HTTPD,APACHE$WWW]
Created: 22-AUG-2012 18:00:19.83
Revised: 6-DEC-2013 14:13:29.47 (3)
Expires: <None specified>
Backup: <No backup recorded>
Effective: <None specified>
Recording: <None specified>
Accessed: 6-DEC-2013 14:13:26.49
Attributes: 6-DEC-2013 14:13:29.47
Modified: 23-AUG-2012 09:27:27.75
Linkcount: 1
File organization: Sequential
Shelved state: Online
Caching attribute: Writethrough
File attributes: Allocation: 32, Extend: 0, Global buffer count: 0, Version limit: 15, Contiguous best try
Record format: Fixed length 512 byte records
Record attributes: None
RMS attributes: None
Journaling enabled: None
File protection: System:RWED, Owner:RWED, Group:, World:
Access Cntrl List: (IDENTIFIER=APACHE$EXECUTE,ACCESS=READ+EXECUTE)
ClClient attributes: None
accessing this path | ran the authentication code this many times | (file: default.html exists?) |
http://node/yada/ | 6 | N |
http://node/yada/ | 2 | Y |
http://node/yada/file.ext | 1 | n/a |
mod_auth mod_auth_basic |
supports Basic access authentication
using a base64 Authorization string mod_auth was renamed to mod_auth_basic in Apache-2.2 |
mod_auth_digest | better than Basic in that the username + password are message digest encrypted |
mod_auth_kerberos | authenticates by dipping into Active Directory (a.k.a. Microsoft stuff) |
mod_auth_ldap | authenticates by dipping into LDAP |
mod_auth_openvms | authenticates by dipping into SYSUAF (a.k.a. OpenVMS stuff) |
Note: this will aid in analyzing your Apache log files so you can improve your web server system. Failure to do this places all your transactions in one huge file.
<sr> $
<ur> sh time
<sr> 27-NOV-2005 20:52:11
$
<ur> dir [...]*.*/siz=all/date/sel=siz=min=10000
<sr> Directory APACHE$COMMON:[000000.SPECIFIC.KAWC15.LOGS]
ACCESS_LOG.;1 1061068/1061095 16-SEP-2003 19:48:46.00
ERROR_LOG.;1 455636/455700 16-SEP-2003 19:48:44.50
SSL_ENGINE_LOG.;1 238230/238280 16-SEP-2003 19:48:44.56
$
<ur> del APACHE$COMMON:[000000.SPECIFIC.KAWC15.LOGS]*_log*.*;*
Wow! These files have been growing 26 months
Notes:
$ set def sys$common:[000000.specific.www.logs] ! $ ren *_log*.* [.log31] ! okay to do this while files are open $ @APACHE$COMMON:[000000]APACHE$SETUP ! create Apache symbols for our process
$ httpd -k flush ! tell Apache to flush the log buffers to disk
$ httpd -k new ! tell Apache to close current files then open new ones
Overview: A few common character sets
Character Set | Set Size | Character Size | Notes | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
7-bit ASCII | 128 | one byte | standardized (uses 8 bits but the top bit is always zero) | ||||||||||||
8-bit ASCII | 256 | one byte | non-standard; no rules for the upper half; lower half is the same as 7-bit ASCII | ||||||||||||
ISO-8858-1 | 256 | one byte | standardized; not all 256 are defined; lower half is the same as 7-bit ASCII | ||||||||||||
Windows-1252 | 256 | one byte | standardized; 32 more characters than ISO-8859-1; also called ANSI | ||||||||||||
Unicode 9.0 | char: 128,237 total: >1 million |
It depends: 2-bytes (Windows) 4-bytes (Linux) |
standardized;
|
||||||||||||
UTF-8 | 1,112,064 | variable | one to 4 bytes (this limit was set in 2003 by RFC-3629) |
Wide Characters + Multibyte
Back in the early 1990s, most data communications occurred via modems so engineers were always looking for ways to send it so that it so that it would not lockup the modem. Many standards were developed including UCS-2 which precedes UTF-16, UCS-4 which precedes UTF-32 but UTF-8 became the most popular. Too bad its implementation in internet applications was so ad-hoc.
<meta charset="UTF-8">
The creators of the "charset kludge" probably meant "character set will be Unicode but will follow UTF-8 encoding rules" HTTP/1.1 200 OK Date: Mon, 23 May 2005 22:38:34 GMT Content-Type: text/html; charset=UTF-8 Content-Encoding: UTF-8 Content-Length: 138 Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux) Connection: close
<?xml version="1.0" encoding="UTF-8"?>
While the browser wars are over, browser vendors are still going out of their way to make sure documents render properly no matter what the server told them. For example, most versions of IE will render documents even though they are not HTML compliant (e.g. a missing tags like: <html> , <head> , and <body>). On top of this, all browsers tend to support only two character set flavors:
quote: browsers will change to Windows-1252 when ISO-8859-1 is declared. This is done for any DOCTYPE:
HTML4, HTML5, and XHTML.
reference-1: http://www.w3schools.com/charsets/ref_html_ansi.asp
quote: Most modern web browsers and e-mail clients treat the MIME charset ISO-8859-1 as Windows-1252 to
accommodate such mislabeling. This is now standard behavior in the HTML5 specification, which requires that documents
advertised as ISO-8859-1 actually be parsed with the Windows-1252 encoding.
reference-2: https://en.wikipedia.org/wiki/Windows-1252
This directive specifies the name of the character set that will be added to any response that does not have any parameter on the content type in the HTTP headers. This will override any character set specified in the body of the document via a META tag. A setting of AddDefaultCharset Off disables this functionality. "AddDefaultCharset On" enables Apache's internal default charset of iso-8859-1 as required by the directive. You can also specify an alternate charset to be used; e.g. "AddDefaultCharset utf-8"
Both these HTTP methods...
...can be coupled to a SUBMIT button on your HTML form -and- will usually (at least before 2008) default to the character set defined for the currently rendered web page. But this is not the case for AJAX-based pushes which now default to UTF-8 no matter what character set was used in the currently rendered web page. To confuse things further:
Total Bytes |
Data Bits |
First code point |
Last code point |
Byte 1 | Byte 2 | Byte 3 | Byte 4 |
---|---|---|---|---|---|---|---|
1 | 7 | U+0000 | U+007F | 0xxxxxxx | |||
2 | 11 | U+0080 | U+07FF | 110xxxxx | 10xxxxxx | ||
3 | 16 | U+0800 | U+FFFF | 1110xxxx | 10xxxxxx | 10xxxxxx | |
4 | 21 | U+10000 | U+10FFFF | 11110xxx | 10xxxxxx | 10xxxxxx | 10xxxxxx |
Behind the scenes (information for programmers)
Update: 2015-07-29
Update: 2016-09-xx