Nex Home

Nex Internal Protocol Specification

Version A1.
(c) 2004, Andrew Sklyarevsky.

About
Download

NIP Specification
LDP Developer Instructions

1. Introduction

Nex Internal Protocol (NIP) - modern, somewhere revolution technology, that provides to us a way to develop web-styled applications, that will run under Nex. The Nex.Standard LDPs provides to user a new favorites system, search system, Nex options page and history page. This pages works throw HTUI (Hypertext User Interface), that more user-friendly and reliable, than old-fashioned GUI applications.

This protocol provides a dialog between Nex and different local dynamic pages under the terms of this document. Current version of the Nex Internal Protocol: A1.

Because of thread safety, you can open multiple LDP windows in Nex, and if one of they become unstable, you will receive just an information about the error (unhandled exception) occurred and can continue your work. You also can open multiple instances of Nex itself.

1.1. Terminology

Word Description
LDP Local Dynamic Page, the generated by some method in some class in some assembly page. Main aim of the NIP - dialog between LDP and Nex.
LSP Local Static Page - the static page, located somewhere on your hard disk. NIP can not modify that page and provides redirection to it only.
Nip.Config The value of !DOCTYPE element in the XML configuration files, where NIP stores information about domain/category/page structure.

2. Nip.Config documents structure

A base to every technology is its data storage system. To store NIP hierarchical structure (domain/category/page), Nex uses XML format. Files, that NIP uses, always have 'Nip.Config' value for '!DOCTYPE' element. There are 5 document types, that provides NIP functionality. As an examples, we will use Nex standard Nip.Config files.

2.1. Global configuration file structure

First (this structure have 'nip.global.config.xml' file) looks like:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE Nip.Config>
<config>
	<properties>
		<!-- Declaration -->
		<property name="Declaration.Version" value="0,01" />
		<property name="Declaration.Class" value= "Nip"
	/>
	</properties>	
		<nip> 
		<!-- Domains--> 
		<domain  name="i" 
			link="nip.i-domain.config.xml" 
			filepath="i\" />
	</nip>
</config>

Note: in current version of Nex Web Browser the Declaration.Version and the Declaration.Class properties must always have '0,01' ('A1') and 'Nip' values responsively. 

This file says to the Nex, that there are an 'i' domain (name attribute), which configuration saved in the 'nip.i-domain.config.xml' file (link attribute), and that the path to 'i' domain items (other configuration files, LDPs, etc.) is 'i\' (relatively to the Nex working directory) - filepath attribute. The files of this type declares only domains, but no LDPs or LSPs.

2.2. First-level domain configuration file structure

'nip.i-domain.config.xml' file should declare it's own subdomains only, but no LDPs or LSPs, because the first type must be used to declare first-level domains only , and the first-level domains can not have a pages. But, if the first-level domains declared by a valid link to its configuration file, second-level (third-level, etc.) domains can be delcared using the file-mask, like this implemented in this example (our 'nip.i-domain.config.xml'):

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE Nip.Config>
<config>
	<properties>
		<!-- Declaration -->
		<property name="Declaration.Version" value="0,01" />
		<property name="Declaration.Class" value="Nip" />
	</properties>
	<nip>
		<!-- Domainmask -->
		<domainmask class="NipDomain" 
			mask="nip.{sub}-domain.config.xml" />
	</nip>
</config>

If in the previous example general element was 'domain' (with name, link  and filepath attributes), in this example main element is a 'domainmask'. This file will requests Nex to find files in the 'i\' directory (this declared in the previous example), which name equals to 'nip.{sub}-domain.config.xml', where '{sub}' is a name of the second-level domain (this is not required, '{sub}' can be different with the domain name, because in one file of this type can be declared two or more domains).

2.3. Subdomain configuration file structure

The third type of the NIP configuration files is a subdomain (second-level domain, third-level domain, etc.) configuration. Let see the example:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE Nip.Config>
<config>
	<properties>
		<!-- Declaration -->
		<property name="Declaration.Version" value="0,01" />
		<property name="Declaration.Class" value="Nip" />
	</properties>
	<nip>
		<!-- Root subdomain needed -->
		<domain name="nex" filepath="nex\">
			<category name="root">
				<pagemask class="NipLDP" 
				mask="nip.{page}.ldp-info.xml" />
				<pagemask class="NipLSP" 
				mask="nip.{page}.lsp-info.xml" />
			</category>
			<category name="root/help">
				<pagemask class="NipLDP" 
				mask="nip.{page}.help-ldp.xml" />
				<pagemask class="NipLSP" 
				mask="nip.{page}.help-lsp.xml" />
			</category>
			<domainmask class="NipDomain" 
			mask="nip.{sub}-nex-domain.config.xml" />
		</domain>
	</nip>
</config>

This file declares the 'nex' subdomain (name attribute), and that all configuration, linked to this subdomain located in 'nex\' directory (filepath attribute). If you name this file as 'nip.nex-domain.config.xml' and save in the 'i\' directory (relatively to previous example location), than 'nex' domain will be accessible by the "nip:/nex.i/" address. If another first-level domain configuration file will link to this file, than no error will be occurred, and all of declarations, located in this file will be available under two or more addresses.

The 'category' element requests Nex to create new category object (with name attribute value as category name), and locate pages, declared inside the 'category' element in this category object (Nex.Nip.NipCategory type). There are only two possible types of elements inside the 'category' element: 'pagemask' element with 'NipLDP' or 'NipLSPclass attribute value.

Note: Nex requires the 'root' category, because Nip.NipCategory object can not work properly without correct name. If you want create a category named 'root', you must set 'root/root' value to name attribute of 'category' element.

Note: 'category' element can contain more than two 'pagemask' elements, but class attribute value of this elements can be 'NipLDP' or 'NipLSP' only.

Note: NipLDP and NipLSP page masks must be different.

The 'pagemask' element requests Nex to find all files, which have 'nip.{page}.ldp-info.xml' name for LDP's and 'nip.{page}.lsp-info.xml' name for LSP's. Nex will generate pages objects (Nex.Nip.NipPage type), that bases on LDP/LSP configuration files found.

'domainmask' provides subdomain functionality as this referenced in 2.2.

2.4. LDP configuration file structure

LDP configuration file provides declarations of end-user pages, which forming process is dynamic, based on Nex Internal Protocol exchange rules. The following example is a 'nip.standard.ldp-info.xml' file, located in '...\nip\i\nex' directory.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE Nip.Config>
<config>
	<properties>
		<!-- Declaration -->
		<property name="Declaration.Version" value="0,01" />
		<property name="Declaration.Class" value="Nip" />
	</properties>
	<nip>
		<page name="begin" class="NipLDP" 
			assembly="Nexldp.dll"
			assemblyClass="NexLDP.Standard" 
			assemblyMethod="Begin" />
		<page name="options" class="NipLDP" 
			assembly="Nexldp.dll" 
			assemblyClass="NexLDP.Standard" 
			assemblyMethod="Options" />	
		<page name="favs" class="NipLDP" 
			assembly="Nexldp.dll" 
			assemblyClass="NexLDP.Standard" 
			assemblyMethod="Favorites" 
			sidebar-style="small" />
		<page name="history" class="NipLDP" 
			assembly="executing" 
			assemblyMethod="GenerateHistoryJournalLDP"
			assemblyClass="Nex.Config.History" 
			sidebar-style="small" />
	</nip>
</config>

The 'page' element has 6 possible attributes:

  1. name - name of this LDP. This name will be used in address of LDP, for example, if this attribute value is 'begin', than address of this page will be: nip:/.../.../begin.
  2. class - this attribute value must be equal to 'NipLDP'.
  3. assembly - the path to the assembly or a simple filename, if assembly located in the same directory, as this configuration file. Nex will open this assembly when user will require a page, that must be formed by a method, located in some of classes in this assembly.
  4. assemblyClass - the qualified name (include namespaces) of the class, where required method is located.
  5. assemblyMethod - method of the assembly, that forms required LDP.
  6. sidebar-style - this attribute is not required, but if it indicated, Nex will make this page available to use throw sidebar. When user will request this page in sidebar, Nex will send to the page the 'style' property, set to the value of 'sidebar-style' attribute.

See chapter  3 to know more about Nex and LDP dialog.

2.5. LSP configuration file structure

LSP configuration file provides declarations of aliases to static pages, located on exact computer. Let see the 'nip.welcome.lsp-info.xml' file to obtain an example.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE Nip.Config>
<config>
	<properties>
		<!-- Declaration -->
		<property name="Declaration.Version" value="0,01" />
		<property name="Declaration.Class" value="Nip" />
	</properties>
	<nip>
		<page name="welcome" class="NipLSP"
			link="nex.i.welcome.html" />
	</nip>
</config>

In this type of Nip.Config configuration files 'page' element have different syntax, than in LDP configuration file and has three attributes:

  1. name - name of this LSP. This name will be used in address of LSP, for example, if this attribute value is 'begin', address of this page will be: nip:/.../.../begin.
  2. class - this attribute value must be equal to 'NipLSP'.
  3. link - address of the file to redirect to.

Note: user will always see the NIP virtual address of this LSP and can not see the real address of this file.

3. Nex Internal Protocol

To form LDP, Nex must use some algorithm to have a dialog between itself and another, unknown assembly. For example, this assembly named Abc . Nex just load specified in Nip.Config configuration files information. But this assemblies not mutually referenced and Nex don't know, what types declared in the Abc, that also don't know what is the Nex and what kind of classes implemented there. So, Abc and Nex must use independent .Net type to speak. The best .Net type to use for this means is a System.String ('string' in C#).

At this moment, NIP provides one way data exchange. A working schema of NIP is:

  1. User requires a resource.
  2. Nex searches NIP hierarchy for requested page object (just an Nex.Nip.NipPage object with information about LDP).
  3. Another thread, named nipThread starts. The FormLDP method of NipPage object used.
  4. FormLDP method generates request string, based on received  get and post properties.
  5. FormLDP method loads the requested assembly and calls requested method inside it.
  6. Extern method generates response string, based on request string and another data, about which we don't know anything. It can use files, network resources, databases, etc.. FormLDP method waits response string. Nex continue it work, because forming LDP process works in another, parallel thread.
  7. Extern method returns a value. This string value is a NIP response. FormLDP method analyzes this string, if some headers in response are important, than it works with they.
  8. FormLDP method writes available only for current user UTF-8 encoded (if response has text type) temporary file and returns address of this temporary file to the Nex.
  9. nipThread stops.
  10. Nex navigate to this temporary file current Web Browser control and it showed to user.

3.1. Hello world! LDP

For example, we have nip:/hello.i/world LDP, which forming process works in the HelloWorld.dll assembly, HelloWorld namespace, Hello class and World method.

// C# example: HelloWorld LDP
namespace HelloWorld
{
	public class Hello
	{
		public static string World(string request)
		{
			return "Response-Type: NipLDP" +
				"\r\nNip-Version: 0,01" +
				"\r\nContent-Type: html" +
				"\r\n\r\n" +
				"<html><body>" +
				"<p>Hello World!</p>" +
				"</body></html>";
		}
	}
}

If user requests this page, he will see the simple 'Hello World!' message. This page is not actually dynamic, because the result of this page will always equal to "<html><body><p>Hello World!</p></body></html>" string. But, every time, when user requests this page, it will be generated by this method.

As the first action, this method should analyze the Nex request string.

3.2. NIP request and response structure

NIP request and response has following format:

Property-Name: property value
Another-Property-Name: another property value
...: ...

Nex.Config.PropertyList class provides a FromNipResponse method, that converts a request/response string to PropertyList object. This method does:

  1. Split the request/response string on the array of the lines.
  2. Adds new Property to the PropertyList, set Property.Name property to string before ':' symbol, and Property.Value property to string after ':' symbol for each line in lines array.
  3. Returns generated PropertyList.

NIP request and response is always encoded in Unicode, this allows to send and receive information on different languages.

3.2.1. PropertyList object System.String type equivalent format

PropertyList class is sizable array of Property objects. Property object have Name and Value properties. To convert PropertyList to string, you can use overridden ToString() method, which converts this list to string using following format:

property name="property value",another property name= "another property value",%is %sl="%slproperty value in quotes%sl, ="

There are some special symbols used and all of they have an alternative to use in property name or value.

Symbol Alternative Applies to
= %is property name
" %sl property name and value
, %zt property name
% %% property name and value

Other symbols, that not used as special can be used without any kind of replacing to alternatives. Property names and values can contain spaces, dots, non-ASCII symbols, etc.. If this string properly formed, PropertyList.Parse method can properly convert it to the PropertyList object.

This format used in NIP to insert in request string property lists, as a property of request itself. 'Get', 'Post' and 'Language-Set' properties of NIP request uses this format.

3.2.2. NIP request

Before call a method, that generates LDP, Nex forms a request string. Request have following format:

Request-Type: NipLDP
Request-Address: nip:/hello.i/world
Nip-Version: 0,01
Nip-Location: C:\Program Files\Nex\nip\ 
Get: style="sidebar"
Post: View.Language="English",...other properties...
Language-Set: Text.Message="Hello, world!"
Languages: English,Russian

Nex request always contains all of this attributes:

Property name Value description
Request-Type This property always equal to 'NipLDP' in this version of Nex.
Request-Address The address of the requested resource. This property is required, because calling method don't know, what page is required to generate.
Nip-Version The current NIP version.
Nip-Location Path to directory, where NIP files located.
Get Get properties, that user can see, and, that may be entered by user. Format of this property value is equal to Nex.Config.PropertyList object string equivalent.
Post Post properties have a  PropertyList object string equivalent format. The value of this property composed from Nex.Config.Storage.CurrentUserConfig.Properties.ToString value and posted by user properties.
Language-Set Has a PropertyList.ToString() method format. Nex searches current language set for properties with LDP address inside the name ('Text.nip:/hello.i/world.Message') and writes this records in this property of NIP request.
Languages List of the currently available languages.

3.2.2.1. NIP request 'Post' property value

If LDP have a form inside, than, when user clicks submit button, entered by user form data will be saved in the  Post property of NIP request. But, whenever user enters data in the form, or LDP opened at first time, Post property always contain Nex current user configuration properties.

Property Name Value description
Declaration.Class & Declaration.Version This properties equals to 'MachineUser' and '0,01' (A1) in this version of Nex.
View.Language Nex user interface language.
View.ToolBarShow Boolean, indicates, that toolbar Visible property is 'True' or 'False'.
View.ToolBarStyle ToolBarAppearance type, indicates Nex toolbar style. Can be 'Flat' or 'Normal'.
View.StatusShow Bollean, 'True', if Nex status line visible, else 'False'.
View.AutohidePanels Boolean, if 'True', Nex will automatically hide panels, when they unused.
Web.HomePage Page, that Nex will open at start.

For example:

...
Post: text="some text entered by user",
	View.Language="Russian",View.ToolBarShow="True",
	View.ToolBarStyle="Flat",View.StatusShow="True",
	View.AutohidePanels="True",
	Web.HomePage="http://www.google.com/"
...

Note: Nex receives posted by user data from Microsoft Web Browser ActiveX control, when BeforeNavigate2 event occurs. As the event argument, Web Browser control sends to Nex postedData object. If user enters some data to the form, this object will be System.Byte[] array. Nex converts this array to string, but this string URL-encoded, and Nex tries URL-decoding by HttpUtility.UrlDecode method, so in the Post property of NIP request all of the properties already decoded, but there are no 100% guaranty, that user-entered properties decoded properly.

3.2.2.2. NIP request 'Get' and 'Request-Address' properties values

For example, user enters 'nip:/hello.i/world,property="value"' address to the Nex. Nex will find 'nip:/hello.i/world' LDP and request to form it, sending the 'property="value"' string as getProperties argument of FormLDP method. So, LDP will receive following properties in the NIP request:

...
Request-Address: nip:/hello.i/world
...
Get: property="value"
...

Note: NIP doesn't support old-fashioned URL-encoded get properties. Do not use 'get' as a value for 'method' attribute of the 'form' HTML element.

Note: if you want to create a hyperlink to NIP resource, that have get properties, you must replace all quotes in this address to '&quote;' and 'a' tag must have following format:

<a href="nip:/required domain.zone/required page,property=
&quote;value&quote;">Click here</a>

3.2.3. LDP response

After analyze of the NIP request, LDP should generate response. This response should have following format:

Response-Type: NipLDP
Nip-Version: 0,01
Content-Type: html

Generated for user HTML text.

Generated by LDP result and response string should always be splited by one empty line, this protects Nex from parsing HTML code as a response properties. Response string can be empty, but it is highly recommended to list 3 basic properties (Response-Type, Nip-Version and Content-Type) to avoid incorrect parsing of LDP result.

The response string have a list of properties, that listed in the following table.

Property name Value description
Response-Type This property should always be equal to 'NipLDP' in this version of Nex.
Nip-Version Nex will check used by LDP version of NIP by this property, and if it will be different with Nex version, Nex will inform user about possible errors.
Content-Type Before show LDP to user, Nex saves a temporary file, that have equal to value of this property extension. Nex uses 'html' as default value for this property.
Nex-Change-Configuration If this property specified, Nex will change current user configuration responsively to value of this property.
Nex-Navigate2 You can use this property to redirect user from this LDP to other page.
Nex-Current-Window-Navigate2 If this property specified, current WebBrowserForm window will navigate to specified as value of this property address. This is useful for sidebar-styled pages.
Nex-New-Window If specified, Nex will create new window, navigated to value of this property.
Nex-Activate-Window If specified, Nex will find a window, that shows a page with address, that equals to value of this property and activate it.
Nex-Exit Value of this property is not important, but if it indicated, Nex will ask user to quit.

Note: if you set 'Nex-Navigate2' property (or 'Nex-Current-Window-Navigate2', if current window shows your LDP), Nex will abort analyzing of other properties and will navigate window, that shows your LDP to specified address. So, put it last, if this possible.

See also Instructions for LDP Developer.

SourceForge.net Logo