Nex Home |
Nex Internal Protocol SpecificationVersion A1. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1. IntroductionNex 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
2. Nip.Config documents structureA 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 structureFirst (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 structureThe 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 'NipLSP' class 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 structureLDP 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:
See chapter 3 to know more about Nex and LDP dialog. 2.5. LSP configuration file structureLSP 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:
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 ProtocolTo 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:
3.1. Hello world! LDPFor 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 structureNIP 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:
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 formatPropertyList 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.
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 requestBefore 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:
3.2.2.1. NIP request 'Post' property valueIf 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.
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 valuesFor 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 '"e;' and 'a' tag must have following format: <a href="nip:/required domain.zone/required page,property= "e;value"e;">Click here</a> 3.2.3. LDP responseAfter 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.
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. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||