Index of /public/ikrs.httpd

Icon  Name                    Last modified      Size  Description
[PARENTDIR] Parent Directory - [DIR] docs/ 2013-07-08 23:56 -

A free tiny java written http server.

Current Yucca version:      1.0.0.alpha
Current ikrs.httpd version: 1.0.13.alpha

Note: I started to write this piece of software in April 2012.
      I'm still working on this project and I'm doing this just for fun 
      but with passion.


  - Added the JSONRPCExampleHandler that demonstrates how to bind a
    JSON-RPC (JavaScript Object Notation/Remote Procedure Call) handler
    into the servers root directory by the use of htaccess (and Java).
    See /tests_and_examples/jsonrpc/ for the example (at document root).

  - The literals "ISO-8859-1" and "UTF-8" were restored in global
    constants and replaced in all source code files by the
    java.nio.charset.StandardCharsets.*.name() values.
    This is why the new version only runs with java 7 (was java 6

  - Made the default error document configurable via 
    ERROR_DOCUMENT.DEFAULT in the {USER_HOME}/.yucca/ikrs.httpd.conf
    file. The default error document is still located inside the
    document root at /system/errors/, but I renamed the file to

  - The error documents now provide (optional) placeholders for the
    actual error messages generated by the server: 
     - {STATUS_CODE}
    I modified the default error documents by adding %{ERROR_MESSAGE}%
    to each and adding an example file with all placeholders:

   Added more runtime statistics:
     - #requests
     - #errors
     - #warnings
    Note: last error and last warning dropped (mind the logger)]

  - Added javadocs at ./document_root/docs/

  - HTTPD command 'HEXDUMP FORMAT' for hexdump output configuration added.
  - Moved the HexDumpOutputStream creation from AbstractPreparedResponse
    to HTTPHandler.
  - Added 'HEXDUMP_FORMAT' to the ikrs.httpd.conf file.

  - Added the HTTPDRuntimeStatistics class.
  - Added a static HTTPHandler.sharedInstance field.
  - Extended the HTTPD STATUS command.

  - Built a ReplacingInputStream based on the MultiStopMarkInputStream

  - The method did not
    return a proper value; even if the stop mark was reached it 
    returned false.
  - Wrote a MultiStopMarkInputStream that allows to pass a whole set of
    possible stop marks for the underlying stream. Idea: use the new
    stream 'tokenizer' to build configurable error documents 
    (placeholder processor).
  - Added the and 
    *.continueStream(boolean overrideEOI) methods.
  - Added ikrs.util.ByteArrayComparator.

  - Fixed: the directory listing missed trailing slashes in directory 
    link names.
  - Finished the XML example parser class: XMLExampleHandler.
    Call {DOCUMENT_ROOT}/tests_and_examples/xml_example_parser/ from
    your browser to run it.

  - The DefaultPostDataWrapper didn't remove the trailing bytes CRLF
    from each multipart item; this was fixed and the XMLExampleHandler
    now counts the correct number of data bytes.

  - Header field 'Content-Disposition' declared in 
  - Fixed an EOI issue (0 read bytes replaces by -1, EOI) in 
  - Built advanced HeaderParam methods 
    (again: the ikrs.httpd.datatypes.* classes are still experimental!).
  - Built basic POST data handling for the XMLExampleHandler class.
    See source for details (not yet finished).
    For a working basic test see 
    {DOCUMENT_ROOT}/tests_and_examples/xml_example_parser. A detailed
    description is located in the source code of the 'example.xmlparser'
  - Fixed: the FormDataItem extended KeyValueStringPair, but it may also 
    contain binary data! Each FormDataItem has a header part and an 
    internal input stream to read from.
  - The FormData had no method(s) to retrieve the key set; as it 
    consists of a sequence of form data items which has a header set
    each such a method is not required any more.
  - Fixed a white-space issue in the HeaderParam parser; all values are
    trimmed now and do not contain any trailing or leading white space
    characters any more.

  - The ikrs.httpd.datatype.HeaderParams is now a three-dimensional 
    structure recocnizing the delimiter chars [ ',', ';', '=' ] in 
    exactly this order; the structure was two-dimensional before.
  - The ikrs.httpd.datatype.FormData and all its implementing classes
    were slightly changed.
  - The QueryFormDataDelegation class is now deprecated and MUST NOT be
    used any more.

    Note that the whole ikrs.httpd.datatype package is highly 
    experimental and should be used for test cases only!
    Actually it does not cover RFC 2616 at all as it contains very basic	
    MIME tools and some very simple parser classes.

  - Fixed an issue with the directory listing: 
    the DefaultDirectoryResource did not add the trailing slash '/'
    after directory hyperlinks, so HTTP forms might have sent their
    GET/POST data into the wrong directory (the parent).

 - The ikrs.http.HTTPHeaderLine is someting like a key-value-pair. It 
   extends ikrs.util.KeyValueStringPair now.

 - Yucca's command line currently did not allow additional white space
   chars between command name and additional arguments.
   Actually it was a regex problem in the 
   ikrs.util.AbstractCommandFactory.parse(...) method.
 - Renamed ikrs.http.LocalCommand to ModuleCommand, and also it's 

  - Yucca command LOGLEVEL built.
  - Yucca command VERSION built.
  - Commandline documentation written (see README).

  - Added the response-characterSet (name) to the ResourceMetaData.
  - Slighty modified the custom_directory_handler example by adding
    the {DOCUMENT_ROOT} to the output; also added some fancy text-box
    stuff ;) ... actually this is the most important example class as it
    shows how to extend the HTTP handler without modifying the handler

  - The STATUS command prints the current system configuration; there is
    a fix that hides sensitive data such das keystore and truststore 
    passwords (otherwise the passwords would be written into the log 

  - Solved the logger's log level issue; both (yucca and ikrs.http) now
    use the same logger instance.
  - Changed YuccaCommadFactory's command lookup order: parent commands 
    first, subclasses' commands later (makes it possible to override 
    existing commands).

  - Enhanced the ikrs.util.session.Default- and AbstractSessionManager
    by adding a new (optional) 'threadSafe' param; this allows to tell
    the manager to use synchronized session maps and so does the 
    HTTPHandler now.

  - Status code for 'Content-Range' responses changed to 206 (Partial
    Content); was still 200 before.
  - Added the ParametrizedHTTPException class to the ResponseBuilder
    to allow to override the status code/reason phrase at the error
    response builder.
  - The ResouceMetaData now has a last-modified field.
  - There is now an ETag class (Entity tag) and the OK response already
    uses the generated ETag hash for response headers.
  - The HTTPHandler now has a global DateFormat that should be used to
    generate Date strings in the required HTTP Date format; for details
    see section
  - The '206 Partial Content' response now contains the 'Date' and 
    'Expires' headers (sent if the 'Content-Range' request is present).
  - Solved an issue with the DefaultDirectoryResource; in some cases an
    additional slash ('/') was added between the path base and the 
    linked file(s).

  - EOI bug in ikrs.httpd.ReadLimitInputStream solved [reaching the 
    virtual end did not necesarily cause -1 but 0 (zero) to be 
    returned which caused an infinite loop in the RangedRessource's
    inputstream read procedures].
  - Implemented the ikrs.httpd.resource.ResourceDelegation and
    RangedResource class.
  - Implemented download recovery (from a specified byte position):
    the server now recognizes the 'Content-Range' header; some new
    classes were added and still need some testing, but the 
    ikrs.httpd.resource.RangedResource seems to work fine so far.

  - Bug fixed in the ProcessableResource class: the open(boolean) method
    blocked on the system process's internal output buffer overflow.
    The output data is now being read while (!) the process is running.
  - New test script added to check if binary data (such as images) is
    correctly handled and displayed:
  - The 'Status' header handled by the PHPHandler now applies the 
    original HTTP version number (from the request headers; was always
    1.1 before).
  - The PHPHandler now applies the generated MIME type (from the PHP 
    output headers) to the resource's meta data (default was text/plain

  - Yucca's ConnectionHandler (TCP) instance can now be re-used (shared 
    This is set by the flag 'sharedHandlerInstance' in the server.xml 
  - The the directory list generator still used an old (not valid any 
    more) favicon URL. This is fixed.
  - Cleaned up document_root directory: moved all tests into the sub 
    directory 'tests_and_examples'.
  - Replaced the HTTPHandler internal maps by threadsafe versions (from 
    java's util.Collections class).!

  - The AbstractPreparedResponse now uses the same HTTP version such as 
    in the request headers.
    This causes the server to send HTTP/1.0 replies when the request is 
    version 1.0 (response was always sent in version 1.1 before).
  - The default error document map is now configurable by 

  - The HypertextAccessFile class now recoginzes the 'ErrorDocument' directive.
    Additionally the HTTP handler has a new method 'getDefaultErrorDocumentURI(...)'].
    Result: htaccess' ErrorDocument directives are now handled (though the default error document
    	    set is not yet configurable).

 - The CGI PATH_INFO and PATH_TRANSLATED were fixed (contained corrupt values before).
 - The CGI environment vars DOCUMENT_ROOT, SCRIPT_FILENAME and REQUEST_URI were added.
 - The internal session now stores REMOTE_ADDRESS, REMOTE_PORT, REMOTE_HOST and also LOCAL_ADDRESS,
 - The ikrs.httpd.filehandler.CGIHandler class has an internal HEADER-to-CGI set now that explicitly
   allows a specified subset of HTTP headers to be mapped into the GCI environment.
   By default these headers are:
      - Accept
      - Accept-Charset
      - Accept-Encoding
      - Accept-Language
      - Connection
      - Cookie
      - Host
      - Referer
      - User-Agent
 - Tested the server with Drupal-7.15. Worked after some drupal configuration issues :)

 - Additional error documents added.
 - Reqest-Line parser method fixed (for the case a fully malformed non-HTTP request was sent).
 - The session timeout is now configurable using the ikrs.http.conf file:
 - The yucca command line is now extensible and capable to handle advanced httpd commands (none exist
   so far, though).

 - There was an issue with the session timeout handling and it is fixed now. 
   Additionally I created a nested SESSION.INTERNAL child now holding the environment data used in the
 - The file handler example now also shows how to use sessions.

 - Some tests with customized file/directory handlers (htaccess, SetHandler) exposed a flaw inside the
   system when using non-existing files; it is now possible to configure FileHandlers by overriding the
   'requiresExistingFile()' method and mock the ResourceAccessor this way: you can now also pass virtual 
   URIs, if you want to.
   See the ikrs.httpd.filehandlers.IkarosExampleHandler for details.
   A configured example directory is located in the default document root at /custom_directory_handler.
   Try to request a non existing file or sub directory, such like /custom_directory_handler/not_existing
   and see what happens :)
 - The hexdump output of requested files during transfer is now restricted up to 10KB of data. Then the 
   output on stdout stops to avoid flooding.
 - still wrote debug data into stdout. The debug/info output was moved

 - Built a nested htaccess evaluation. Before the application just searched up the document
   tree until the first htaccess file was found. That was not correct! *All* htaccess files
   upon the request path are now used; later occurrences override earlier stated stettings.
   The HyptertextAccessFile class got a new merge() method for this purpose.

  - Moved ikrs.httpd.datatype.KeyValueStringPair to ikrs.util.KeyValueStringPair.
  - Added a handler method in HTTPHandler.rejectedExecution(...) that processes rejected requests fast and 
  - SSL default example configuration issue solved.

  - There is a new utility class: that can be used to copy files and nested directories.
  - The yucca main class now has a first-run-check. If the configuration files or -directory do not exist the 
    program performs a short survey and creates the config files and -directories automatically.
    The templates are located in '_.templates/'.

  - File paths may now contain the '{USER_HOME}' placeholder (for yucca and httpd).
  - Renamed document root 'document_root_alpha' to 'document_root'.
  - Moved configuration directory '_.yucca/' to '{USER_HOME}/.yucca/'.
  - Buy in method ikrs.httpd.CustomUtil.classImplementsInterface(...) fixed.
  - DOCUMENT_ROOT is now configurable via .yuccasrv/ikrs.httpd.config#DOCUMENT_ROOT.
  - New yucca-commands: 'warranty' and 'license'.

  - Changed package name from 'ikrs.http' to 'ikrs.httpd'.

  - HTTP methods can now be disabled: ikrs.httpd.conf#DISABLE_METHOD.{METHOD} = { On | Off }

  - INI-file parser added.

  - The ConnectionHandler has a customizable init() method now which applies the whole yucca server config
    into the handler.
  - The yucca config has an (optional) 'httpConfig' node now that can be used to define additional custom
    config settings to the HTTP handler.
  - The filehandlers config is now defined inside the yucca config: httpConfig-node.

  - The HTTP server is now capable to process HTTP TRACE.

  - The HTTP server is now capable to process HTTP OPTIONS and HTTP HEAD.

  - The socket manager ikrs.yuccasrv.socketmngr.BindManager supports secure sockets using SSL/TLS now.

  - The 'filehandlers.ini' is now interpreted and contains the file handler mappings.
  - The htaccess 'SetHandler' and 'AddHandler' directives work now.

  - HTTP POST works now with PHP (actually it was an unsolved php-cgi issue).

  - Replaced HTTPHandler.getServerName() by HTTPHandler.getSoftwareName() to avoid CGI name clash.
  - Built new HTTPHandler.getServerName() method.
  - Built basic CGI/1.1 handler.
  - Finished PHP POST handling.

  - htaccess 'DirectoryIndex' implemented.
  - htaccess 'Options {+|-}Indexes' implemented.
  - New class for directory listings: ikrs.http.resource.DefaultDirectoryResource.
  - The error response 405 (Method Not Allowed) now includes the 'Allow' header.

  - Bug fixed: server sent an '200 OK' even if the external file handler reported runtime errors.

  - htaccess 'Digest' authorization implemented (not apache compatible: ikrs.http.MD5).

  - htaccess 'Basic' authorizaion implemented (apache compatible).

The java documentation files are located at ./document_root/docs/ or
if 'document_root' is your configured {DOCUMENT_ROOT} (the default value)
the files will be available at

Important Notes

Use PHP-CGI instead of PHP-CLI
 - To enable PHP install the 'php-cgi' package (not the commandline 
   interface 'php-cli' or just 'php').
   sudo apt-get install php5-cgi

The "File not found" issue
 - If the PHP interpreter is prompting on each PHP file you want to run 
   (using your browser):

   "<b>Security Alert!</b> The PHP CGI cannot be accessed directly"

   The CGI handler requires to set some environment vars for php-cgi. By 
   default this is not allowed by the 'cgi.force_redirect' directive in 
   your php.ini (php-cgi, NOT php-cli!).
   Locate your php-cgi configuration file, something like
   near line ~834
   ; cgi.force_redirect is necessary to provide security running PHP as 
   a CGI under
   ; most web servers.  Left undefined, PHP turns this on by default.  
   You can
   ; turn it off here AT YOUR OWN RISK
   ; **You CAN safely turn this off for IIS, in fact, you MUST.**
   ;cgi.force_redirect = 1

   Now set 'cgi.force_redirect' to 0 to allow modifications to php-cgi's 
   cgi.force_redirect = 0

 - If the PHP interpreter is not prompting 

   "No input file specified." (Status: 404 Not Found)

   you have to set the document-root in your php-cgi config file,
   near line ~804:
   ; The root of the PHP pages, used only if nonempty.
   ; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set 
   ; if you are running php as a CGI under any web server (other than 
   ; see documentation for security issues.  The alternate is to use the
   ; cgi.force_redirect configuration below
   doc_root = 

   Now set 'doc_root' to your document root.
   doc_root = "/home/your_user_name/java/document_root"

   If this does not fix the problem add an additional document-root 
   server.document_root = "/home/your_user_name/java/document_root"

   Now near line ~850:
   ; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support 
   for CGI.  PHP's
   ; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, 
   and to not grok
   ; what PATH_INFO is.  For more information on PATH_INFO, see the cgi 
   specs.  Setting
   ; this to 1 will cause PHP CGI to fix its paths to conform to the 
   spec.  A setting
   ; of zero causes PHP to behave as before.  Default is 1.  You should 
   fix your scripts
   ; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.

   Set cgi.fix_pathinfo to 1:
   cgi.fix_pathinfo = 1

   NOTE 1: The ikrs.http.filehandler.CGIHandler class will add an 
   	   additional security check field
   	   to the environment vars which will finally fix the "File not 
	   found" issue.

   NOTE 2: I only changed my config in /etc/php5/cgi/, I left 
   	   /etc/php5/cli unchanged.

File-Upload issue: $_FILES is always empty

As soon as PHP (CGI mode) is running there might be the problem of 
failing file uploads (HTTP POST):
PHP's $_FILES array is always empty, even if the file data was 
successfully sent using HTTP POST method.
  (i)  Does you upload form use method="post" and 
       enctype="multipart/form-data"? :)
  (ii) Check your php.ini (in /etc/php5/cgi):
    - Check if 'file_uploads' is enabled.
    - Check if 'upload_tmp_dir' is set (to your system's tempfiles 
      directory or a temp dir of your choice) [near line ~890].
    - Check if your upload-file size does not exceed 'post_max_size'.

How to add custom file handlers

There are three basic steps required to add a custom file- or directory 
 (i)   You need to build your own handler class that implements the 
       ikrs.httpd.FileHandler interface.
       Optionally you might just want to extend the abstract class 
       in that case you have to override the methods 
       'boolean requiresExistingFile()' and 'Resource process(...)'.

       If you are not sure what to do just see the example handler in

 (ii)  You need to bind your handler into the system and assign an alias 
       Do this by editing the {USER_HOME}/.yuccasrv/filehandlers.ini 
       file; add a new line
	<your_handler_alias> = <your_handler_class> 
			       [ <list_of_associated_file_extensions> ]
	   - <your_handler_alias>                 can be any name (not including white spaces), but 
	     					  it should be unique!
	   - <your_handler_class>                 must be the fully qualified class name of your 
	     					  handler (with package name!)
	   - <list_of_associated_file_extensions> Is an optional list of file extensions you want to
	     					  have associated with you handler BY DEFAULT (global!).


 (iii) If you didn't already associate file extensions with your handler you have to do so in the last
       step. Configure the desired directory(~ies) by the use of htaccess' SetHandler/AddHandler
         - 'SetHandler <your_handler_alias>' sets your handler for the current directory (and all files
	   inside and all sub directories).
	 - AddHandler <your_handler_alias> <list_of_associated_file_extensions>' addy your handler for
	   the given file extensions).

	  (a) SetHandler IkarosExampleHandler
	  (b) AddHandler IkarosExampleHandler .ikrs

 Note: file extensions are compared case-insensitive, so '.TXT' would also match '.txt'.


This is the user specific directory containing all configuration files required to run ikrs.yucca/ikrs.httpd.

 This is the global yucca server configuration file.



 The error response files. If the file for a given error code does not 
 exist the server will send an auto-generated response content.

 There is also a default error document for the case a passed status
 code does has no matching error document: 
 the GenericError.template.html file.

 The stylesheet for HTML/XHTML directory listings.

Realtime Commands

 Prints a short summary of all available commands.
 Indeed the HELP command could be a bit mor verbose; a more enhanced
 version might come soon ...

 This is a customized command for the httpd module (added to yucca's
 bind manager). Currently there is only one sub command, which is not
 fully implemented:
    Prints the current status of the HTTPd module.

  - HEXDUMP FORMAT <format>
    Changes the hexdump output column format. The expected value must
    be a comma separated integer list, each integer indicating the 
    respective column list and the number of integers the total number
    of columns.
    Example: the format '4,4,0,4,4' would generate a hexdump format
    	     like this:

    0x00000000  89504e47 0d0a1a0a  0000000d 49484452  .PNG........IHDR
    0x00000010  00000010 00000010  08060000 001ff3ff  ................
    0x00000020  61000000 01735247  4200aece 1ce90000  a....sRGB.......
    0x00000030  0006624b 474400ff  00ff00ff a0bda793  ..bKGD..........
    0x00000040  00000009 70485973  00000dd7 00000dd7  ....pHYs........
    0x00000050  0142289b 78000000  0774494d 4507dc0c  .B(.x....tIME...
    0x00000060  03112534 aaced90e  00000213 49444154  ..%4........IDAT
    0x00000070  38cba592 bfab5c65  10869f99 6fbedd73  8.....\e....o..s
    0x00000080  4eb20917 2f04ae08  c1340662 9b267083  N.../....4.b.&p.
    0x00000090  8db5a6cc 9f10b0f0  cf112d04 ab105258  ..........-...RX

 Prints the license information.

 Add a new listening socket the yucca's bind manager:
 LISTEN [-p <protocol>] [-b <backlog>] <host> <port>

 If succeeded the bind manager fires a serverCreated() event and yucca
 will print a bind summary containing the created socket's ID (this 
 requires the log level to be at least set to Level.INFO; a command for
 changing the level at runtime will be coming soon).
 @See UNLISTEN <socketID>

 Prints or changes the current log level.
 LOGLEVEL [<level>]

 Valid log levels are: 
    - SEVERE (highest value)
    - INFO
    - CONFIG
    - FINE
    - FINER
    - FINEST (lowest value) 

 These are the same values as in java.util.logging.Level (see java docs
 for further details).

 This command quits Yucca. This means that all listening sockets will 
 be released, and the finalize() event will be fired to all running
 server threads and to all bound listeners (such as the HTTPd module).

 Prints the current socket manager status summary containing basic 
 information such as bind addresses, ports, socket IDs, SSL 
 configuration, protocol information and backlog.
 Since version 1.0.3 this command is secure and does not print any
 sensitive data. 

 Releases a listening socket specified by the passed socket ID:
 UNLISTEN <socketID>

 If you don't know a listening socket's ID just use the STATUS
 command. The socket ID is the unique number generated when the
 socket was bound by LISTEN.

 Prints the Yucca version number. This command does not take any

 Prints the warranty.


 A password hash generator for htaccess 'Digest' authorization.
 Usage: java ikrs.httpd.MD5 -r <realm> [-s <salt>] -u <user> [-p <password>]
 	- salt must be 8 characters long.

    > java ikrs.httpd.MD5 -r "My cool realm" -u testuser -p test
    Generating random salt ... 
    Your hashed password (line for .htpasswd): 

 Store the last line printed into your .htpasswd file to add the user to the user list (AuthUserFile).