3.1. Application Delegate
3.4. Request Body
3.5. Response Body
3.6. Request Lifetime
5.1. URI Scheme
6.1. Application Errors
6.2. Server Errors
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.
OWIN is defined in terms of a delegate structure. There is no assembly called OWIN.dll or similar. Implementing either the host or application side the OWIN spec does not introduce a dependency to a project.
In this document, the C#
syntax is used to notate some delegate structures. 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.
This document refers to the following software actors:
· Server – The HTTP server that directly communicates with the client and then uses OWIN semantics to process requests. Servers may require an adapter layer that converts to OWIN semantics.
· Web Framework – A self-contained component on top of OWIN exposing its own object model or API that applications may use to facilitate request processing. Web Frameworks may require an adapter layer that converts from OWIN semantics.
· Web Application – A specific application, possibly built on top of a Web Framework, which is run using OWIN compatible Servers.
· Middleware – Pass through components that form a pipeline between a server and application to inspect, route, or modify request and response messages for a specific purpose.
· Host – The process an application and server execute inside of, primarily responsible for application startup. Some Servers are also Hosts.
Broadly speaking, a server invokes an application (providing as arguments an environment dictionary with request and response headers and bodies); an application either populates a response or indicates an error.
The primary interface in OWIN is called the application delegate or AppFunc. An application delegate takes the IDictionary<string, object> environment and returns a Task when it has finished processing.
using AppFunc = Func<
IDictionary<string, object>, // Environment
Task>; // Done
The Environment dictionary stores information about the request, the response, and any relevant server state. The server is responsible for providing body streams and header collections for both the request and response in the initial call. The application then populates the appropriate fields with response data, writes the response body, and returns when done.
The headers of HTTP
request and response messages are represented by objects of type
IDictionary<string, string>. The requirements below are
predicated on RFC 2616
If the request indicates there is an associated body the server SHOULD provide a Stream in the “owin.RequestBody” key to access the body data. Stream.Null MAY be used as a placeholder if there is no request body data expected. If the request Expect header indicates the client requests a 100 Continue, it is up to the server to provide this. The application MUST NOT set “owin.ResponseStatusCode” to 100. 100 Continue is only an intermediate response and using it would prevent the application from providing a final response (e.g. 200 OK). The server SHOULD send the 100 Continue on behalf of the application if the application starts reading from the stream before data starts arriving.
The server provides a response body Stream with the “owin.ResponseBody” key in the initial environment dictionary. The headers, status code, reason phrase, etc., can be modified up until the first write to the response body stream. Upon first write, the server validates and sends the headers. Applications MAY choose to buffer response data to delay the header finalization.
The full scope or lifetime of a request is limited by the several factors, including the client, server, and application delegate. In the simplest scenario a request’s lifetime ends when the application delegate has completed and the server gracefully ends the request. Failures at any level may cause the request to terminate prematurely, or may be handled internally and allow the request to continue.
The “owin.CallCancelled” key is associated with a CancellationToken that the server uses to signal if the request has been aborted. This SHOULD be triggered if the request becomes faulted before the AppFunc Task is completed. It MAY be triggered at any point at the providers discretion. Middleware MAY replace this token with their own to provide added granularity or functionality, but they SHOULD chain their new token with the one originally provided to them.
When the host process starts there are a number of steps it goes through to set up the application.
1. The host creates a Properties IDictionary<string, object> and populates any startup data or capabilities provided by the host.
2. The host selects which server will be used and provides it with the Properties collection so it can similarly announce any capabilities.
3. The host locates the application setup code and invokes it with the Properties collection.
4. The application reads and/or sets configuration in the Properties collection, constructs the desired request processing pipeline, and returns the resulting application delegate.
5. The host invokes the server startup code with the given application delegate and the Properties dictionary. The server finishes configuring itself, starts accepting requests, and invokes the application delegate to process those requests.
The Properties dictionary may be used to read or set any configuration parameters supported by the host, server, middleware, or application.
Applications often require the ability to reconstruct the complete URI of a request. This process cannot be perfect since HTTP clients do not usually transmit the complete URI which they are requesting, but OWIN makes provisions for the purpose of reconstructing the approximate URI of a request.
This information is usually not transmitted by an HTTP client and depending on network configuration it may not be possible for an OWIN server to determine a correct value. In these cases, the server may have to manually configure or compute a value.
In the context of an HTTP/1.1 request, the name of the server to which the client is making a request is usually indicated in the Host header field-value of the request, although it might be specified using an absolute Request-URI (see RFC 2616, sections 5.1.2, 220.127.116.11).
Servers may have the
ability to map application delegates to some base path. For example, a server
might have an application delegate configured to respond to requests beginning
"/my-app", in which case it should set the
"owin.RequestPathBase" in the environment dictionary to
"/my-app". If this server receives a
"/my-app/foo", the “
owin.RequestPath” value of the environment
dictionary provided to the application configured to respond at
"/my-app" should be
The following algorithm can be used to approximate the complete URI of the current request:
var uri =
if (Environment["owin.RequestQueryString"] != "")
uri += "?" + (string)Environment["owin.RequestQueryString"];
The result of this algorithm may not be identical to the URI the client used to make the request; for example, the server may have done some rewriting to canonicalize the request. Further, it is subject to the caveats described in the URI Scheme and Hostname sections above.
A URI uses percent
encoding to transport characters outside its normally allowed character rules (RFC 3986 section 2).
Percent-encoding is used to express the underlying octets present in a URI
component, whose octets are interpreted via UTF-8 encoding. Most web server
implementations will perform percent-decoding on paths in order to perform
request routing (as they rightly may, see: RFC 2616 section 5.1.2,
and OWIN follows this precedent. The request query string in OWIN is presented
in its percent-encoded form; a percent-decoded query string could contain
'=' characters, which would render
the string unparseable.
While there are standard exceptions such as ArgumentException and IOException that may be expected in normal request processing scenarios, handling only such exceptions is insufficient when building a robust server or application. If a server wishes to be robust it SHOULD consistently address all exception types thrown or returned from the application delegate or body delegate. The handling mechanism (e.g. logging, crashing and restarting, swallowing, etc.) is up to the server and host process.
An application may generate an exception in the following places:
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 server.
After an application provides a response, the server SHOULD wait to receive at least one write from the response Stream before writing the response headers to the underlying transport. In this way, if instead of a write to the Stream the server gets an exception from the application delegate Task, the server will still be able to generate a 500-level response. If the server gets a write to the Stream first, it can safely assume that the application has caught as many of its internal errors as possible; the server can begin sending the response. If an exception is subsequently received, the server MAY handle it as it sees fit (e.g. logging, write a textual description of the error to the underlying transport, and/or close the connection).
When a server encounters errors during a request’s lifetime it SHOULD signal the CancellationToken it provided in “owin.CallCancelled”. The server MAY then take any necessary actions to terminate the request, but it SHOULD be tolerant of completion delays of the application delegate.
Future updates to this standard may contain breaking changes (e.g. signature changes, key additions or modifications, etc.) or non-breaking additions. While addressing specific changes is the responsibility of later versions of the standard, here are initial guidelines for expected changes:
· This standard uses Semantic Versioning as described at http://semver.org/ (e.g. Major.Minor.Patch).
· Breaking changes to the API signatures or existing keys will require incrementing the major version number (e.g. OWIN 2.0)
· Adding new keys or delegates in a backwards compatible way only requires incrementing the minor version number (e.g. OWIN 1.1).
· Making corrections and clarifications to the document alone only requires incrementing the patch version number and last modified date (e.g. OWIN 1.0.1).
· The “owin.Version” key in the startup Properties and request Environment dictionaries indicates the latest version of the standard implemented by the server and may be used to dynamically adjust behaviors of applications.
· All implementers SHOULD clearly document the full version number(s) of the OWIN standard they support.
· The keys listed in CommonKeys.html are strictly optional. Additions may be made there without directly affecting the OWIN standard or version number.