Removed old .refresh file.
[dotnetoauth.git] / src / DotNetOpenAuth / Messaging / HttpRequestInfo.cs
blobcb446e76d1586d549e4e7b4007c47e79e38b9a40
1 //-----------------------------------------------------------------------
2 // <copyright file="HttpRequestInfo.cs" company="Andrew Arnott">
3 // Copyright (c) Andrew Arnott. All rights reserved.
4 // </copyright>
5 //-----------------------------------------------------------------------
7 namespace DotNetOpenAuth.Messaging {
8 using System;
9 using System.Collections.Specialized;
10 using System.Diagnostics;
11 using System.IO;
12 using System.Net;
13 using System.ServiceModel.Channels;
14 using System.Web;
16 /// <summary>
17 /// A property store of details of an incoming HTTP request.
18 /// </summary>
19 /// <remarks>
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
22 /// of our one.
23 /// </remarks>
24 public class HttpRequestInfo {
25 /// <summary>
26 /// The key/value pairs found in the entity of a POST request.
27 /// </summary>
28 private NameValueCollection form;
30 /// <summary>
31 /// The key/value pairs found in the querystring of the incoming request.
32 /// </summary>
33 private NameValueCollection queryString;
35 /// <summary>
36 /// Initializes a new instance of the <see cref="HttpRequestInfo"/> class.
37 /// </summary>
38 internal HttpRequestInfo() {
39 this.HttpMethod = "GET";
42 /// <summary>
43 /// Initializes a new instance of the <see cref="HttpRequestInfo"/> class.
44 /// </summary>
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
59 // these as well.
60 this.form = request.Form;
61 this.queryString = request.QueryString;
64 /// <summary>
65 /// Initializes a new instance of the <see cref="HttpRequestInfo"/> class.
66 /// </summary>
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;
79 /// <summary>
80 /// Initializes a new instance of the <see cref="HttpRequestInfo"/> class.
81 /// </summary>
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;
90 /// <summary>
91 /// Initializes a new instance of the <see cref="HttpRequestInfo"/> class.
92 /// </summary>
93 /// <param name="message">The message being passed in through a mock transport.</param>
94 internal HttpRequestInfo(IDirectedProtocolMessage message) {
95 this.Message = message;
98 /// <summary>
99 /// Gets or sets the message that is being sent over a mock transport (for testing).
100 /// </summary>
101 internal IDirectedProtocolMessage Message { get; set; }
103 /// <summary>
104 /// Gets or sets the verb in the request (i.e. GET, POST, etc.)
105 /// </summary>
106 internal string HttpMethod { get; set; }
108 /// <summary>
109 /// Gets or sets the entire URL of the request.
110 /// </summary>
111 internal Uri Url { get; set; }
113 /// <summary>
114 /// Gets the query part of the URL (The ? and everything after it).
115 /// </summary>
116 internal string Query {
117 get { return this.Url != null ? this.Url.Query : null; }
120 /// <summary>
121 /// Gets or sets the collection of headers that came in with the request.
122 /// </summary>
123 internal WebHeaderCollection Headers { get; set; }
125 /// <summary>
126 /// Gets or sets the entity, or body of the request, if any.
127 /// </summary>
128 internal Stream InputStream { get; set; }
130 /// <summary>
131 /// Gets the key/value pairs found in the entity of a POST request.
132 /// </summary>
133 internal NameValueCollection Form {
134 get {
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);
143 } else {
144 this.form = new NameValueCollection();
148 return this.form;
152 /// <summary>
153 /// Gets the key/value pairs found in the querystring of the incoming request.
154 /// </summary>
155 internal NameValueCollection QueryString {
156 get {
157 if (this.queryString == null) {
158 this.queryString = HttpUtility.ParseQueryString(this.Query);
161 return this.queryString;
165 /// <summary>
166 /// Converts a NameValueCollection to a WebHeaderCollection.
167 /// </summary>
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]);
178 return headers;