<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">

<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<style>
<!--
 /* Font Definitions */
 @font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";
        color:black;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";
        color:black;}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:"Consolas","serif";
        color:black;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page Section1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.Section1
        {page:Section1;}
 /* List Definitions */
 @list l0
        {mso-list-id:250087295;
        mso-list-template-ids:-1385927126;}
@list l0:level1
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:36.0pt;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        mso-ansi-font-size:10.0pt;
        font-family:Symbol;}
@list l0:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:72.0pt;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        mso-ansi-font-size:10.0pt;
        font-family:"Courier New";
        mso-bidi-font-family:"Times New Roman";}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
-->
</style>
<!--[if gte mso 9]><xml>
 <o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
 <o:shapelayout v:ext="edit">
  <o:idmap v:ext="edit" data="1" />
 </o:shapelayout></xml><![endif]-->
</head>

<body bgcolor=white lang=EN-AU link=blue vlink=purple>

<div class=Section1>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Looks good!<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p> </o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>+1<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p> </o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Adam<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p> </o:p></span></p>

<div>

<div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'>

<p class=MsoNormal><b><span lang=EN-US style='font-size:10.0pt;font-family:
"Tahoma","sans-serif";color:windowtext'>From:</span></b><span lang=EN-US
style='font-size:10.0pt;font-family:"Tahoma","sans-serif";color:windowtext'>
opensim-dev-bounces@lists.berlios.de
[mailto:opensim-dev-bounces@lists.berlios.de] <b>On Behalf Of </b>Dr Scofield<br>
<b>Sent:</b> Wednesday, 28 May 2008 2:07 AM<br>
<b>To:</b> opensim-dev@lists.berlios.de<br>
<b>Subject:</b> [Opensim-dev] HttpServer overview & RFC<o:p></o:p></span></p>

</div>

</div>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>hi all, another request for comments :-)<br>
<br>
i've been chewing on HttpServer and how to use it instead of the .NET
HttpListener stuff. here's first a short overview of HttpServer and what it
offers (keyword is "short", for more details have a look at opensim-libs/HttpServer),
then some thoughts on how we could make use of it.<br>
<br>
HttpServer basically offers the following ways of processing HTTP requests:<br>
<br>
* HttpListener() <br>
* HttpModule<br>
* Controllers<br>
<br>
== HttpListener ==<br>
<br>
HttpListener (not the .NET one!) basically works like this:<o:p></o:p></p>

<p class=MsoNormal>HttpListener listener;<br>
listener = new HttpListener(IPAddress.Any, 80);<br>
listener.RequestHandler += OnRequest;<br>
listener.Start(5);<o:p></o:p></p>

<p class=MsoNormal>with OnRequest like this:<o:p></o:p></p>

<p class=MsoNormal>void OnRequest(HttpClientContext client, HttpRequest
request)<br>
{<br>
    ...<br>
    client.Respond(...);<br>
}<o:p></o:p></p>

<p class=MsoNormal>to support HTTPS, all we need to do is load an X509
certificate and pass that in to the HttpListener constructor.<br>
<br>
== HttpModule ==<br>
<br>
HttpModule basically allows us to register an HttpModule derived object with an
HttpServer object (which internally uses HttpListener). Each registered module
gets invoked to handle an incoming request (similar to the handler idea alan
webb brainstormed about a couple of days ago) and can signal back whether it
has handled the request.<br>
<br>
== Controller ==<br>
<br>
Controller finally is kind of a pre-canned REST handler making use of the first
three parts of an URL (slash is separator) as "addressing"<o:p></o:p></p>

<p class=MsoNormal><a href="http://localhost/user/view/1">http://localhost/user/view/1</a>   
<br>
<br>
<br>
<o:p></o:p></p>

<p class=MsoNormal><span style='font-size:10.0pt'>(example from <a
href="http://www.codeplex.com/webserver/Wiki/View.aspx?title=Part%20five%20-%20Using%20controllers&referringTitle=Home">http://www.codeplex.com/webserver/Wiki/View.aspx?title=Part%20five%20-%20Using%20controllers&referringTitle=Home</a>)<br>
<br>
</span>would address the controller module User (or UserController) and invoke
the method View() with the value "1".<br>
<br>
<br>
== Authentication ==<br>
<br>
Authentication is via Authentication modules as well as via callbacks where
required (for example for DigestAuthentication the callback occurs to get the
password).<br>
<br>
<br>
== making use of HttpServer ==<br>
<br>
what i'd actually like to implement (either as an HttpModule or as an
HttpListener handler) is an event--event handler scheme:<o:p></o:p></p>

<ul type=disc>
 <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
     mso-list:l0 level1 lfo1'>incoming HTTP request is pushed as an
     OSHttpRequest object into an HTTP request queue.<o:p></o:p></li>
 <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
     mso-list:l0 level1 lfo1'>each OSHttpRequest encapsulates <o:p></o:p></li>
 <ul type=circle>
  <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:
      auto;mso-list:l0 level2 lfo1'>the HTTP request header, <o:p></o:p></li>
  <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:
      auto;mso-list:l0 level2 lfo1'>an input stream fed by the remote client, <o:p></o:p></li>
  <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:
      auto;mso-list:l0 level2 lfo1'>an output stream feeding the remote client<o:p></o:p></li>
  <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:
      auto;mso-list:l0 level2 lfo1'>method to produce OSHttpResponse object
      (for signaling redirects, setting status codes, etc)<o:p></o:p></li>
 </ul>
 <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
     mso-list:l0 level1 lfo1'>we have a pool of OSHttpRequest pumps that take
     OSHttpRequest objects and pump them via the registered event handlers to
     whoever registered an interest (via multicast mechanism that stefan
     already explained a couple of days ago as well)<o:p></o:p></li>
 <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
     mso-list:l0 level1 lfo1'>event handlers return either<o:p></o:p></li>
 <ul type=circle>
  <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:
      auto;mso-list:l0 level2 lfo1'>Pass --- didn't act on it<o:p></o:p></li>
  <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:
      auto;mso-list:l0 level2 lfo1'>Handled --- acted on it, response return as
      out parameter<o:p></o:p></li>
  <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:
      auto;mso-list:l0 level2 lfo1'>Detach --- acting on it, taking care of it
      myself, don't do anything<o:p></o:p></li>
 </ul>
 <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
     mso-list:l0 level1 lfo1'>if no event handler acted on the OSHttpRequest,
     we return an error code<o:p></o:p></li>
 <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
     mso-list:l0 level1 lfo1'>as soon as as we get a Handled or Detached
     response we stop going through the handlers<o:p></o:p></li>
 <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
     mso-list:l0 level1 lfo1'>if we get a Handled we OSHttpResponse.SendHeaders
     and close the input and output streams<o:p></o:p></li>
</ul>

<p class=MsoNormal>any event handler that returns Detached is responsible for
sending response header and for dealing with the input and output stream itself
--- and could, for example, keep an HTTP connection open, implementing a long
poll scheme, for example.<br>
<br>
BaseHttpServer would offer two events to which event handlers could attach:
OnHttpRequest and OnHttpsRequest.<br>
<br>
<br>
what do you think?<br>
<br>
    cheers,<br>
    dr scofield/dirk<br>
<br>
<br>
<o:p></o:p></p>

<pre>-- <o:p></o:p></pre><pre>dr dirk husemann ---- virtual worlds research ---- ibm zurich research lab<o:p></o:p></pre><pre>SL: dr scofield ---- <a
href="mailto:drscofield@xyzzyxyzzy.net">drscofield@xyzzyxyzzy.net</a> ---- <a
href="http://xyzzyxyzzy.net/">http://xyzzyxyzzy.net/</a><o:p></o:p></pre><pre>RL: <a
href="mailto:hud@zurich.ibm.com">hud@zurich.ibm.com</a> - +41 44 724 8573 - <a
href="http://www.zurich.ibm.com/%7Ehud/">http://www.zurich.ibm.com/~hud/</a><o:p></o:p></pre></div>

</body>

</html>