neokernel_logo_final

Neokernel User Guide Release 2.0

Table of Contents

Part One: Administrators Guide  3

Introduction  3

Starting the Server 3

Command Line Arguments  3

Configuring Server Properties (Props) 4

Server Logs  7

Running the Neokernel as a Windows Service  8

How it Works – Just the Basics  8

Virtual Hosts  9

Props Supported by All Agents  10

com.neokernel.httpd.WebServer 11

com.neokernel.httpd.SecureWebServer 12

com.neokernel.httpd.HTTPFileServerAgent 14

com.neokernel.httpd.HTTPAuthenticationAgent 15

com.neokernel.httpd.HTTPProxyAgent 17

com.neokernel.httpd.HTTPRedirectAgent 18

com.neokernel.httpd.HTTPPutAgent 20

com.neokernel.httpd.LogViewerPage  20

com.neokernel.io.FileReporter 21

Part Two: Developing Dynamic Web Applications with the Neokernel 22

Deploying Custom Request Agents  22

Loading New Agent Components  24

How It Works – The Complete Picture  24

Working with Agent Props  25

Details on the XML Props File  26

Setting classname in Different Scenarios  26

Getting CGI Parameters  27

Tracking Sessions using Cookies and the SessionManager 28

Debugging Neokernel Agents in Visual Studio .NET  29

Other Useful Classes  30

Neokernel Bootstrapping Details  32

 


The following conventions are used in the text of this document:

1.      This font is used to denote text displayed by the user interface, like the names of files, directories, server messages, and errors.

2.      This font is used to denote literal input, output from example programs, user selectable items in the GUI, and prop names.

3.      This mono-spaced font is used to denote examples of source code and the names of classes or namespaces, unless the name is being used in a section title.

4.      Italics indicate emphasis.

5.      Meta-names (for example, words like YourName), which describe the type of text to be entered rather than the literal string, are enclosed in angle brackets, e.g.: <YourName>

Part One: Administrators Guide

Introduction

The Neokernel is a simple, lightweight, secure, and high performance web server. It can be embedded and distributed with other applications or used immediately as a production web server. In addition to serving static files, the server can execute custom C# and Visual Basic software components to generate dynamic content in response to web requests.

The Neokernel lets your application serve static and dynamic web pages without relying on a pre-installed or external web server.

Starting the Server

The Neokernel can be started in three ways:

1. Using the neokernel.exe file. The executable can be launched using Windows Explorer, from a command prompt, or with a .bat file.

2. Running the server as a Service. If the Neokernel Windows Service component is installed, the server can be started and stopped from the Services control panel on Windows NT, 2000 and XP.

3. By embedding the server library in your own .NET application and using the provided APIs to start the server process.

The Neokernel must have a valid license key file, named license, located in the same directory as the executable or library file. The Neokernel comes with a free 30 day license. License keys are available from http://www.neokernel.com.

Command Line Arguments

The neokernel.exe executable supports the following command line syntax:

neokernel [-hide_println] [-hide_debug] [-hide_warning] [-startup_dir <dir>] [-startup_file <.xml startup file>]

 

-startup_dir <dir>

Where <dir> is the path to the directory that neokernel.exe should use as a startup directory.

 

-startup_file <file>

Where <file> is the path to an xml props file that neokernel.exe should use as the startup file.

 

hide_println

If this prop is set to true, all println() output from this kernel is hidden. The default value is false.

 

hide_debug

If this prop is set to true, all debug output from this kernel is hidden. The default value is false.

 

hide_warning

If this prop is set to true, all warning output for this kernel is hidden. The default value is false.

 

Table 1 – Command line arguments supported by neokernel.exe.

Configuring Server Properties ( Props)

Most server behavior is configurable by editing the neokernel_props.xml file. This file is divided into sections corresponding to the components that the server will load at startup.

Each section defines a set of properties (Props[1]) used to configure a specific server component. Neokernel Server components are called agents and include agents for serving web pages and images, authentication, proxy services, and redirection.

If you define a value for a prop in the neokernel_props.xml file, the agent will use that value instead of a default value. Default values are used when the prop isn’t specified. The /demos directory has examples of various server configurations with different neokernel_props.xml files that can be used as templates for your own server configurations.

Multiple Neokernel Server processes can be running at the same time, each with a unique neokernel_props.xml file. The properties in the file are read when the Neokernel Server is started; if you edit the file, you must re-start the Neokernel before your changes will take effect.

The startup file doesn’t have to be called neokernel_props.xml if the server is started with the -startup_file argument to specify a file with a different name.

Note: If you specify a startup file in a different directory than the Neokernel executable, the -startup_dir does not change and the Neokernel’s -startup_dir is the executable directory. Unless the -startup_dir is specified as well, relative paths in the neokernel_props.xml file will be resolved relative to the executable’s directory and not the directory with the startup file.


 

Other files are also used for configuring the Neokernel Server. The following table describes each of these files[2].

File Name

Purpose

neokernel_props.xml

An XML server configuration file with the properties for agents that the server will load. Here is an example of a very simple neokernel_props.xml file:

 

<?xml version="1.0"?>
<props_list>
       <props>
              <agent_id>100</agent_id>
              <classname>AgentOne</classname>
              <startup>true</startup>
       </props>
       <props>
              <agent_id>101</agent_id>
              <classname>AgentTwo</classname>
              <startup>true</startup>
       </props>
</props_list>
</xml>

 

authmap

If the HTTPAuthenticationAgent is running, it uses this file to determine what directories on the server require authentication. The file must contain the names of each secured directory, or realm, and the username / password combinations that are allowed to access that realm. The authentication map file must be in this format:

 
default
PATH0 REALM0
username0 password0
 
PATH1 REALM2
username0 password0
username1 password1
 

Here is an example of an authentication file:

 
default
/private/mine/ My Realm
john johnpassword
santos halper
 
/private/ Main Realm
john mainpassword
 

If the above example is used as the authentication map file, attempts to access http://hostname/private/mine/ will be prompted for a username and password (the prompt will ask for the password to My Realm). If you want to password protect an agent-generated page, set the agent’s service_name so it includes the protected realm (directory) in it’s URL.

 

The default keyword at the start of the example means that the realms apply to ALL domains that this server handles. If you want a realm to apply only to a certain domain, replace the default keyword with the hostname of the domain you want. Multiple domains may be listed in a single authentication map file, as in the following example:

               

www.myserver.com
/private/mine/ My Realm
john johnpassword
santos halper
 
www.myotherserver.com
/private/ Main Realm
john mainpassword

 

redirect

If the HTTPRedirectAgent is running, it uses this file to determine what requests should be redirected and where they should be redirected to. Here is an example of a redirect file:

 
http://myserver/redir1/file.htm=http://yahoo.com/
http://myserver/redir2/=http://redirect1:9000/
http://myserver/redir2/==http://redirect2:9000/
http://myserver/redir2/==http://redirect3:9000/
 

When a browser requests /redir1/file.html, it is redirected to http://yahoo.com. When it requests /redir2, it is redirected to http://redirect1:9000/. The next request for /redir2 is redirected to http://redirect2:9000/. The third incoming request is redirected to http://redirect3:9000/. The fourth request is redirected to http://redirect1:9000/, and the cycle is started again. In this way, the HTTPRedirectAgent can be used for round-robin style load balancing.

 

Complete URLs must be used to specify redirected URLs and the redirect targets.

 

proxy_hosts

If the HTTPProxyAgent is in use, this file provides the list of URLs that will be proxied instead of being handled normally by the Web Server. Here is an example of a proxy file:

 
http://myserver/proxy_me=http://proxy:1099
http://myserver/proxy_me2=http://proxy1:9000
http://myserver/proxy_me2=http://proxy2:9000
http://myserver/proxy_me2=http://proxy3:9000
 

When a browser requests /proxy_me, the WebServer gives the request to the HTTPProxyAgent to handle. The HTTPProxyAgent contacts the web server at proxy on port 1099 and proxies the request to that server. When a browser requests /proxy_me_too, the HTTPProxyAgent will cycle through the 3 web servers indicated, so that the first time the URL is accessed, the connection is proxied to proxy1, port 9000. The second time, the request is proxied to proxy2, the third request goes to proxy3, the fourth request goes to proxy1, and so on.

 

The HTTPProxyAgent also supports listeners, which can proxy all HTTP or HTTPS traffic instead of specific URLs. Listeners are used when you want to provide a proxy for HTTP browsers like Internet Explorer; they are configured to listen on a specific port and IP number, and are specified using the listener prop of the HTTPProxyAgent. For more information, see page 15.

 

mime_types

 

This file describes what MIME types the server should use when sending browsers a file with a specific file extension. If a mime_types file isn’t found, a default set of common MIME types is used.

 

log_maps

The LogViewerPage provides a web interface for viewing summary information from the web server’s log files. If it is running, the log_maps file defines the reports that the LogViewerPage generates. This file should contain names mapped to text patterns. For example, a map file might look like this:

 
Total requests=GET
 
LogViewer requests=GET /logviewer.agent
 

In the above example, LogViewerPage will let the user select from 2 fields, Total requests and LogViewer requests. If the user chooses the report called Total requests, all log entries that match the pattern ‘GET’ will be counted and included in the report. If the user chooses to view the report called LogViewer requests, a smaller set of entries (that match the pattern ‘GET /logviewer.agent’) will be included in the second report. The search patterns used to filter the reports can be regular expressions.

 

 

Table 2 – Server configuration files.

Server Logs

The server generates log files that record server processes and client requests. By default, HTTP log files are generated in a subdirectory of the startup directory called /logs. This directory will be created if it doesn’t exist. The http log files conform to the NCSA-Extended Log File formatting conventions.

By default, all other program output gets routed to the console. If you need to store the console output in log files, look in the neokernel_props.xml file for the com.neokernel.io.FileReporter section and set the startup prop of this agent to true. This agent will log all console output to sequentially numbered text files in the /logs subdirectory of the server’s working directory. You can change the log directory by setting the log_dir prop to a different path (if the log_dir prop is not set, the default value is ./logs).

Running the Neokernel as a Windows Service

The nkservice.exe executable is for running the Neokernel as a Windows Service. The installer registers this executable as a windows service so it can be controlled using the Services control panel. The Neokernel service supports the same command line arguments as the Neokernel console executable.

When the Neokernel is running as a windows service, all of the output that normally appears in the console is logged to sequentially numbered files in the /logs subdirectory of the startup directory. Errors and other significant events will also appear in the Windows Event log, viewable using the Event Viewer[3]

How it Works – Just the Basics

The Neokernel works like other web servers; if a browser requests a file from the server and the file is available, the server delivers it. However, if the requested URL ends in .agent, the server looks for a C# or Visual Basic object mapped to the URL and uses it to generate the response. Classes that handle requests for the server extend the class RequestAgent. The WebServer class hands off incoming requests to these RequestAgent[4] objects which generate dynamic content when their URL is requested. If no file or RequestAgent is found to match the incoming request, a 404 (file not found) error is returned. The WebServer class also manages logging, error responses, and determining the MIME types of files being requested[5].

RequestAgent objects handle requests for the URL specified in their service_name prop. Therefore, when a client requests http://myserver/somepage.agent, the WebServer searches all loaded RequestAgents for an agent with a service_name prop set to /somepage.agent. If it finds one, it calls that agent’s handleRequest method and the agent generates a response.

Here’s a step by step walkthrough:

6.      A client submits a request and the server creates an HTTPRequestObject from the client’s request and the open socket connection with the client.

7.      The server hands off the HTTPRequestObject to an agent specified by the requested URL.

8.      The agent responds to the request using the print() and println() methods of the HTTPRequestObject to send data to the client.

 

 

 

 

 

 

 

 

 

 

 

 


Figure 1 – Neokernel web request task flow.

Virtual Hosts

The Neokernel supports virtual hosts[6], which refers to serving different domains from a single web server. Usually each site is mapped to a different server directory with content for that domain. Visitors to these sites will be routed to the correct virtual host, with its own default pages and web links.

Agents that handle requests for a specific virtual host must include the domain in their service_name when running in a virtual hosts configuration.

To use virtual hosts:

9.      Set the virtual_hosts prop of the WebServer to true and create directories with the content for each of the virtual sites.

10.  Create HTTPFileServerAgent entries in the neokernel_props.xml file for each directory from step 2.

11.  Set the service_name prop of each HTTPFileServerAgent to the virtual host name (e.g. domain name) that it should handle requests for, and set their html_directory props to the path of the directory with their site content, as in the following example:

 

Text Box: <?xml version="1.0"?>
<props_list>
	<props>
	   <classname>com.neokernel.httpd.HTTPFileServerAgent</classname>
	   <name>HTTPFileServerAgent</name>
	   <default_index>index.html</default_index>
	   <html_directory>./default_html/</html_directory>
	   <startup>true</startup>
	</props>
	<props>
	   <classname>com.neokernel.httpd.HTTPFileServerAgent</classname>
	   <name>HTTPFileServerAgent2</name>
	   <default_index>index.html</default_index>
	   <html_directory>./localhost_html/</html_directory>
	   <service_name>localhost/</service_name>
	   <startup>true</startup>
	</props>
</props_list>
</xml>

Here are examples of valid service_name settings:

http://www.server.org/homepage.agent
http://www.server.org:8080/homepage.agent
https://www.server.org/homepage.agent
www.newserver.org/homepage.agent
www.newserver.org:8080/homepage.agent
/homepage.agent

 

To review, when the web server gets a request, it tries to find an agent whose service_name prop matches the requested URL. If virtual hosts is active, the server first looks for an agent with the hostname that the client is using appended in the beginning. If no matching agents are found, the server tries to load the URL without a hostname.

When the domain is not included as part of an agent’s service_name prop, that agent will respond to requests that match its URL regardless of the hostname requested by the client.

For example, if an agent registers with the service_name of /homepage.agent, and the host is registered in the DNS as both www.server.org and www.newserver.org, then the agent will handle requests for both http://www.newserver.org/homepage.agent and http://www.server.org/homepage.agent.

However, if the service_name includes the server’s hostname, for example http://www.newserver.org/homepage.agent, the agent will respond to requests for http://www.newserver.org/homepage.agent, but not to requests for http://www.server.org/homepage.agent. Requests for the second URL will result in a 404 (file not found) error.

Props Supported by All Agents

The following props are supported by all agents. If no entry for a prop is specified in the neokernel_props.xml file, a default value for that prop is used. Agents that interact with other agents typically have a service_name property in addition to those listed here:

 

name

The agent’s display name; this will be used in agent output to identify messages from this agent. Defaults to be the same as the classname

startup

This boolean prop determines if this agent will be started by the server. The default value is true

 

id

The agent's id (a numeric value.) The kernel loads agents in numeric order according to their agent id. The default is for agents to use an id assigned by the kernel.

classname

The name of the object that contains this agent’s code.

 

hide_println

If this prop is set to true, all println() output for this agent is hidden. The default value is false

 

hide_debug

If this prop is set to true, all debug output for this agent is hidden. The default value is false

 

hide_warning

If this prop is set to true, all warning output for this agent is hidden. The default value is false

 

Table 3 – Props supported by all agents.

com.neokernel.httpd.WebServer

Multiple WebServer agents can run within a single Neokernel process, but each must be running on a unique port (as specified by it’s bind_port prop).

 

bind_port

This prop tells the web server what port to bind to and accept connections from.

 

bind_ip

This prop specifies the IP address that the server will bind to. To bind to every IP address on the host machine, set this prop to  0.0.0.0

               

virtual_hosts

 

Set this prop to true to enable support for virtual hosts.

max_connections

This prop determines how many simultaneous connections the web server will handle. Any connection made after this number of connection has been reached will hang until the next thread becomes available to handle it, or for the amount of time specified in thread_pool_timeout.

 

index_agent

This prop specifies the agent that handles requests for the server’s root or default directory (e.g. http://www.neokernel.com/). Typically this is set to an HTTPFileServerAgent which serves a default_index page.

 

log_file_dir

This prop defines the path to the directory where the server will output NCSA-Extended format http log files. By default this prop is set to ./logs

 

log_requests

If this prop is set to true, the WebServer will log http requests to sequentially numbered text files in the directory specified in log_file_dir.

 

mime_types_file

This prop contains the path to a file describing what mime types to use for specific file extensions; this file is also mentioned on page 5. By default this prop is set to ./mime_types

 

refuse_requests

This prop specifies a list of strings that will result in a request being refused if a client passes them in the request header. This can be used to block access based on the IP or “user-agent” description passed with the request. For example, the value

               

204.182.54.1,Googlebot,Windows ME
 

tells the server to refuse requests from the IP address of 204.182.54.1, the Google indexer bot, and anyone using Windows ME. By default this prop is not set.

 

socket_linger_time

The number of milliseconds the agent should wait after an http request is completed before closing the socket used to service that request. The default value is 2000

 

proxy_agent
 

If this prop is set, the WebServer will use it’s value as the service name to get a reference to the HTTPProxyAgent from the ServiceManager. The HTTPProxyAgent will be used proxy incoming requests for any of the URIs in the http.proxy file, and for http proxy traffic on the IP addresses and ports specified in the listeners prop of the HTTPProxyAgent. Set the value of this prop to http_proxy.agent or to the service_name of an HTTPProxyAgent running in your server if you have configured it to use a different service name. This prop is not set by default.

 

redirect_agent
 

If this prop is set, the HTTPRedirectAgent will be used to redirect requests for the URIs specified in the http.redirect file. Set the value of this prop to http_redirect.agent or to the service_name of an HTTPRedirectAgent running in your server. This prop is not set by default.

 

authentication_agent
 

If this prop is set, the HTTPAuthenticationAgent will be used to authenticate incoming requests. Set the value of this prop to http_authentication.agent or to the service_name of an HTTPAuthenticationAgent running in your server. This prop is not set by default.

 

Table 4 - com.neokernel.httpd.WebServer

com.neokernel.httpd.SecureWebServer

SecureWebServer supports secure communications using SSL. It supports the same props as WebServer, and adds support for the following:

 
server_certificate

 

This prop tells the server where to find a certificate for SSL communications.

 

If the certificate is a file on the disk, use the path to that file as the value of this prop. For instance:

 

c:\\neokernel\\localhost-cert.pfx

 

If the certificate is installed in one of the host machine’s certificate stores, use the syntax

 

store:[name of certificate store]

               

The value for [name of certificate store] will usually be MY meaning the group of certificates listed under the Personal tab in the Certificates window[7]. A typical setting for this prop when loading certificates from the local certificate store is:

 

store:MY

 

The server will use the first cert in the specified store that is appropriate for SSL server use. Use the following values to access the various certificate stores on windows platforms:

 

CA

Certification authority certificates.

MY

A certificate store holding "My" certificates.

ROOT

Root certificates.

SPC

Software publisher certificates.

 

The default value of this prop is localhost-cert.pfx, which is the name of the example certificate provided for testing SSL connectivity.

 

certificate_password

The password to use when accessing the SSL certificate. Note: The password for the example certificate provided in the file localhost-cert.pfx[8] is abcd.

 

 

The following props may or may not be necessary depending on the type of certificate you are using:

server_key_file

The private key file for the server certificate. By default this prop is not set because the example certificate

(localhost-cert.pfx) has a private key embedded in the certificate.

 

key_file_password

This is the password for accessing the .pvk file specified in the key_file prop. By default this prop is not set.

 

Table 5 - com.neokernel.httpd.SecureWebServer

com.neokernel.httpd.HTTPFileServerAgent

This agent serves html, ASP.NET, image, and other files from a specified directory. To serve different web sites from a single WebServer, start multiple instances of FileServerAgent[9] and give each a unique service_name prop matching the domain or hostname that it should handle requests for. The \Virtual Hosts example in the \demos directory shows how to do this.

Here are some examples of valid service_name entries in a virtual hosts configuration:

http://www.server.org/
http://www.server.org:8080/
https://www.server.org/
www.server.org/
www.server.org:8080/
/

 

If the requested filename ends with .aspx, the file will be passed to the ASP.NET Runtime and code contained in the file will be executed before the content is returned to the requestor. If the ASP.NET code references other assemblies or .dlls, copies of these must be in the same folder (or the \bin subdirectory of the folder) where the ASP.NET (.aspx) file is located.

 
html_directory
 

This prop specifies the directory containing the static files that will be served by this agent. By default, this prop is set to ./html

 

default_index

This prop specifies what (if any) file to serve when the URL requested by a client is a directory name. This prop is set to index.html by default, which means if a browser requests /public_html/my_stuff/, the server will look for the file at /public_html/my_stuff/index.html.

 

aspnet_config_file

The path to an XML file containing ASP.NET configuration and debugging information. Defaults to web.config.

preload_aspx_pages

A list describing the ASP.NET pages that should be pre-loaded when the agent starts. This is not required but it makes pages load faster the first time they are requested by the user. To pre-load ASP.NET pages the agent must know the file location and it's URL relative to the server root. The list of files is delimited by semi-colons and looks like:

 [WebPath1],[FilePath1];[WebPath2],[FilePath2]

 

…and so on, where the first item in each pair is the path to the file relative to the root of the web server (e.g. /aspapp/myfile.aspx) and the second is the path to the file on the hard disk (e.g. d:\htmldir\aspapp\myfile.aspx). This property is not set by default.

aspx_assemblies

An optional comma seperated list of assemblies referenced by ASP.Net pages. Assemblies appearing in this list will be copied to the \bin subdirectory of the folder where the ASP.Net page is located. The files will be re-copied and re-loaded if a newer version becomes available. Use the full path. Here is an example value for this property:

 

c:\app\foo.dll,c:\anotherapp\bar.dll

allow_directory_lists

By default this prop is set to no. If this prop is set to yes the server will dynamically construct an HTML document which lists the files in the requested directory (if it is a subdirectory of html_directory and there is no default_index file) and return it to the browser.

 

Table 6 - com.neokernel.httpd.HTTPFileServerAgent

com.neokernel.httpd.HTTPAuthenticationAgent

This agent handles HTTP authentication. A configuration file defines the realms[10] that require authentication and the username/password pairs to use when authenticating with each realm. HTTPAuthenticationAgent is used by the WebServer to handle authorization of password protected URIs.

The authentication file defines the realms and the list of username/password combinations that can be used to authenticate with each realm. A “realm” is the name of the protected item or website; this will be shown to the user when they are asked to authenticate. The authentication file is delimited by newline characters and must end with a newline. Each realm is declared with a PATH and the REALM name separated by spaces, followed by usernames and passwords on new lines, separated by a space. PATHs must begin with a slash and end with a slash.

The HOSTNAME field at the beginning of the file indicates to the HTTPAuthentication agent what hostname the realms should be mapped to. The default hostname is default, meaning the http.authentication file applies to all hostnames on the server machine.

Here is an example of an authentication file for a website that will ask for authentication if the user requests anything from the folders /PATH0 or /PATH2:

        HOSTNAME
        PATH0 REALM_NAME0
        username0 password0
        username1 password1
        username2 password2
        username3 password3
        PATH2 REALM_NAME0
        username0 password0
        username1 password1

             

The next example shows an authentication file with two realms, 'My realm' and 'Main Realm'. If any access is made to files or directories in /private, the username jonlin with the password mainpassword will be expected, except for accesses to /private/mine/, which is under the /private path but is its own realm and requires its own usernames and passwords. If default is used as the hostname then the authentication map will apply to all virtual hosts on this server.


 

Here is an example of an authentication map file that applies to every hostname:

        default
        /private/mine/ My realm
        john johnpassword
        santos halper
        /private/ Main Realm
        john mainpassword

             

service_name

The name this agent uses to register with the ServiceManager. The WebServer’s authentication_agent prop must be set to a matching value so that requests for URLs requiring authentication are handed off to this agent. The default value is http_authentication.agent

authentication_files
 

This prop holds the path to the authentication map file (or multiple files in a comma separated list) described on page 5. The default value is .\http.authentication

 

Table 7 - com.neokernel.httpd.HTTPAuthenticationAgent

 

com.neokernel.httpd.HTTPProxyAgent

This agent serves as a proxy for http and https traffic. It can provide complete proxy services to browsers and other clients connecting on the addresses and ports specified in the listeners property, and it can proxy the specific URLs listed in the http.proxy file while the WebServer handles other requests normally.

The http.proxy file lists full URLs or URIs to proxy and what server to get the data from (if it is running.) It consists of name/value pairs separated by the newline character. Lines beginning with the # character are ignored as comments. The value of each name/value pair must be a complete URL.

Here are some valid name/value pairs that might be used in the http.proxy file:

        http://myserver/proxy_me=http://proxy:1099
        http://myserver/proxy_me2=http://proxy1:9000
        http://myserver/proxy_me2=http://proxy2:9000
        http://myserver/proxy_me2=http://proxy3:9000

 

When a browser requests /proxy_me, the HTTPProxyAgent contacts the web server at proxy on port 1099 and proxies the request to that server. When a browser requests /proxy_me_too, the HTTPProxyAgent cycles through the 3 web servers indicated, so that the first time the URL is accessed, the connection is proxied to proxy1:9000. The second time, the request is proxied to proxy2:9000, the third request goes to proxy3:9000, the fourth request goes to proxy1:9000, and so on. Both the name and the value of each name/value pair are assumed to be literal, so they will only match the exact path/hostname of the http request.

The servers listed in the http.proxy file are periodically checked to ensure that they are up and responding. The HTTPProxyAgent will not proxy requests to servers in the http.proxy file that aren't responding.

HTTPProxyAgent also supports listeners, which operate independently of the WebServer to proxy traffic for browsers configured to use a proxy server. Any number of listeners can be started to provide proxy services on specific ports or IPs. Listeners are specified using the listeners prop of the HTTPProxyAgent.

 

service_name

The name this agent uses to register with the ServiceManager. The WebServer’s proxy_agent prop must be set to a matching value so that requests for proxied URLs are handed off to this agent. The default value is http_proxy.agent

 
proxy_file

 

This prop holds the path to the proxy file described on page 5. By default, this prop is set to ./http.proxy

 

check_interval

The HTTPProxyAgent has an internal check where it pings the web servers on the proxy list. If they are not responding, that web server will be removed from the proxy list temporarily. It will be added again once the server is responding. By default, this is set to 300000, which means every 300000 milliseconds the agent will check each proxy destination on its list.

 

listeners

This is a comma separated list of IP addresses with port numbers on which the agent will proxy ANY http or https request. This is used for proxying all requests as opposed to when only certain URLs are proxied. A typcial setting for this prop is 0.0.0.0:80,0.0.0.0:443, which means the agent will provide HTTP proxy services on all local IP addresses on port 80, and on all local IP addresses on port 443 (the default port for https traffic). Note that this setting will conflict with the default port that the WebServer runs on, so if you use proxy listeners on the same machine as a WebServer you’ll need to use different ports. By default this prop is not set.

log_requests

When this prop is set to true, the agent will log requests handled by proxy listeners. Requests routed through the WebServer are logged in the WebServer’s http logs

proxy_log_dir

The path to a directory where proxy log files will be written to. Defaults to .\proxy_logs

initial_wait_time

This prop specifies how long to wait after startup before starting to ping the proxy destinations. By default this prop is set to 60000, which means the agent will wait 60000 milliseconds before it starts checking the servers in the list.

 

Table 8 - com.neokernel.httpd.HTTPProxyAgent

 

com.neokernel.httpd.HTTPRedirectAgent

This agent is used by the WebServer to determine whether a web request should be redirected and to redirect requests that should be redirected.

If an HTTPRedirectAgent is running and the WebServer's redirect_agent prop is the same as the HTTPRedirectAgent's service_name, the agent will redirect requests for URLs listed in the http.redirect file. This file lists where to redirect to; URIs with multiple redirects listed in the file will be cycled between the listed redirects, providing a round-robin load distribution scheme.

The file format is name/value pairs delimited by newline characters; lines starting with # are ignored. Complete URLs must be used to specify redirected URLs and the redirect targets. Here is an example of a redirect file:

       http://myserver/redir1/file.htm=http://yahoo.com/
       http://myserver/redir2/=http://redirect1:9000/
       http://myserver/redir2/=http://redirect2:9000/
       http://myserver/redir2/=http://redirect3:9000/

 

There are 2 kinds of name/value pairs used in the http.redirect file. The first is a direct mapping in the format NAME=VALUE. This mapping tells the redirect agent to redirect PATH NAME to PATH VALUE.

A directly mapped NAME that contains a hostname must have a host in its VALUE. A direct mapping will not recurse subdirectories in a path and each path is treated as literal. Names can by mapped to multiple values if the values are separated by commas. The agent will cycle through each of the different paths given as the value.

The second kind of mapping maps only hosts to hosts, and passes the requested URL along with the redirected request for the mapped host to handle. This is an example of host-to-host mapping syntax:

        http://myhost.com>http://www.myhost.com

             

No path information is included in the syntax of this mapping, only the host names. Requests for myhost.com will be mapped to the host www.myhost.com. This mapping is especially useful when the WebServer is running virtual hosts, because multiple hostnames can all by mapped to a single host or URL.

Note: Cyclical references in the redirect mappings are not checked, if the redirect file has cyclical references, clients can be put into an infinite loop of redirects.

redirect_file

This prop determines the path to the redirect file described on page 5. By default, this prop is set to ./http.redirect

 

check_interval

The HTTPRedirectAgent checks the status of the web servers on the redirect list. If a server doesn’t respond, it will be removed from the redirect list temporarily. It will be added again once the HTTPRedirectAgent pings it and it is responding. By default, this value is set to 300000, which means every 300000 milliseconds the agent will check the redirect destinations on its list.

 

initial_wait_time

This prop tells the agent how long to wait before it starts checking the redirect destinations. In the case where you are redirecting to yourself, you must wait until the WebServer is fully started before the agent starts pinging it. By default this prop is set to 60000, which means the agent will wait 60000 milliseconds before it starts checking.

 

service_name

The name this agent uses to register with the ServiceManager. By default, this prop is set to http_redirect.agent

 

Table 9 - com.neokernel.httpd.HTTPRedirectAgent

com.neokernel.httpd.HTTPPutAgent

When this agent is loaded the server supports traditional HTTP PUT features, saving uploaded files to the directory specified in the html_directory prop. To run the HTTPPutAgent, the WebServer must have a prop called put_agent that matches the service_name that the HTTPPutAgent agent registered with. See the /FileUploadExample folders (in the /demos/Visual Basic Projects and /demos/Visual C# Projects) for an example of generating a file upload form. Not all browsers support this feature so provide an alternate means of file transfer.

service_name

The name this agent uses to register with the ServiceManager. By default, this prop is set to http_put.agent

 

html_directory

The path to the directory where received files will be stored. By default, this value is set to ./

 

make_directories

If this prop is set to true, the HTTPPutAgent will create new sub-directories under the server’s html_directory when a client uploads a file to a non-existent directory. By default this prop is set to false

 

Table 10 - com.neokernel.httpd.HTTPPutAgent

 

com.neokernel.httpd.LogViewerPage

This agent registers itself with the ServiceManager and generates web reports on the contents of server log files. It analyzes the files in the log_dir directory and uses a mapping file to obtain information about how these files should be displayed. The mapping file maps report names to text search patterns. When a browser accesses this agent, the agent lets the user choose from the reports specified in the map file using a popup menu. When the user submits a request for one of the reports, they are shown all lines in the log files that match the text search pattern for that report. The source code for this agent is included in the /demos directory. This agent will treat every file in the specified directory as a log file.

log_dir

This prop tells the LogViewerPage where to look for the log files.

 

log_map_file

This is the path to the log.maps file described on page 5. By default, this prop is set to ./log.maps

 

check_interval

All requests to view the actual lines of log files are processed in real time. This means that the log files are searched when a request for a report is received. However, the “hit counts” displayed on the “choose a report” page are recorded at intervals. This prop defines how often this agent updates these values in milliseconds.

 

service_name

This is the name that the agent will use as its URL.

 

is_logger_output

If this prop is set to true, the LogViewerPage will assume that the log files are generated by the Neokernel, resulting in improved formatting of multiple line log entries.

 

max_show_log_length

This is the maximum length of data (in bytes) that will be shown when a request to view log output is received. The default value is 50000

 

Table 11 - com.neokernel.httpd.LogViewerPage

com.neokernel.io.FileReporter

This agent captures all output that would normally appear in the console window and writes it to a file. It supports the following Props:

log_file_prefix

The prefix to use when naming log files. Default value is log_

 

logs_per_file

The maximum number of log entries per file. When logs_per_file has been reached, a new log file is created to hold additional data. Default value is 10000

 

log_dir

The path where log files will be output to. Default value is ./logs

 

Table 12 - com.neokernel.io.FileReporter

 

Note: The com.neokernel.io.ServiceReporter agent is used as the default logger when the Neokernel is running as a windows service. This agent supports the same properties as the FileReporter, but it also logs errors to the Windows Event Log. If the Neokernel is running as a service and you want to make other events appear in the Event Log, use the printEventLogEntry() and debugEventLogEntry() methods of com.neokernel.io.ServiceReporter


Part Two: Developing Dynamic Web Applications with the Neokernel

Deploying Custom Request Agents

The Neokernel is designed to be extended with custom Agent and RequestAgent classes that you develop. To develop and deploy a custom RequestAgent:

1. Create a class in Visual Basic or C# that extends com.neokernel.ak.RequestAgent and implements the method handleRequest(AgentRequest request).

 

2. Compile your class and put the new .dll in the same directory as neokernel.exe:

compilinghelloworld_005

Figure 2 - Compiling the HelloWorldAgent.


 

 

3. Optionally, add Props for your agent to the neokernel_props.xml file:

a. Create a prop called service_name that will be your agent’s URL, for instance /helloworld.agent.[11]

b. Create a prop called classname set to the name of your class.[12]

 

4. Start the neokernel.exe application and use your browser to navigate to the agent’s URL as specified in its service_name. The agent’s URL will be in the format:

 
http://<server’s hostname><agent’s service_name>
 

Templates for a variety of custom agents and configurations can be found in the /demos folder. The following C# code snippet shows a complete custom agent:

Text Box: using System;
using com.neokernel.nk;

public class SimplePage : RequestAgent
{
 public override void initProps()
 {
	setDefault("service_name", "/simple.agent");

	setDefault("body", "This is output from the SimplePage agent!");
 }

 public override void handleRequest(HTTPAgentRequest request)
 {
	String body = getString("body");

	request.println( body );
 }
}

If a browser requests the URL http://localhost/simple.agent from a server that has started the SimpleAgent from the above example, the browser will display the text

This is output from the SimplePage agent!

               

Text Box: Imports com.neokernel.nk

Public Class SimpleVBPage
  Inherits RequestAgent

  Overrides Sub initProps()
    setDefault("service_name", "/simple.agent")
    setDefault("body", "This is output from the SimplePage agent!")
  End Sub

  Overrides Sub handleRequest(ByVal Request As AgentRequest)
    Dim title, body As String
    body = getString("body")
    Request.println(body)
  End Sub

End Class

Here is the same agent implemented using Visual Basic:

 

Loading New Agent Components

To make a new agent available from your server, put the agent’s assembly in the same folder as the server executable and re-start the server. Agents found in the startup directory are loaded automatically using their default properties unless an agent of the same type has been defined in the neokernel_props.xml file, in which case the properties in the neokernel_props.xml file are used. Agents are typically compiled into .dll or .exe files (called assemblies.) The assembly containing the agent to be loaded must be in the same directory as the neokernel.exe, or a subdirectory of the directory that the neokernel.exe executable was launched from.

How It Works – The Complete Picture

Lets review how everything works together:

1. When a request is received, the Neokernel looks up the ServiceManager to look up the agent that should handle an incoming request.

2. It creates an HTTPRequestObject which it hands-off to the chosen agent by passing it as an argument to that agent’s handleRequest() method.


3. The agent generates a response in the course of it’s handleRequest() method.

 

 

 

 

 

 

 

 

Figure 3 – Neokernel task flow including the ServiceManager.

 

The HTTPAgentRequest passed as an argument when handleRequest() is called serves two purposes: it stores useful data about the incoming request, and it is used to send the response to the client. To write data in response to a request, call the print() or println() methods of HTTPAgentRequest.

The server automatically adds the correct HTTP header and response codes to data sent to the client using the print() and println() methods. A RequestAgent may override this feature if the first text sent in response to a request is HTTP/[13]. If anything besides HTTP/ is printed first, HTTP headers are automatically generated and pre-pended. This ensures that browsers will display the response.

Working with Agent Props

The SimplePage example illustrated how writing Neokernel agents isn't that different from writing other programs in the .NET environment. What is it about agents that make them different? One key difference between agents and other programs is that they maintain an identity defined by agent properties (to review, it is the convention in Neokernel programming that agent properties are called props.)

Before an agent can start using its identity, it initializes its props using the initProps() method. The following code shows initProps() in action:

Text Box: using System;
using com.neokernel.nk;

public class SimplePage : RequestAgent
{
 public override void initProps()
 {
	setDefault("color", "red");
	setDefault("greeting", "Hello, world!");
	setDefault("language", "English");
	setDefault("service_name", "/simple.agent");
	setDefault("body", "This is output from the SimplePage agent!");
 }

 public override void handleRequest(HTTPAgentRequest request)
 {
	String body = getString("body");
  
	request.println("I like to speak in " + getString("language"));
	request.println("My favorite color is " + getString("color"));
	request.println( body );
 }
}

 

Agents have built-in methods for managi