1
//-----------------------------------------------------------------------
2 // <copyright file="HttpRequestInfo.cs" company="Andrew Arnott">
3 // Copyright (c) Andrew Arnott. All rights reserved.
5 //-----------------------------------------------------------------------
7 namespace DotNetOpenAuth
.Messaging
{
9 using System
.Collections
.Specialized
;
10 using System
.Diagnostics
;
13 using System
.ServiceModel
.Channels
;
17 /// A property store of details of an incoming HTTP request.
20 /// This serves a very similar purpose to <see cref="HttpRequest"/>, except that
21 /// ASP.NET does not let us fully initialize that class, so we have to write one
24 public class HttpRequestInfo
{
26 /// The key/value pairs found in the entity of a POST request.
28 private NameValueCollection form
;
31 /// The key/value pairs found in the querystring of the incoming request.
33 private NameValueCollection queryString
;
36 /// Initializes a new instance of the <see cref="HttpRequestInfo"/> class.
38 internal HttpRequestInfo() {
39 this.HttpMethod
= "GET";
43 /// Initializes a new instance of the <see cref="HttpRequestInfo"/> class.
45 /// <param name="request">The ASP.NET structure to copy from.</param>
46 internal HttpRequestInfo(HttpRequest request
) {
47 if (request
== null) {
48 throw new ArgumentNullException("request");
51 this.HttpMethod
= request
.HttpMethod
;
52 this.Url
= request
.Url
;
53 this.Headers
= GetHeaderCollection(request
.Headers
);
54 this.InputStream
= request
.InputStream
;
56 // These values would normally be calculated, but we'll reuse them from
57 // HttpRequest since they're already calculated, and there's a chance (<g>)
58 // that ASP.NET does a better job of being comprehensive about gathering
60 this.form
= request
.Form
;
61 this.queryString
= request
.QueryString
;
65 /// Initializes a new instance of the <see cref="HttpRequestInfo"/> class.
67 /// <param name="request">The WCF incoming request structure to get the HTTP information from.</param>
68 /// <param name="requestUri">The URI of the service endpoint.</param>
69 internal HttpRequestInfo(HttpRequestMessageProperty request
, Uri requestUri
) {
70 if (request
== null) {
71 throw new ArgumentNullException("request");
74 this.HttpMethod
= request
.Method
;
75 this.Headers
= request
.Headers
;
76 this.Url
= requestUri
;
80 /// Initializes a new instance of the <see cref="HttpRequestInfo"/> class.
82 /// <param name="request">The HttpWebRequest (that was never used) to copy from.</param>
83 internal HttpRequestInfo(WebRequest request
) {
84 this.HttpMethod
= request
.Method
;
85 this.Url
= request
.RequestUri
;
86 this.Headers
= GetHeaderCollection(request
.Headers
);
87 this.InputStream
= null;
91 /// Initializes a new instance of the <see cref="HttpRequestInfo"/> class.
93 /// <param name="message">The message being passed in through a mock transport.</param>
94 internal HttpRequestInfo(IDirectedProtocolMessage message
) {
95 this.Message
= message
;
99 /// Gets or sets the message that is being sent over a mock transport (for testing).
101 internal IDirectedProtocolMessage Message { get; set; }
104 /// Gets or sets the verb in the request (i.e. GET, POST, etc.)
106 internal string HttpMethod { get; set; }
109 /// Gets or sets the entire URL of the request.
111 internal Uri Url { get; set; }
114 /// Gets the query part of the URL (The ? and everything after it).
116 internal string Query
{
117 get { return this.Url != null ? this.Url.Query : null; }
121 /// Gets or sets the collection of headers that came in with the request.
123 internal WebHeaderCollection Headers { get; set; }
126 /// Gets or sets the entity, or body of the request, if any.
128 internal Stream InputStream { get; set; }
131 /// Gets the key/value pairs found in the entity of a POST request.
133 internal NameValueCollection Form
{
135 if (this.form
== null) {
136 if (this.HttpMethod
== "POST" && this.Headers
[HttpRequestHeader
.ContentType
] == "application/x-www-form-urlencoded") {
137 StreamReader reader
= new StreamReader(this.InputStream
);
138 long originalPosition
= this.InputStream
.Position
;
139 this.form
= HttpUtility
.ParseQueryString(reader
.ReadToEnd());
140 if (this.InputStream
.CanSeek
) {
141 this.InputStream
.Seek(originalPosition
, SeekOrigin
.Begin
);
144 this.form
= new NameValueCollection();
153 /// Gets the key/value pairs found in the querystring of the incoming request.
155 internal NameValueCollection QueryString
{
157 if (this.queryString
== null) {
158 this.queryString
= HttpUtility
.ParseQueryString(this.Query
);
161 return this.queryString
;
166 /// Converts a NameValueCollection to a WebHeaderCollection.
168 /// <param name="pairs">The collection a HTTP headers.</param>
169 /// <returns>A new collection of the given headers.</returns>
170 private static WebHeaderCollection
GetHeaderCollection(NameValueCollection pairs
) {
171 Debug
.Assert(pairs
!= null, "pairs == null");
173 WebHeaderCollection headers
= new WebHeaderCollection();
174 foreach (string key
in pairs
) {
175 headers
.Add(key
, pairs
[key
]);