The Pliant HTTP server is designed mainly for serving dynamic pages, but it can also be used as a classical HTTP server. It's key difference with other HTTP servers is that it introduces a new text file format, called .page. The .page file format can be learned in very few time, because it's not more complicated to write .page files than to write HTML pages using a text editor, but it scales incredibly better because .page files are true Pliant programs, so adding dynamic features is easy, is done using the very consistent Pliant syntax, and you get all Pliant language power (dynamic compiling, meta programming).
The performances of the Pliant HTTP server as a static pages server are probably not very high, and it's not a main goal to increase this because focusing on static pages only servers is stupid: most sites are network bandwild bounded, so the only interesting goals are getting more flexibility and reasonable security. However, should your site be processor speed bounded, it's probably not due to static pages servicing but due to true dynamic pages servicing. Now, if you really are a very special site that has so much bandwild that you get processor speed bounded, the best to do is probably to run two HTTP servers in a Linux box: the Linux kernel HTTP server will fast service the most frequently accessed static pages, and the Pliant HTTP server will give you the greatest flexibility on dynamic pages. Another even more powerfull alternative might be to use TUX (developped by the clever Ingo Molnar) as the kernel HTTP server.If you need such solutions, please keep in touch we me so that I can provide you advises on how to configure your server, and add improvements in order to increase Pliant HTTP server scalability based on real big sites experiments rather than abstract benchmark numbers.
pliant module /pliant/protocol/http/server.pli command 'http_server configure'
pliant module /pliant/protocol/http/server.pli command 'http_server port 8080 configure'
Important: If you specifyed 'configure' option when starting the HTTP server, then, in your browser, you have to connect to the server using http://localhost/ or http://localhost:8080/ but not any other server name such as the real name of your computer since the access would be rejected unless you HTTP server is already fully configured.
Now, these are all options you may select when starting the HTTP server: pliant module /pliant/protocol/http/server.pli command 'http_server configure simulate a_string name a_string port an_integer secured secured_port an_integer channel an_array_of_strings protocol_level a_string send_software_release_number a_boolean maximal_form_length an_integer log a_string'
If you want the HTTP server to start faster, you can use Pliant precompiling capabilities. So, you'll simply enter something like:
pliant 'precompile /binary/http.dump module /pliant/protocol/http/server.pli module /pliant/protocol/http/style/default.style' module /pliant/protocol/http/server.pli command http_server
Another solution for configuring Pliant HTTP server both on a server and on a client computer is to configure everything locally on the server computer, then copy site.pdb , user.pdb and user_secret.pdb on the client, and finally remove user_secret.pdb on the server computer (also removing is recommended, not necessary). So, on the server you end with: site.pdb site_secret.pdb user.pdb and on the client, you end with: site.pdb user.pdb user_secret.pdb If you do things the other way round (configure everything on the client), then copy to the server, then you should also not use the network to copy the files from the client to the server since a network sniffer could pick site_secret.pdb content on the fly, so it's not recommended.
When the requested page does not point to a .page or static file, the Pliant HTTP server will look for a virtual tree. As an example, if you request /abc/def/ghi/jkl.html and there is no /abc/def/ghi/jkl.html or /abc/def/ghi/jkl.page file, then the server will successively try to execute: /abc/def/ghi/virtual_tree.page /abc/def/virtual_tree.page /abc/virtual_tree.page /virtual_tree.page If one such page exists, while it's executed, the 'virtual_path' variable is set with the subpath that have been removed to find the virtual page.
You can find an example in virtual_tree.page and virtual_tree_PUT.page that implement Pliant files and data browser.
If the clients sends a PUT HTTP request, the same mechanism is applyed, but the virtual page name must be virtual_tree_PUT.page and while the virtual page is executed, the 'http_request:put_file' variable is the name of the file that has been sent.
If the clients sends a DELETE HTTP request, the same mechanism is applyed, but the virtual page name must be virtual_tree_DELETE.page
This is a sample style sheet that you could call sample.style :
module "/pliant/protocol/http/server.pli" module "/pliant/protocol/http/style/default.style" method p highlight msg arg_rw HtmlPage p ; arg Str msg strong_definition p font color (color hsl 60 100 50) p small p text msg export '. highlight'
Then you want to apply the new style sheet to an existing .page file, you just include the module:
module "sample.style" text "This is the text " ; highlight "with it's highlighted part"
So, the final result is:
Instead of:
This is the text with it's highlighted part
This sample is available in /pliant/protocol/http/style/ directory.
The Pliant HTTP server uses the file extension to decide how to handle it. The extensions are recorded using 3 functions: 'declare_mime_type' just specify the MIME type to associate to the file when answering a HTTP request. 'declare_mime_static_filter' provides a function that will translate the file on the fly at run time. 'declare_mime_dynamic_filter' provides a function that will translate the file to a Pliant program at compile time. You can find sample filters in filters.pli
Pliant HTTP server maintains the set of dynamic pages in a dictionary called 'dynamic_pages' Each page is convered from a .page source file (by the 'compile_dynamic_page' method) to a Pliant function that will be stored in the dictionary. This is done using a very classical Pliant mechanism: add a small header on top of the .page source code, then compile it using the standard 'compile_text' Pliant function. When a dynamic page is called, the function is retreved from the dictionary, then checked for consitency (if the source code file has changed, then it will be automatically recompiled) and finally executed.
What's stronger in this system is the subpages notion. A subpage is what will be executed when you click on a button. The subpage is also recorded in the dictionary when the main one is, but it's a more sophisticated thing: it also is a function that will be executed, but this function has an environment parameter, which is a Pliant type that contains one field for each local variables that is expected to be passed from the main page to the subpage.When the function is executed in 'send_dynamic_file' method, the environement is scanned (the HTTP form, and the URL options) for local variables values, and these will be checked against the server signature (in order to protect against the client changing them), then copyed in the instance of the subpage function context data type.
In simple words, if you write this in a .page:
var Int i := 5 button "press me" text "the value of i was "+string:i
Of course, there is something magic here since the code handling dynamic page is so small, and it's the 'freeze' method defined in freeze.pli module that is responsible for deciding which variables needs to be copyed, and compile the subpart of the function as a new function that will get the variables value from the enviroment structure rather than allocating them on the stack, but it's not at all something specific to the HTTP server. As an example, it's also used by 'thread' control.