Added the XrdsPublisher ASP.NET control.
[dotnetoauth.git] / src / DotNetOpenAuth / Messaging / DirectWebResponse.cs
blob11e1f75062aec7e9654429d95497fad1ccbf5eef
1 //-----------------------------------------------------------------------
2 // <copyright file="DirectWebResponse.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.Diagnostics;
10 using System.Diagnostics.CodeAnalysis;
11 using System.Globalization;
12 using System.IO;
13 using System.Net;
14 using System.Net.Mime;
15 using System.Text;
17 /// <summary>
18 /// Details on the response from a direct web request to a remote party.
19 /// </summary>
20 public abstract class DirectWebResponse : IDisposable {
21 /// <summary>
22 /// The encoding to use in reading a response that does not declare its own content encoding.
23 /// </summary>
24 private const string DefaultContentEncoding = "ISO-8859-1";
26 /// <summary>
27 /// Initializes a new instance of the <see cref="DirectWebResponse"/> class.
28 /// </summary>
29 protected internal DirectWebResponse() {
30 this.Status = HttpStatusCode.OK;
31 this.Headers = new WebHeaderCollection();
34 /// <summary>
35 /// Initializes a new instance of the <see cref="DirectWebResponse"/> class.
36 /// </summary>
37 /// <param name="requestUri">The original request URI.</param>
38 /// <param name="response">The response to initialize from. The network stream is used by this class directly.</param>
39 protected DirectWebResponse(Uri requestUri, HttpWebResponse response) {
40 ErrorUtilities.VerifyArgumentNotNull(requestUri, "requestUri");
41 ErrorUtilities.VerifyArgumentNotNull(response, "response");
43 this.RequestUri = requestUri;
44 if (!string.IsNullOrEmpty(response.ContentType)) {
45 this.ContentType = new ContentType(response.ContentType);
47 this.ContentEncoding = string.IsNullOrEmpty(response.ContentEncoding) ? DefaultContentEncoding : response.ContentEncoding;
48 this.FinalUri = response.ResponseUri;
49 this.Status = response.StatusCode;
50 this.Headers = response.Headers;
53 /// <summary>
54 /// Initializes a new instance of the <see cref="DirectWebResponse"/> class.
55 /// </summary>
56 /// <param name="requestUri">The request URI.</param>
57 /// <param name="responseUri">The final URI to respond to the request.</param>
58 /// <param name="headers">The headers.</param>
59 /// <param name="statusCode">The status code.</param>
60 /// <param name="contentType">Type of the content.</param>
61 /// <param name="contentEncoding">The content encoding.</param>
62 protected DirectWebResponse(Uri requestUri, Uri responseUri, WebHeaderCollection headers, HttpStatusCode statusCode, string contentType, string contentEncoding) {
63 ErrorUtilities.VerifyArgumentNotNull(requestUri, "requestUri");
64 this.RequestUri = requestUri;
65 this.Status = statusCode;
66 if (!string.IsNullOrEmpty(contentType)) {
67 this.ContentType = new ContentType(contentType);
69 this.ContentEncoding = string.IsNullOrEmpty(contentEncoding) ? DefaultContentEncoding : contentEncoding;
70 this.Headers = headers;
71 this.FinalUri = responseUri;
74 /// <summary>
75 /// Gets the type of the content.
76 /// </summary>
77 public ContentType ContentType { get; private set; }
79 /// <summary>
80 /// Gets the content encoding.
81 /// </summary>
82 public string ContentEncoding { get; private set; }
84 /// <summary>
85 /// Gets the URI of the initial request.
86 /// </summary>
87 public Uri RequestUri { get; private set; }
89 /// <summary>
90 /// Gets the URI that finally responded to the request.
91 /// </summary>
92 /// <remarks>
93 /// This can be different from the <see cref="RequestUri"/> in cases of
94 /// redirection during the request.
95 /// </remarks>
96 public Uri FinalUri { get; private set; }
98 /// <summary>
99 /// Gets the headers that must be included in the response to the user agent.
100 /// </summary>
101 /// <remarks>
102 /// The headers in this collection are not meant to be a comprehensive list
103 /// of exactly what should be sent, but are meant to augment whatever headers
104 /// are generally included in a typical response.
105 /// </remarks>
106 public WebHeaderCollection Headers { get; internal set; }
108 /// <summary>
109 /// Gets the HTTP status code to use in the HTTP response.
110 /// </summary>
111 public HttpStatusCode Status { get; internal set; }
113 /// <summary>
114 /// Gets the body of the HTTP response.
115 /// </summary>
116 public abstract Stream ResponseStream { get; }
118 /// <summary>
119 /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
120 /// </summary>
121 /// <returns>
122 /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
123 /// </returns>
124 public override string ToString() {
125 StringBuilder sb = new StringBuilder();
126 sb.AppendLine(string.Format(CultureInfo.CurrentCulture, "RequestUri = {0}", this.RequestUri));
127 sb.AppendLine(string.Format(CultureInfo.CurrentCulture, "ResponseUri = {0}", this.FinalUri));
128 sb.AppendLine(string.Format(CultureInfo.CurrentCulture, "StatusCode = {0}", this.Status));
129 sb.AppendLine(string.Format(CultureInfo.CurrentCulture, "ContentType = {0}", this.ContentType));
130 sb.AppendLine(string.Format(CultureInfo.CurrentCulture, "ContentEncoding = {0}", this.ContentEncoding));
131 sb.AppendLine("Headers:");
132 foreach (string header in this.Headers) {
133 sb.AppendLine(string.Format(CultureInfo.CurrentCulture, "\t{0}: {1}", header, this.Headers[header]));
136 return sb.ToString();
139 /// <summary>
140 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
141 /// </summary>
142 public void Dispose() {
143 this.Dispose(true);
144 GC.SuppressFinalize(this);
147 /// <summary>
148 /// Creates a text reader for the response stream.
149 /// </summary>
150 /// <returns>The text reader, initialized for the proper encoding.</returns>
151 [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Costly operation")]
152 public abstract StreamReader GetResponseReader();
154 /// <summary>
155 /// Gets an offline snapshot version of this instance.
156 /// </summary>
157 /// <param name="maximumBytesToCache">The maximum bytes from the response stream to cache.</param>
158 /// <returns>A snapshot version of this instance.</returns>
159 /// <remarks>
160 /// If this instance is a <see cref="NetworkDirectWebResponse"/> creating a snapshot
161 /// will automatically close and dispose of the underlying response stream.
162 /// If this instance is a <see cref="CachedDirectWebResponse"/>, the result will
163 /// be the self same instance.
164 /// </remarks>
165 internal abstract CachedDirectWebResponse GetSnapshot(int maximumBytesToCache);
167 /// <summary>
168 /// Releases unmanaged and - optionally - managed resources
169 /// </summary>
170 /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
171 protected virtual void Dispose(bool disposing) {
172 if (disposing) {
173 Stream responseStream = this.ResponseStream;
174 if (responseStream != null) {
175 responseStream.Dispose();