Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

moved spec to spec.html

  • Loading branch information...
commit b51db94d2cc02c02d5bf097ac347e92792b80295 1 parent 9288e21
Benjamin van der Veen authored
Showing with 215 additions and 704 deletions.
  1. +215 −96 spec.html
  2. +0 −260 spec_draft4.html
  3. +0 −348 spec_draft5.html
View
311 spec.html
@@ -1,20 +1,32 @@
<html>
<head>
- <title>OWIN &mdash; Open Web Server Interface for .NET, v1.0 Draft 3</title>
+ <title>OWIN &mdash; Open Web Server Interface for .NET, v1.0 Draft 5</title>
<style>
body
{
font-family: Helvetica, sans-serif;
}
+ .normative, .notes
+ {
+ margin: 10px;
+ padding: 10px;
+ }
+ .normative
+ {
+ border: 1px solid #f99;
+ }
+ .notes
+ {
+ border: 1px solid #ec0;
+ }
</style>
</head>
<body>
-<h1>OWIN &mdash; Open Web Server Interface for .NET, v1.0 Draft 3</h1>
+<h1>OWIN &mdash; Open Web Server Interface for .NET, v1.0 Draft 5</h1>
<ul>
<li>Author: <a href="http://bvanderveen.com">Benjamin van der Veen</a></li>
- <li>Last updated: 3 January 2011</li>
- <li>Discussion: <a href="http://groups.google.com/group/net-http-abstractions">.NET HTTP Abstractions</a></li>
+ <li>Last updated: 9 March 2011</li>
</ul>
<h2>Contents</h2>
@@ -25,6 +37,8 @@
<li><a href="#ApplicationDelegate">Application Delegate</a></li>
<li><a href="#EnvironmentDictionary">Environment Dictionary</a></li>
<li><a href="#ResponseCallback">Response Callback</a></li>
+ <li><a href="#Headers">Headers</a></li>
+ <li><a href="#BodyDelegate">Body Delegate</a></li>
</ul>
</li>
<li><a href="#Paths">Paths</a></li>
@@ -34,149 +48,250 @@
<li><a href="#HostErrors">Host Errors</a></li>
</ul>
</li>
- <li><a href="#Acknowledgements">Acknowledgements</a></li>
</ul>
<a name="Overview"></a>
<h2>Overview</h2>
-<p>This document defines a standard interface between .NET web servers and web applications. The goal of the OWIN interface is to decouple server and application, encourage the development of simple "middleware" modules for .NET web development, and, by being an open standard, stimulate the open source ecosystem of .NET web development tools.</p>
+<p>This document defines OWIN, a standard interface between .NET web servers and web applications. The goal of OWIN is to decouple server and application and, by being an open standard, stimulate the open source ecosystem of .NET web development tools.</p>
+
+
+<p>OWIN is defined in terms of a delegate structure. There is no assembly called <code>OWIN.dll</code> or similar. Implementing either the host or application side the OWIN spec does not introduce a dependency to a project.</p>
+
+<p>In this document, the C# <code>Action</code>/<code>Func</code> syntax is used to notate the delegate structure. However, the delegate structure could be equivalently represented with F# native functions, CLR interfaces, or named delegates. This is by design; when implementing OWIN, choose a delegate representation that works for you and your stack.</p>
+
+<div class="normative">
+<p>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
+</div>
+<div class="notes">
+ <p>Normative sections are highlighted with a red outline, important notes are highlighted with yellow.</p>
+</div>
-<p>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.</p>
<a name="Definition"></a>
<h2>Definition</h2>
-<p>The OWIN interface is expressed as a single raw .NET delegate (the <em>application delegate</em>).</p>
+<p>In this document, an OWIN-compatible web server is referred to as a "host", and an instance of an application delegate (described below) is referred to as an "application". Broadly speaking, a host invokes an application (providing as arguments an environment dictionary, and response and error callbacks); an application either provides a response to the host by invoking the response callback with response information, or indicates an error by invoking the error callback with an exception.</p>
+
+<p>How an application is provided to a host is outside the scope of this specification and must be documented by the host implementor.</p>
+
+<a name="ApplicationDelegate"></a>
+<h3>Application Delegate</h3>
+
+<p>The primary interface in OWIN is called the <em>application delegate</em>. An application delegate takes three parameters: an environment dictionary, a response callback, and an error callback.</p>
<pre><code>Action&lt;
- // an environment dictionary containing server and request data
+ // an environment dictionary containing host and request data
IDictionary&lt;string, object&gt;,
// response callback
- Action&lt;string, IDictionary&lt;string, string&gt;, IEnumerable&lt;object&gt;&gt;,
+ Action&lt;
+ string, // response status, e.g., "200 OK"
+ IDictionary&lt;string, string&gt;, // response headers
+ [a body delegate] // response body, as represented by a body delegate (described below)
+ &gt;,
// error callback
Action&lt;Exception&gt;
&gt;</code></pre>
-<p>In this document, an OWIN-compatible web server is referred to as a "host", and an instance of the above delegate is referred to as an "application". Broadly speaking, hosts invoke applications (providing as arguments an environment dictionary, and response and error callbacks), and the application either provides a response to the host by invoking the response callback with response information, or indicates an error by invoking the error callback with an exception. How an application is provided to a host is outside the scope of this specification and must be documented by the host implementor.</p>
-
-<p>Because OWIN is defined in terms of a raw delegate, there is no need for an assembly called "OWIN.dll" or similar. Implementing either the host or application side the OWIN spec does not introduce a dependency to a project.
-
-<a name="ApplicationDelegate"></a>
-<h3>Application Delegate</h3>
-
-<p>An application delegate takes an environment, a response callback, and an error callback. When an application delegate is invoked, it must invoke either the response callback or the error callback exactly once, or throw an exception. A callback provided to an application by a host must not throw an exception.</p>
+<div class="normative">
+<ul>
+ <li>A host must provide non-null values for all three arguments.</li>
+ <li>The application must invoke either the response callback or the error callback exactly once, or throw an exception.</li>
+</ul>
+</div>
<a name="EnvironmentDictionary"></a>
<h3>Environment Dictionary</h3>
-<p>When a host invokes an application delegate, it provides an environment dictionary which represents the request the application is to process. The environment dictionary also provides additional context to the application. An environment dictionary must be mutable and must contain the following keys whose values must be non-null unless otherwise specified below:</p>
-
-<table border=1>
-<tr>
- <td><code>owin.RequestMethod</code></td>
- <td>The HTTP request method string of the request (e.g., <code>"GET"</code>, <code>"POST"</code>).</td>
-</tr>
-
-<tr>
- <td><code>owin.RequestUri</code></td>
- <td>The HTTP request URI string of the request. The value includes the query string of the HTTP request URI (e.g., <code>"/path/and?query=string"</code>). The URI must be relative to the application delegate; see <a href="#Paths">Paths</a>.</td>
-</tr>
- <tr>
- <td>
- <code>owin.RequestHeaders</code>
- </td>
- <td>
- <p>A dictionary of the form <code>IDictionary&lt;string, string&gt;</code> which represents the HTTP headers present in the request (the <em>request header dictionary</em>). The requirements outlined below are predicated on <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2">RFC 2616 section 4.2</a>.</p>
- <p>The dictionary must be mutable and its keys must be case-insensitive. Keys must be HTTP header names without <code>':'</code> or whitespace. Values are <code>string</code> objects containing the corresponding field-value strings, with any linear whitespace (as defined by <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2">RFC 2616 section 2.2</a>) collapsed to a single space (<code>' '</code>). If a given field-name appears multiple times in a request received by a host, the host must collapse the corresponding field-values into a single string, with the field-values delimited by a comma (<code>','</code>), preserving the order in which the values appeared in the original request. Hosts must not generate request header dictionaries whose values start or end with a comma, contain adjacent commas, or are null, empty, or consist entirely of linear whitespace.</p>
- </td>
- </tr>
+<p>When a host invokes an application delegate, it provides the application with an environment dictionary. The environment dictionary represents the request the application is to process. Host implementations may provide additional context (such as server address and port, client address and port, URL scheme, etc) to the application using keys prefixed with <code>"host."</code>.</p>
+
+<div class="normative">
+<p>An environment dictionary must be mutable and must contain the keys in the table below. The values of the keys must be non-null, unless otherwise specified. Keys starting with the string <code>"host."</code> are reserved for use by host implementations.</p>
+<br>
+<table border="1">
+ <tr>
+ <td><code>"owin.RequestMethod"</code></td>
+ <td>A <code>string</code> containing the HTTP request method of the request (e.g., <code>"GET"</code>, <code>"POST"</code>).</td>
+ </tr>
+ <tr>
+ <td><code>"owin.RequestUri"</code></td>
+ <td>A <code>string</code> containing the HTTP request URI of the request (e.g., <code>"/request/uri"</code>). <!-- The value must be percent-decoded; see <a href="http://tools.ietf.org/html/rfc3986#section-2.1">RFC 3986</a>.--> The value must not include the query string component of the HTTP request URI. The URI must be relative to the application delegate; see <a href="#Paths">Paths</a>.</td>
+ </tr>
+ <!--tr>
+ <td><code>"owin.RequestUriRaw"</code></td>
+ <td>The same value as "owin.RequestUri", but not percent-decoded.</td>
+ </tr-->
+ <tr>
+ <td><code>"owin.RequestQueryString"</code></td>
+ <td>A <code>string</code> containing the query string component of the HTTP request URI (e.g., <code>"foo=bar&baz=quux"</code>). <!--The string must not be percent-decoded.-->
+ </td>
+ </tr>
<tr>
<td>
- <code>owin.RequestBody</code>
+ <code>"owin.RequestHeaders"</code>
</td>
<td>
- <p>A delegate of the form <code>Action&lt;Action&lt;ArraySegment&lt;byte&gt;&gt;, Action&lt;Exception&gt;&gt;</code> (the <em>request body delegate</em>). The request body delegate defines an asynchronous operation which causes the host to read a single chunk of request body data into a buffer and provide it to the application.</p>
- <p>In response to an invocation of the request body delegate, the host must invoke either the result callback or the exception callback exactly once. When invoking the result callback, a host must provide an <code>ArraySegment&lt;byte&gt;</code> which refers to the body data read as a result of the invocation of the request body delegate. This buffer is considered internal to the host implementation and is only guaranteed to be valid during the result callback; if an application wishes to retain the data it must copy it out of the buffer. If there is no more request body data to be read, the host must provide an <code>ArraySegment&lt;byte&gt;</code> whose <code>Count</code> is 0 to signal the end of the request body. After invoking the request body delegate, an application must not invoke the request body delegate again until after the result callback provided to the request body delegate is invoked by the host. If an error occurs while attempting to read the request body, the host must invoke the exception callback with a relevant exception. If the exception callback is invoked, the application must propagate the exception back to the host as described in the <a href="#ErrorHandling">Error Handling</a> section and abort all processing of the request.</p>
+ An instance of <code>IDictionary&lt;string, string&gt;</code> which represents the HTTP headers present in the request (the <em>request header dictionary</em>); see <a href="#Headers">Headers</a>.
</td>
</tr>
<tr>
<td>
- <code>owin.BaseUri</code>
+ <code>"owin.RequestBody"</code>
</td>
<td>
- The portion of the request URI's path corresponding to the "root" of the application object. See <a href="#Paths">Paths</a>.
+ An instance of the body delegate representing the body of the request. May be <code>null</code>.
</td>
</tr>
<tr>
<td>
- <code>owin.ServerName</code>, <code>owin.ServerPort</code>
+ <code>"owin.BaseUri"</code>
</td>
<td>
- Hosts should provide values which can be used to reconstruct the full URI of the request in absence of the HTTP <code>Host</code> header of the request.
+ A <code>string</code> containing the portion of the request URI's path corresponding to the "root" of the application delegate; see <a href="#Paths">Paths</a>. <!-- The value must be percent-decoded; see <a href="http://tools.ietf.org/html/rfc3986#section-2.1">RFC 3986</a>. -->
</td>
</tr>
- <tr>
+ <!--tr>
<td>
- <code>owin.UriScheme</code>
+ <code>"owin.BaseUriRaw"</code>
</td>
<td>
- <code>"http"</code> or <code>"https"</code>.
+ The same value as <code>"owin.BaseUri"</code>, but not percent-decoded.
</td>
- </tr>
+ </tr-->
<tr>
<td>
- <code>owin.RemoteEndPoint</code>
- </td>
- <td>
- A <code>System.Net.IPEndPoint</code> representing the connected client.
- </td>
- </tr>
- <tr>
- <td>
- <code>owin.Version</code>
+ <code>"owin.Version"</code>
</td>
<td>
The string <code>"1.0"</code> indicating OWIN version 1.0.
</td>
</tr>
-
</table>
+
+</div>
+
+<div class="notes">
<p>In addition to these keys, the host, application, or user may add arbitrary data associated with the request to the environment dictionary.</p>
+</div>
<a name="ResponseCallback"></a>
<h3>Response Callback</h3>
-<p>The response callback of the application delegate takes three arguments of type <code>string</code>, <code>Dictionary&lt;string, string&gt;</code>, and <code>IEnumerable&lt;object&gt;&gt;</code>. These arguments together represent an HTTP response generated by an application.</p>
-
-<p>The first argument to the response callback must be a string which contains the integer status of the response followed by a space and a reason phrase without a newline (e.g., <code>"200 OK"</code>). All characters in the status string provided by an application should be within the ASCII codepage.</p>
+<p>The response callback of the application delegate takes three arguments. The first is a <code>string</code> object representing the response status; the second is an instance of <code>IDictionary&lt;string, string&gt;</code> representing the response headers; the third is a body delegate representing the response body. These arguments together represent an HTTP response generated by an application.</p>
-<p>The second argument to the response callback must be a dictionary representing the headers to be sent with the request (the <em>response header dictionary</em>). The dictionary must be mutable and its keys must be case-insensitive. The keys must be header field-names without <code>':'</code> or whitespace. Values must be <code>string</code> objects containing the corresponding header field-value strings. The application must encode or strip all <code>'\r'</code> and <code>'\n'</code> characters from header value data. The application should use the token <code>"\r\n"</code> to delimit values that are required to be sent as separate response headers of the same name (this is to support <code>Set-Cookie</code>). Applications must not produce dictionary values which start or end with <code>"\r\n"</code>, or contain adjacent <code>"\r\n"</code> delimiters. Applications must not generate response header dictionaries whose values start or end with <code>"\r\n"</code>, contain adjacent <code>"\r\n"</code> delimiters, or are null, empty, or consist entirely of linear whitespace (as defined by <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2">RFC 2616 section 2.2</a>). All characters in header field-name and field-value strings should be within the ASCII codepage.</p>
+<div class="normative">
+<ul>
+ <li>The first argument to the response callback must be a <code>string</code> which contains the integer status of the response followed by a space and a reason phrase without a newline (e.g., <code>"200 OK"</code>). All characters in the status string provided by an application should be within the ASCII codepage.</li>
+ <li>The second argument to the response callback must be a dictionary representing the headers to be sent with the request (the <em>response header dictionary</em>). See <a href="#Headers">Headers</a>.
+ </li>
+ <li>
+ The third argument must be a body delegate representing the response body, or null.
+ </li>
+ </ul>
+</div>
-<p>The third argument to the response callback must be a instance of <code>IEnumerable&lt;object&gt;</code> which represents the body data (the <em>response enumerable</em>), or null if the response does not include a body. Each item in the response enumerable may be of one of the following types (the <em>response item types</em>):</p>
+<a name="Headers"></a>
+<h3>Headers</h3>
+<p>
+ The headers of HTTP messages are represented by objects of type <code>IDictionary&lt;string, string&gt;</code>. Request headers are contained within the environment dictionary, and response headers are provided to the response callback.
+</p>
-<ul>
-<li><code>byte[]</code></li>
-<li><code>ArraySegment&lt;byte&gt;</code></li>
-<li><code>FileInfo</code></li>
-<li><code>Action&lt;Action&lt;object&gt;,Action&lt;Exception&gt;&gt;</code></li>
-</ul>
+<div class="normative">
+ <h4>Common header dictionary requirements</h4>
+
+ <ul>
+ <li>The dictionary must be mutable.</li>
+ <li>Keys must be HTTP field-names without <code>':'</code> or whitespace.</li>
+ <li>Keys must be case-insensitive.</li>
+ <li>All characters in key and value strings should be within the ASCII codepage.</li>
+ </ul>
+</div>
-<p>Hosts must write both <code>byte[]</code> and <code>ArraySegment&lt;byte&gt;</code> to the underlying transport as raw data. <code>FileInfo</code> must cause the host to write the named file to the underlying transport. How relative file paths are resolved is outside the scope of this specification and must be documented by the host implementor.</p>
+<p>The requirements below are predicated on <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2">RFC 2616 section 4.2</a>.</p>
-<p>An item of the type <code>Action&lt;Action&lt;object&gt;,Action&lt;Exception&gt;&gt;</code> (an <em>asynchronous response delegate</em>) allows applications to provide the next item asynchronously. The semantics of this delegate are the same as that of the application delegate and the request body delegate. The host must provide non-null result and exception callbacks to the delegate, and when the delegate is invoked, the application must invoke either the result or exception callback exactly once. A host must invoke an asynchronous response delegate exactly once, and the callbacks it provides must not throw exceptions. The application may invoke the result callback with objects of any of the response item types.<p>
+<div class="normative">
+
+ <h4>Request header dictionary requirements</h4>
+
+ <ul>
+ <li>If a field-value in a request received by a host contains linear whitespace (as defined by <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2">RFC 2616 section 2.2</a>), the host must collapse it to a single space (<code>'&nbsp;'</code>) in the corresponding dictionary value string.</li>
+ <li>If a given field-name appears multiple times in a request received by a host, the host must collapse the corresponding field-values into a single dictionary string value, with the field-values delimited by a comma (<code>','</code>), preserving the order in which the field-values appeared in the original request.</li>
+ <li>Hosts must not generate request header dictionaries whose values start or end with a comma, contain adjacent commas, or are null, empty, or consist entirely of linear whitespace.</li>
+ </ul>
+
+
+ <h4>Response header dictionary requirements</h4>
+
+ <ul>
+ <li>The application must encode or strip all <code>'\r'</code> and <code>'\n'</code> characters from header value data.</li>
+ <li>The application must use the token <code>"\r\n"</code> to delimit values that are required to be sent as separate response headers of the same name (as in the case of <code>Set-Cookie</code>).</li>
+ <li>Applications must not generate response header dictionaries whose values start or end with <code>"\r\n"</code>, contain adjacent <code>"\r\n"</code> delimiters, or are null, empty, or consist entirely of linear whitespace (as defined by <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2">RFC 2616 section 2.2</a>).</li>
+
+ </ul>
+</div>
+
+<a name="BodyDelegate"></a>
+<h3>Body Delegate</h3>
+
+<p>The <em>body delegate</em> is the mechanism which transfers entity data between host and application. It is used for both request and response entities in OWIN. Code sending data using the delegate is called the "producer", and code receiving data using the delegate is called the "consumer". In the context of a request, the host plays the role of producer; in the context of a response, the application plays the role of producer.</p>
+
+<p>An instance of the delegate is implemented by a producer; a consumer invokes the delegate and provides it on-next, on-error, and on-complete callbacks. The return value of the body delegate is a cancellation delegate, which allows the consumer to instruct the producer not to produce any further values.</p>
+
+<p>The body delegate is equivalent to <code>IObserver</code>/<code>IObservable</code>, except for a modified on-next callback signature. In addition to taking a data value parameter, the on-next callback takes a continuation parameter, and returns a boolean value indicating whether or not it will invoke the continuation.
+
+<pre><code>Func&lt;
+
+ // on next
+ Func&lt;
+ ArraySegment&lt;byte&gt;, // data
+ Action, // continuation
+ bool // will invoke continuation
+ &gt;,
+
+ // on error
+ Action&lt;Exception&gt;,
+
+ // on complete
+ Action,
+
+ // cancel
+ Action
+&gt;</code></pre>
-<p>In the interest of extensibility, a response enumerable may contain items (and an asynchronous response delegate may yield values) whose types are not among the response item types listed above, and hosts may support additional response item types and define and document corresponding behaviors. If a host does not recognize the type of an object contained in the response enumerable or yielded by an asynchronous response delegate, it may ignore the object and continue enumerating.</p>
+<p>The signature of the on-next callback allows the consumer to instruct the producer to "back off" and not produce values for a time (specifically, until the consumer invokes the continuation). Without this backpressure mechanism, a producer could potentially produce values faster than a consumer could process them without buffering, and the buffer could grow unbounded.</p>
-<p>Hosts must enumerate the enumerable to completion (i.e., until <code>MoveNext</code> returns false) or until an exception is thrown by <code>MoveNext()</code> or the <code>Current</code> property. After all of the items have been enumerated or if an exception occurs during enumeration, the host must call <code>Dispose</code> on the enumerator.</p>
+<div class="normative">
+<ul>
+ <li>If the producer provides a null continuation to the on-next callback, the consumer must return false.</li>
+ <li>If the producer provides a non-null continuation to the on-next callback, the consumer may return true or false.
+ <li>The consumer returns true from the on-next callback if and only if the consumer will eventually invoke the continuation. The consumer must not invoke the continuation in a manner such that the on-next callback which provided the continuation is on the call stack when the continuation is invoked.</li>
+ <li>The consumer returns false from the on-next callback if and only if the consumer will never invoke continuation.</li>
+ </li>
+ <li>If the consumer returns true from the on-next callback, the producer must not invoke the consumer's on-next, on-error, or on-complete callbacks until the consumer invokes the continuation provided by the producer.</li>
+ <li>The producer must signal the end of the sequence of values by invoking either the on-complete callback or the on-error callback. After invoking the on-complete callback or on-error callback, the producer must not subsequently invoke any of the consumer's callbacks.</li>
+</ul>
+</div>
+<div class="notes">
+ <p>In general, a consumer should not invoke a body delegate more than once. While a "repeatable" producer is possible, consumers should not assume that a producer is repeatable and producers may not support repeatability.</li>
+
+ <p>Instances of <code>ArraySegment&lt;byte&gt;</code> provided to consumers should be considered internal to the producer implementation and are guaranteed to be valid only for the duration of the on-next callback. Once the on-next callback returns, the <code>ArraySegment&lt;byte&gt;</code> may be invalid. If a consumer wishes to retain the data it should copy it out of the buffer before the on-next callback returns.</p>
+</div>
<a name="Paths"></a>
<h2>Paths</h2>
-<p>Hosts may have the ability to map application objects to some base path. For example, a host might have an application delegate configured to respond to requests beginning with <code>"/my-app"</code>, in which case it must set the value of <code>"owin.BaseUri"</code> in the environment dictionary to <code>"/my-app"</code>. If this host receives a request for <code>"/my-app/foo"</code>, the <code>owin.RequestUri</code> value of the environment dictionary provided to the application configured to respond at <code>"/my-app"</code> must be <code>"/foo"</code>. The value of <code>"owin.BaseUri"</code> may be an empty string and must not end with a trailing slash; the value of the <code>"owin.RequestUri"</code> property must not be an empty string and must start with a slash.</p>
+<p>Hosts may have the ability to map application objects to some base path. For example, a host might have an application delegate configured to respond to requests beginning with <code>"/my-app"</code>, in which case it should set the value of <code>"owin.BaseUri"</code> in the environment dictionary to <code>"/my-app"</code>. If this host receives a request for <code>"/my-app/foo"</code>, the <code>owin.RequestUri</code> value of the environment dictionary provided to the application configured to respond at <code>"/my-app"</code> should be <code>"/foo"</code>.</p>
+
+<div class="normative">
+<ul>
+ <li>The value of the <code>"owin.BaseUri"</code> environment dictionary key may be an empty string and must not end with a trailing slash</li>
+ <li>The value of the <code>"owin.RequestUri"</code> environment dictionary key must not be an empty string and must start with a slash.</li>
+</ul>
+</div>
+
<a name="ErrorHandling"></a>
<h2>Error Handling</h2>
@@ -184,46 +299,50 @@
<a name="ApplicationErrors"></a>
<h3>Application Errors</h3>
-<p>An application might generate an exception in the following places:</p>
+<p>An application may generate an exception in the following places:</p>
<ul>
<li>Thrown from an invocation of the application delegate.</li>
<li>Provided to the error callback of the application delegate.</li>
- <li>Thrown from the result callback of the request body delegate.</li>
- <li>Thrown from the error callback of the request body delegate.</li>
- <li>Thrown from the <code>GetEnumerator</code> method of the response enumerable.</li>
- <li>Thrown from the <code>MoveNext</code> method of the enumerator returned by the response enumerable.</li>
- <li>Thrown from the <code>Current</code> property of the enumerator returned by the response enumerable.</li>
- <li>Thrown from an invocation of an asynchronous response item contained in the response enumerable.</li>
- <li>Provided to the error callback of an asynchronous item delegate contained in the response enumerable.</li>
+ <li>Thrown from an invocation of the on-next, on-error, or on-complete callbacks provided to the request body delegate.</li>
+ <li>Thrown from an invocation of the response body delegate.</li>
+ <li>Provided to the on-error callback of the response body delegate.</li>
+ <li>Thrown from an invocation of the continuation provided to the on-next callback of the response body delegate.</li>
+ <li>Thrown from an invocation of the cancellation delegate returned by the response body delegate.</li>
</ul>
<p>An application should attempt to trap its own internal errors and generate an appropriate (possibly 500-level) response rather than propagating an exception up to the host.</p>
-<p>After an application provides a response, if the response enumerable is non-null, the host should attempt to enumerate at least one item from the response enumerable before writing the response headers to the underlying transport. If the enumeration of the first item results in an error, the host will be able to generate a 500-level response. Otherwise, the application has caught as many of its internal errors as possible and host can begin the response without further buffering. If an exception is thrown by the application while enumerating subsequent items from the response body enumerable, the host may write a textual description of the error to the underlying transport, and/or close the connection.</p>
+<p>After an application provides a response, if the response body delegate is non-null, the host should wait to receive least one on-next callback from the the response body delegate before writing the response headers to the underlying transport. In this way, if instead of an on-next callback the host gets an on-error callback, the host will be able to generate a 500-level response. If the host gets an on-next callback first, it can safely assume that the application has caught as many of its internal errors as possible; the host can begin the response without further buffering. If an on-error callback is subsequently received, the host may write a textual description of the error to the underlying transport, and/or close the connection.</p>
<a name="HostErrors"></a>
<h3>Host Errors</h3>
-<p>A host might generate exceptions in the following places:</p>
+<p>A host may generate exceptions in the following places:</p>
<ul>
<li>Thrown from an invocation of the request body delegate.</li>
- <li>Provided to the error callback of the request body delegate.</li>
+ <li>Provided to the on-error callback of the request body delegate.</li>
</ul>
-<p>An exception generated in either of these places may indicate that the client has closed or dropped the connection, or another transport-layer error has occurred. The application should perform any post-mortem logic it needs to, and must propagate the exception back to the host through one of the sites described in <a href="#ApplicationErrors">Application Errors</a>.</p>
+<p>An exception generated in either of these places may indicate that the client has closed or dropped the connection, or another transport-layer error has occurred.
+
+<div class="normative">
+ <p>If an application receives an error from a host, it must propagate it back to the host through one of the sites described in <a href="#ApplicationErrors">Application Errors</a>.</p>
+</div>
-<a name="Acknowledgements"></a>
-<h2>Acknowledgments</h2>
+<p>There are several other points where an application might call into the host but cannot meaningfully handle an exception from thrown from the call.<p>
-<p>This specification draws heavily on the wonderful <a href="http://www.python.org/dev/peps/pep-0333/">PEP 333 (WSGI)</a>. Many thanks to everyone participating in the discussion at <a href="http://groups.google.com/group/net-http-abstractions">.NET HTTP Abstractions</a>, and in particular:
+<div class="notes">
+ <p>A host should not generate exceptions in the following places:</p>
<ul>
- <li><a href="http://twitter.com/panesofglass">Ryan Riley</a></li>
- <li><a href="http://twitter.com/serialseb">Sebastien Lambla</a></li>
- <li><a href="http://jdhardy.blogspot.com/">Jeff Hardy</a></li>
- <li><a href="http://twitter.com/demisbellot">Demis Bellot</a></li>
- <li><a href="http://whereslou.com/">Louis DeJardin</a></li>
+ <li>Thrown from an invocation of the response callback provided to the application delegate.</li>
+ <li>Thrown from an invocation of the error callback provided to the application delegate.</li>
+ <li>Thrown from an invocation of the continuation provided to the on-next callback of the request body delegate.</li>
+ <li>Thrown from an invocation of the cancellation delegate returned by the request body delegate.</li>
+ <li>Thrown from the on-next, on-error, or on-completed callbacks provided to the response body delegate.</li>
</ul>
+</div>
+
</body>
</html>
View
260 spec_draft4.html
@@ -1,260 +0,0 @@
-<html>
-<head>
- <title>OWIN &mdash; Open Web Server Interface for .NET, v1.0 Draft 3</title>
- <style>
- body
- {
- font-family: Helvetica, sans-serif;
- }
- </style>
-</head>
-<body>
-
-<h1>OWIN &mdash; Open Web Server Interface for .NET, v1.0 Draft 4</h1>
-<ul>
- <li>Author: <a href="http://bvanderveen.com">Benjamin van der Veen</a></li>
- <li>Last updated: 13 February 2011</li>
- <li>Discussion: <a href="http://groups.google.com/group/net-http-abstractions">.NET HTTP Abstractions</a></li>
-</ul>
-
-<h2>Contents</h2>
-<ul>
- <li><a href="#Overview">Overview</a></li>
- <li><a href="#Definition">Definition</a>
- <ul>
- <li><a href="#ApplicationDelegate">Application Delegate</a></li>
- <li><a href="#EntityStreamDelegate">Entity Stream Delegate</a></li>
- <li><a href="#EnvironmentDictionary">Environment Dictionary</a></li>
- <li><a href="#ResponseCallback">Response Callback</a></li>
- </ul>
- </li>
- <li><a href="#Paths">Paths</a></li>
- <li><a href="#ErrorHandling">Error Handling</a>
- <ul>
- <li><a href="#ApplicationErrors">Application Errors</a></li>
- <li><a href="#HostErrors">Host Errors</a></li>
- </ul>
- </li>
- <li><a href="#Acknowledgements">Acknowledgements</a></li>
-</ul>
-
-<a name="Overview"></a>
-<h2>Overview</h2>
-
-<p>This document defines a standard interface between .NET web servers and web applications. The goal of the OWIN interface is to decouple server and application, encourage the development of simple "middleware" modules for .NET web development, and, by being an open standard, stimulate the open source ecosystem of .NET web development tools.</p>
-
-<p>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.</p>
-
-<a name="Definition"></a>
-<h2>Definition</h2>
-
-<p>In this document, an OWIN-compatible web server is referred to as a "host", and an instance of an application delegate (described below) is referred to as an "application". Broadly speaking, a host invokes an application (providing as arguments an environment dictionary, and response and error callbacks); an application either provides a response to the host by invoking the response callback with response information, or indicates an error by invoking the error callback with an exception.</p>
-
-<p>How an application is provided to a host is outside the scope of this specification and must be documented by the host implementor.</p>
-
-<p>Because OWIN is defined in terms of a raw delegate, there is no need for an assembly called "OWIN.dll" or similar. Implementing either the host or application side the OWIN spec does not introduce a dependency to a project.</p>
-
-<p>In this document, the C# <code>Action</code>/<code>Func</code> syntax is used to notate the delegate structure. However, the delegate structure could be equivalently represented with F# native functions, CLR interfaces, or named delegates. This is by design; when implementing OWIN, choose an equivalent representation that works for you.</p>
-
-<a name="ApplicationDelegate"></a>
-<h3>Application Delegate</h3>
-
-<p>The primary interface in OWIN is called the <em>application delegate</em>. An application delegate takes three parameters: an environment dictionary, a response callback, and an error callback.</p>
-
-<pre><code>Action&lt;
- // an environment dictionary containing host and request data
- IDictionary&lt;string, object&gt;,
-
- // response callback
- Action&lt;
- string, // response status, e.g., "200 OK"
- IDictionary&lt;string, string&gt;, // response headers
- EntityStream // response body, as represented by an entity stream delegate (described below)
- &gt;,
-
- // error callback
- Action&lt;Exception&gt;
-&gt;</code></pre>
-
-<p>A host must provide non-null values for all three arguments. The application must invoke either the response callback or the error callback exactly once, or throw an exception. The response and error callbacks provided to an application by a host must not throw an exception.</p>
-
-<a name="EntityStreamDelegate"></a>
-<h3>Entity Stream Delegate</h3>
-
-<p>The <em>entity stream delegate</em> is a mechanism for transferring streaming data between host and application. It is used for both request and response entities in OWIN.</p>
-
-<p>The entity stream delegate is roughly equivalent to <code>IObserver</code>/<code>IObservable</code>, but with a modified "on next" signature. An instance of the delegate is a producer; a consumer invokes the delegate and provides it "on next", "on error", and "on complete" callbacks. The return value of the entity stream delegate is a cancellation delegate, which allows the consumer to instruct the producer not to produce any further values.</p>
-
-<p>The purpose of the modified "on next" callback is to enable the consumer to instruct the producer to "back off" and not produce values for a time, thereby preventing potentially unbounded buffer sizes in host and application implementations.</p>
-
-<p>In addition to taking a data value parameter, the "on next" callback takes a continuation parameter, and returns a boolean value indicating whether or not it will invoke the continuation.</p>
-
-<pre><code>Func&lt;
-
- // on next
- Func&lt;
- ArraySegment&lt;byte&gt;, // data
- Action, // continuation
- bool // will invoke continuation
- &gt;,
-
- // on error
- Action&lt;Exception&gt;,
-
- // on complete
- Action,
-
- // cancel
- Action
-&gt;</code></pre>
-
-<p>If the producer provides a null continuation, the consumer must return false. If the producer provides a non-null continuation, the consumer may return true or false. If the consumer returns true, the consumer must eventually invoke the continuation. The consumer must not invoke the continuation in a manner such that the "on next" callback which provided the continuation is on the stack when the continuation is invoked. If the consumer returns false, it must not invoke the continuation provided by the producer.
-
-<p>If the consumer returns true, the producer must not invoke the consumer "on next", "on error", or "on complete" callbacks until the consumer invokes the continuation provided by the producer. If the consumer returns false, the producer may invoke the "on next", "on error, or "on complete"" callbacks at any time.</p>
-
-<p>Instances of <code>ArraySegment&lt;byte&gt;</code> provided to consumers must be considered internal to the producer implementation and must be guaranteed to be valid only for the duration of the "on next" callback. Once the "on next" callback returns, the <code>ArraySegment&lt;byte&gt;</code> may be invalid. If a consumer wishes to retain the data it must copy it out of the buffer before the "on next" callback returns.</p>
-
-<a name="EnvironmentDictionary"></a>
-<h3>Environment Dictionary</h3>
-
-<p>When a host invokes an application delegate, it provides the application with an environment dictionary. The environment dictionary represents the request the application is to process and provides additional context to the application. An environment dictionary must be mutable and must contain the following keys whose values must be non-null unless otherwise specified:</p>
-
-<table border=1>
-<tr>
- <td><code>owin.RequestMethod</code></td>
- <td>The HTTP request method string of the request (e.g., <code>"GET"</code>, <code>"POST"</code>).</td>
-</tr>
-
-<tr>
- <td><code>owin.RequestUri</code></td>
- <td>The HTTP request URI string of the request. The value includes the query string of the HTTP request URI (e.g., <code>"/path/and?query=string"</code>). The URI must be relative to the application delegate; see <a href="#Paths">Paths</a>.</td>
-</tr>
- <tr>
- <td>
- <code>owin.RequestHeaders</code>
- </td>
- <td>
- <p>A dictionary of the form <code>IDictionary&lt;string, string&gt;</code> which represents the HTTP headers present in the request (the <em>request header dictionary</em>).</p>
- <p>The dictionary must be mutable and its keys must be case-insensitive. Keys must be HTTP header names without <code>':'</code> or whitespace. </p>
- <p>The requirements below are predicated on <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2">RFC 2616 section 4.2</a>.</p>
- <p>Values must be <code>string</code> objects containing the corresponding field-value strings, with any linear whitespace (as defined by <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2">RFC 2616 section 2.2</a>) collapsed to a single space (<code>' '</code>). If a given field-name appears multiple times in a request received by a host, the host must collapse the corresponding field-values into a single string, with the field-values delimited by a comma (<code>','</code>), preserving the order in which the values appeared in the original request. Hosts must not generate request header dictionaries whose values start or end with a comma, contain adjacent commas, or are null, empty, or consist entirely of linear whitespace.</p>
- </td>
- </tr>
- <tr>
- <td>
- <code>owin.RequestBody</code>
- </td>
- <td>
- <p>An entity stream delegate representing the body of the request.</p>
- </td>
- </tr>
- <tr>
- <td>
- <code>owin.BaseUri</code>
- </td>
- <td>
- The portion of the request URI's path corresponding to the "root" of the application object. See <a href="#Paths">Paths</a>.
- </td>
- </tr>
- <tr>
- <td>
- <code>owin.ServerName</code>, <code>owin.ServerPort</code>
- </td>
- <td>
- Hosts should provide values which can be used to reconstruct the full URI of the request in absence of the HTTP <code>Host</code> header of the request.
- </td>
- </tr>
- <tr>
- <td>
- <code>owin.UriScheme</code>
- </td>
- <td>
- <code>"http"</code> or <code>"https"</code>.
- </td>
- </tr>
- <tr>
- <td>
- <code>owin.RemoteEndPoint</code>
- </td>
- <td>
- A <code>System.Net.IPEndPoint</code> representing the connected client.
- </td>
- </tr>
- <tr>
- <td>
- <code>owin.Version</code>
- </td>
- <td>
- The string <code>"1.0"</code> indicating OWIN version 1.0.
- </td>
- </tr>
-
-</table>
-
-<p>In addition to these keys, the host, application, or user may add arbitrary data associated with the request to the environment dictionary.</p>
-
-<a name="ResponseCallback"></a>
-<h3>Response Callback</h3>
-
-<p>The response callback of the application delegate takes three arguments. The first two are of type <code>string</code>, <code>Dictionary&lt;string, string&gt;</code>. The third is an entity stream delegate representing the response body. These arguments together represent an HTTP response generated by an application.</p>
-
-<p>The first argument to the response callback must be a string which contains the integer status of the response followed by a space and a reason phrase without a newline (e.g., <code>"200 OK"</code>). All characters in the status string provided by an application should be within the ASCII codepage.</p>
-
-<p>The second argument to the response callback must be a dictionary representing the headers to be sent with the request (the <em>response header dictionary</em>). The dictionary must be mutable and its keys must be case-insensitive. The keys must be header field-names without <code>':'</code> or whitespace. Values must be <code>string</code> objects containing the corresponding header field-value strings. The application must encode or strip all <code>'\r'</code> and <code>'\n'</code> characters from header value data. The application must use the token <code>"\r\n"</code> to delimit values that are required to be sent as separate response headers of the same name (this is to support <code>Set-Cookie</code>). Applications must not generate response header dictionaries whose values start or end with <code>"\r\n"</code>, contain adjacent <code>"\r\n"</code> delimiters, or are null, empty, or consist entirely of linear whitespace (as defined by <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2">RFC 2616 section 2.2</a>). All characters in header field-name and field-value strings should be within the ASCII codepage.</p>
-
-<p>The third argument must be an entity stream delegate representing the response body, or null.</p>
-
-<a name="Paths"></a>
-<h2>Paths</h2>
-
-<p>Hosts may have the ability to map application objects to some base path. For example, a host might have an application delegate configured to respond to requests beginning with <code>"/my-app"</code>, in which case it must set the value of <code>"owin.BaseUri"</code> in the environment dictionary to <code>"/my-app"</code>. If this host receives a request for <code>"/my-app/foo"</code>, the <code>owin.RequestUri</code> value of the environment dictionary provided to the application configured to respond at <code>"/my-app"</code> must be <code>"/foo"</code>. The value of <code>"owin.BaseUri"</code> may be an empty string and must not end with a trailing slash; the value of the <code>"owin.RequestUri"</code> property must not be an empty string and must start with a slash.</p>
-
-<a name="ErrorHandling"></a>
-<h2>Error Handling</h2>
-
-<a name="ApplicationErrors"></a>
-<h3>Application Errors</h3>
-
-<p>An application might generate an exception in the following places:</p>
-
-<ul>
- <li>Thrown from an invocation of the application delegate.</li>
- <li>Provided to the error callback of the application delegate.</li>
- <li>Thrown from the result callback of the request body delegate.</li>
- <li>Thrown from the error callback of the request body delegate.</li>
- <li>Thrown from the <code>GetEnumerator</code> method of the response enumerable.</li>
- <li>Thrown from the <code>MoveNext</code> method of the enumerator returned by the response enumerable.</li>
- <li>Thrown from the <code>Current</code> property of the enumerator returned by the response enumerable.</li>
- <li>Thrown from an invocation of an asynchronous response item contained in the response enumerable.</li>
- <li>Provided to the error callback of an asynchronous item delegate contained in the response enumerable.</li>
-</ul>
-
-<p>An application should attempt to trap its own internal errors and generate an appropriate (possibly 500-level) response rather than propagating an exception up to the host.</p>
-
-<p>After an application provides a response, if the response enumerable is non-null, the host should attempt to enumerate at least one item from the response enumerable before writing the response headers to the underlying transport. If the enumeration of the first item results in an error, the host will be able to generate a 500-level response. Otherwise, the application has caught as many of its internal errors as possible and host can begin the response without further buffering. If an exception is thrown by the application while enumerating subsequent items from the response body enumerable, the host may write a textual description of the error to the underlying transport, and/or close the connection.</p>
-
-<a name="HostErrors"></a>
-<h3>Host Errors</h3>
-
-<p>A host might generate exceptions in the following places:</p>
-
-<ul>
- <li>Thrown from an invocation of the request body delegate.</li>
- <li>Provided to the error callback of the request body delegate.</li>
-</ul>
-
-<p>An exception generated in either of these places may indicate that the client has closed or dropped the connection, or another transport-layer error has occurred. The application should perform any post-mortem logic it needs to, and must propagate the exception back to the host through one of the sites described in <a href="#ApplicationErrors">Application Errors</a>.</p>
-
-<a name="Acknowledgements"></a>
-<h2>Acknowledgments</h2>
-
-<p>This specification draws heavily on the wonderful <a href="http://www.python.org/dev/peps/pep-0333/">PEP 333 (WSGI)</a>. Many thanks to everyone participating in the discussion at <a href="http://groups.google.com/group/net-http-abstractions">.NET HTTP Abstractions</a>, and in particular:
- <ul>
- <li><a href="http://twitter.com/panesofglass">Ryan Riley</a></li>
- <li><a href="http://twitter.com/serialseb">Sebastien Lambla</a></li>
- <li><a href="http://jdhardy.blogspot.com/">Jeff Hardy</a></li>
- <li><a href="http://twitter.com/demisbellot">Demis Bellot</a></li>
- <li><a href="http://whereslou.com/">Louis DeJardin</a></li>
- </ul>
-</body>
-</html>
View
348 spec_draft5.html
@@ -1,348 +0,0 @@
-<html>
-<head>
- <title>OWIN &mdash; Open Web Server Interface for .NET, v1.0 Draft 5</title>
- <style>
- body
- {
- font-family: Helvetica, sans-serif;
- }
- .normative, .notes
- {
- margin: 10px;
- padding: 10px;
- }
- .normative
- {
- border: 1px solid #f99;
- }
- .notes
- {
- border: 1px solid #ec0;
- }
- </style>
-</head>
-<body>
-
-<h1>OWIN &mdash; Open Web Server Interface for .NET, v1.0 Draft 5</h1>
-<ul>
- <li>Author: <a href="http://bvanderveen.com">Benjamin van der Veen</a></li>
- <li>Last updated: 9 March 2011</li>
-</ul>
-
-<h2>Contents</h2>
-<ul>
- <li><a href="#Overview">Overview</a></li>
- <li><a href="#Definition">Definition</a>
- <ul>
- <li><a href="#ApplicationDelegate">Application Delegate</a></li>
- <li><a href="#EnvironmentDictionary">Environment Dictionary</a></li>
- <li><a href="#ResponseCallback">Response Callback</a></li>
- <li><a href="#Headers">Headers</a></li>
- <li><a href="#BodyDelegate">Body Delegate</a></li>
- </ul>
- </li>
- <li><a href="#Paths">Paths</a></li>
- <li><a href="#ErrorHandling">Error Handling</a>
- <ul>
- <li><a href="#ApplicationErrors">Application Errors</a></li>
- <li><a href="#HostErrors">Host Errors</a></li>
- </ul>
- </li>
-</ul>
-
-<a name="Overview"></a>
-<h2>Overview</h2>
-
-<p>This document defines OWIN, a standard interface between .NET web servers and web applications. The goal of OWIN is to decouple server and application and, by being an open standard, stimulate the open source ecosystem of .NET web development tools.</p>
-
-
-<p>OWIN is defined in terms of a delegate structure. There is no assembly called <code>OWIN.dll</code> or similar. Implementing either the host or application side the OWIN spec does not introduce a dependency to a project.</p>
-
-<p>In this document, the C# <code>Action</code>/<code>Func</code> syntax is used to notate the delegate structure. However, the delegate structure could be equivalently represented with F# native functions, CLR interfaces, or named delegates. This is by design; when implementing OWIN, choose a delegate representation that works for you and your stack.</p>
-
-<div class="normative">
-<p>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
-</div>
-<div class="notes">
- <p>Normative sections are highlighted with a red outline, important notes are highlighted with yellow.</p>
-</div>
-
-
-<a name="Definition"></a>
-<h2>Definition</h2>
-
-<p>In this document, an OWIN-compatible web server is referred to as a "host", and an instance of an application delegate (described below) is referred to as an "application". Broadly speaking, a host invokes an application (providing as arguments an environment dictionary, and response and error callbacks); an application either provides a response to the host by invoking the response callback with response information, or indicates an error by invoking the error callback with an exception.</p>
-
-<p>How an application is provided to a host is outside the scope of this specification and must be documented by the host implementor.</p>
-
-<a name="ApplicationDelegate"></a>
-<h3>Application Delegate</h3>
-
-<p>The primary interface in OWIN is called the <em>application delegate</em>. An application delegate takes three parameters: an environment dictionary, a response callback, and an error callback.</p>
-
-<pre><code>Action&lt;
- // an environment dictionary containing host and request data
- IDictionary&lt;string, object&gt;,
-
- // response callback
- Action&lt;
- string, // response status, e.g., "200 OK"
- IDictionary&lt;string, string&gt;, // response headers
- [a body delegate] // response body, as represented by a body delegate (described below)
- &gt;,
-
- // error callback
- Action&lt;Exception&gt;
-&gt;</code></pre>
-
-<div class="normative">
-<ul>
- <li>A host must provide non-null values for all three arguments.</li>
- <li>The application must invoke either the response callback or the error callback exactly once, or throw an exception.</li>
-</ul>
-</div>
-
-<a name="EnvironmentDictionary"></a>
-<h3>Environment Dictionary</h3>
-
-<p>When a host invokes an application delegate, it provides the application with an environment dictionary. The environment dictionary represents the request the application is to process. Host implementations may provide additional context (such as server address and port, client address and port, URL scheme, etc) to the application using keys prefixed with <code>"host."</code>.</p>
-
-<div class="normative">
-<p>An environment dictionary must be mutable and must contain the keys in the table below. The values of the keys must be non-null, unless otherwise specified. Keys starting with the string <code>"host."</code> are reserved for use by host implementations.</p>
-<br>
-<table border="1">
- <tr>
- <td><code>"owin.RequestMethod"</code></td>
- <td>A <code>string</code> containing the HTTP request method of the request (e.g., <code>"GET"</code>, <code>"POST"</code>).</td>
- </tr>
- <tr>
- <td><code>"owin.RequestUri"</code></td>
- <td>A <code>string</code> containing the HTTP request URI of the request (e.g., <code>"/request/uri"</code>). <!-- The value must be percent-decoded; see <a href="http://tools.ietf.org/html/rfc3986#section-2.1">RFC 3986</a>.--> The value must not include the query string component of the HTTP request URI. The URI must be relative to the application delegate; see <a href="#Paths">Paths</a>.</td>
- </tr>
- <!--tr>
- <td><code>"owin.RequestUriRaw"</code></td>
- <td>The same value as "owin.RequestUri", but not percent-decoded.</td>
- </tr-->
- <tr>
- <td><code>"owin.RequestQueryString"</code></td>
- <td>A <code>string</code> containing the query string component of the HTTP request URI (e.g., <code>"foo=bar&baz=quux"</code>). <!--The string must not be percent-decoded.-->
- </td>
- </tr>
- <tr>
- <td>
- <code>"owin.RequestHeaders"</code>
- </td>
- <td>
- An instance of <code>IDictionary&lt;string, string&gt;</code> which represents the HTTP headers present in the request (the <em>request header dictionary</em>); see <a href="#Headers">Headers</a>.
- </td>
- </tr>
- <tr>
- <td>
- <code>"owin.RequestBody"</code>
- </td>
- <td>
- An instance of the body delegate representing the body of the request. May be <code>null</code>.
- </td>
- </tr>
- <tr>
- <td>
- <code>"owin.BaseUri"</code>
- </td>
- <td>
- A <code>string</code> containing the portion of the request URI's path corresponding to the "root" of the application delegate; see <a href="#Paths">Paths</a>. <!-- The value must be percent-decoded; see <a href="http://tools.ietf.org/html/rfc3986#section-2.1">RFC 3986</a>. -->
- </td>
- </tr>
- <!--tr>
- <td>
- <code>"owin.BaseUriRaw"</code>
- </td>
- <td>
- The same value as <code>"owin.BaseUri"</code>, but not percent-decoded.
- </td>
- </tr-->
- <tr>
- <td>
- <code>"owin.Version"</code>
- </td>
- <td>
- The string <code>"1.0"</code> indicating OWIN version 1.0.
- </td>
- </tr>
-</table>
-
-
-</div>
-
-<div class="notes">
-<p>In addition to these keys, the host, application, or user may add arbitrary data associated with the request to the environment dictionary.</p>
-</div>
-
-<a name="ResponseCallback"></a>
-<h3>Response Callback</h3>
-
-<p>The response callback of the application delegate takes three arguments. The first is a <code>string</code> object representing the response status; the second is an instance of <code>IDictionary&lt;string, string&gt;</code> representing the response headers; the third is a body delegate representing the response body. These arguments together represent an HTTP response generated by an application.</p>
-
-<div class="normative">
-<ul>
- <li>The first argument to the response callback must be a <code>string</code> which contains the integer status of the response followed by a space and a reason phrase without a newline (e.g., <code>"200 OK"</code>). All characters in the status string provided by an application should be within the ASCII codepage.</li>
- <li>The second argument to the response callback must be a dictionary representing the headers to be sent with the request (the <em>response header dictionary</em>). See <a href="#Headers">Headers</a>.
- </li>
- <li>
- The third argument must be a body delegate representing the response body, or null.
- </li>
- </ul>
-</div>
-
-<a name="Headers"></a>
-<h3>Headers</h3>
-<p>
- The headers of HTTP messages are represented by objects of type <code>IDictionary&lt;string, string&gt;</code>. Request headers are contained within the environment dictionary, and response headers are provided to the response callback.
-</p>
-
-<div class="normative">
- <h4>Common header dictionary requirements</h4>
-
- <ul>
- <li>The dictionary must be mutable.</li>
- <li>Keys must be HTTP field-names without <code>':'</code> or whitespace.</li>
- <li>Keys must be case-insensitive.</li>
- <li>All characters in key and value strings should be within the ASCII codepage.</li>
- </ul>
-</div>
-
-<p>The requirements below are predicated on <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2">RFC 2616 section 4.2</a>.</p>
-
-<div class="normative">
-
- <h4>Request header dictionary requirements</h4>
-
- <ul>
- <li>If a field-value in a request received by a host contains linear whitespace (as defined by <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2">RFC 2616 section 2.2</a>), the host must collapse it to a single space (<code>'&nbsp;'</code>) in the corresponding dictionary value string.</li>
- <li>If a given field-name appears multiple times in a request received by a host, the host must collapse the corresponding field-values into a single dictionary string value, with the field-values delimited by a comma (<code>','</code>), preserving the order in which the field-values appeared in the original request.</li>
- <li>Hosts must not generate request header dictionaries whose values start or end with a comma, contain adjacent commas, or are null, empty, or consist entirely of linear whitespace.</li>
- </ul>
-
-
- <h4>Response header dictionary requirements</h4>
-
- <ul>
- <li>The application must encode or strip all <code>'\r'</code> and <code>'\n'</code> characters from header value data.</li>
- <li>The application must use the token <code>"\r\n"</code> to delimit values that are required to be sent as separate response headers of the same name (as in the case of <code>Set-Cookie</code>).</li>
- <li>Applications must not generate response header dictionaries whose values start or end with <code>"\r\n"</code>, contain adjacent <code>"\r\n"</code> delimiters, or are null, empty, or consist entirely of linear whitespace (as defined by <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2">RFC 2616 section 2.2</a>).</li>
-
- </ul>
-</div>
-
-<a name="BodyDelegate"></a>
-<h3>Body Delegate</h3>
-
-<p>The <em>body delegate</em> is the mechanism which transfers entity data between host and application. It is used for both request and response entities in OWIN. Code sending data using the delegate is called the "producer", and code receiving data using the delegate is called the "consumer". In the context of a request, the host plays the role of producer; in the context of a response, the application plays the role of producer.</p>
-
-<p>An instance of the delegate is implemented by a producer; a consumer invokes the delegate and provides it on-next, on-error, and on-complete callbacks. The return value of the body delegate is a cancellation delegate, which allows the consumer to instruct the producer not to produce any further values.</p>
-
-<p>The body delegate is equivalent to <code>IObserver</code>/<code>IObservable</code>, except for a modified on-next callback signature. In addition to taking a data value parameter, the on-next callback takes a continuation parameter, and returns a boolean value indicating whether or not it will invoke the continuation.
-
-<pre><code>Func&lt;
-
- // on next
- Func&lt;
- ArraySegment&lt;byte&gt;, // data
- Action, // continuation
- bool // will invoke continuation
- &gt;,
-
- // on error
- Action&lt;Exception&gt;,
-
- // on complete
- Action,
-
- // cancel
- Action
-&gt;</code></pre>
-
-<p>The signature of the on-next callback allows the consumer to instruct the producer to "back off" and not produce values for a time (specifically, until the consumer invokes the continuation). Without this backpressure mechanism, a producer could potentially produce values faster than a consumer could process them without buffering, and the buffer could grow unbounded.</p>
-
-<div class="normative">
-<ul>
- <li>If the producer provides a null continuation to the on-next callback, the consumer must return false.</li>
- <li>If the producer provides a non-null continuation to the on-next callback, the consumer may return true or false.
- <li>The consumer returns true from the on-next callback if and only if the consumer will eventually invoke the continuation. The consumer must not invoke the continuation in a manner such that the on-next callback which provided the continuation is on the call stack when the continuation is invoked.</li>
- <li>The consumer returns false from the on-next callback if and only if the consumer will never invoke continuation.</li>
- </li>
- <li>If the consumer returns true from the on-next callback, the producer must not invoke the consumer's on-next, on-error, or on-complete callbacks until the consumer invokes the continuation provided by the producer.</li>
- <li>The producer must signal the end of the sequence of values by invoking either the on-complete callback or the on-error callback. After invoking the on-complete callback or on-error callback, the producer must not subsequently invoke any of the consumer's callbacks.</li>
-</ul>
-</div>
-<div class="notes">
- <p>In general, a consumer should not invoke a body delegate more than once. While a "repeatable" producer is possible, consumers should not assume that a producer is repeatable and producers may not support repeatability.</li>
-
- <p>Instances of <code>ArraySegment&lt;byte&gt;</code> provided to consumers should be considered internal to the producer implementation and are guaranteed to be valid only for the duration of the on-next callback. Once the on-next callback returns, the <code>ArraySegment&lt;byte&gt;</code> may be invalid. If a consumer wishes to retain the data it should copy it out of the buffer before the on-next callback returns.</p>
-</div>
-
-<a name="Paths"></a>
-<h2>Paths</h2>
-
-<p>Hosts may have the ability to map application objects to some base path. For example, a host might have an application delegate configured to respond to requests beginning with <code>"/my-app"</code>, in which case it should set the value of <code>"owin.BaseUri"</code> in the environment dictionary to <code>"/my-app"</code>. If this host receives a request for <code>"/my-app/foo"</code>, the <code>owin.RequestUri</code> value of the environment dictionary provided to the application configured to respond at <code>"/my-app"</code> should be <code>"/foo"</code>.</p>
-
-<div class="normative">
-<ul>
- <li>The value of the <code>"owin.BaseUri"</code> environment dictionary key may be an empty string and must not end with a trailing slash</li>
- <li>The value of the <code>"owin.RequestUri"</code> environment dictionary key must not be an empty string and must start with a slash.</li>
-</ul>
-</div>
-
-
-<a name="ErrorHandling"></a>
-<h2>Error Handling</h2>
-
-<a name="ApplicationErrors"></a>
-<h3>Application Errors</h3>
-
-<p>An application may generate an exception in the following places:</p>
-
-<ul>
- <li>Thrown from an invocation of the application delegate.</li>
- <li>Provided to the error callback of the application delegate.</li>
- <li>Thrown from an invocation of the on-next, on-error, or on-complete callbacks provided to the request body delegate.</li>
- <li>Thrown from an invocation of the response body delegate.</li>
- <li>Provided to the on-error callback of the response body delegate.</li>
- <li>Thrown from an invocation of the continuation provided to the on-next callback of the response body delegate.</li>
- <li>Thrown from an invocation of the cancellation delegate returned by the response body delegate.</li>
-</ul>
-
-<p>An application should attempt to trap its own internal errors and generate an appropriate (possibly 500-level) response rather than propagating an exception up to the host.</p>
-
-<p>After an application provides a response, if the response body delegate is non-null, the host should wait to receive least one on-next callback from the the response body delegate before writing the response headers to the underlying transport. In this way, if instead of an on-next callback the host gets an on-error callback, the host will be able to generate a 500-level response. If the host gets an on-next callback first, it can safely assume that the application has caught as many of its internal errors as possible; the host can begin the response without further buffering. If an on-error callback is subsequently received, the host may write a textual description of the error to the underlying transport, and/or close the connection.</p>
-
-<a name="HostErrors"></a>
-<h3>Host Errors</h3>
-
-<p>A host may generate exceptions in the following places:</p>
-
-<ul>
- <li>Thrown from an invocation of the request body delegate.</li>
- <li>Provided to the on-error callback of the request body delegate.</li>
-</ul>
-
-<p>An exception generated in either of these places may indicate that the client has closed or dropped the connection, or another transport-layer error has occurred.
-
-<div class="normative">
- <p>If an application receives an error from a host, it must propagate it back to the host through one of the sites described in <a href="#ApplicationErrors">Application Errors</a>.</p>
-</div>
-
-<p>There are several other points where an application might call into the host but cannot meaningfully handle an exception from thrown from the call.<p>
-
-<div class="notes">
- <p>A host should not generate exceptions in the following places:</p>
- <ul>
- <li>Thrown from an invocation of the response callback provided to the application delegate.</li>
- <li>Thrown from an invocation of the error callback provided to the application delegate.</li>
- <li>Thrown from an invocation of the continuation provided to the on-next callback of the request body delegate.</li>
- <li>Thrown from an invocation of the cancellation delegate returned by the request body delegate.</li>
- <li>Thrown from the on-next, on-error, or on-completed callbacks provided to the response body delegate.</li>
- </ul>
-</div>
-
-</body>
-</html>
Please sign in to comment.
Something went wrong with that request. Please try again.