1
//-----------------------------------------------------------------------
2 // <copyright file="DirectWebResponse.cs" company="Andrew Arnott">
3 // Copyright (c) Andrew Arnott. All rights reserved.
5 //-----------------------------------------------------------------------
7 namespace DotNetOpenAuth
.Messaging
{
9 using System
.Diagnostics
;
10 using System
.Diagnostics
.CodeAnalysis
;
11 using System
.Globalization
;
14 using System
.Net
.Mime
;
18 /// Details on the response from a direct web request to a remote party.
20 public abstract class DirectWebResponse
: IDisposable
{
22 /// The encoding to use in reading a response that does not declare its own content encoding.
24 private const string DefaultContentEncoding
= "ISO-8859-1";
27 /// Initializes a new instance of the <see cref="DirectWebResponse"/> class.
29 protected internal DirectWebResponse() {
30 this.Status
= HttpStatusCode
.OK
;
31 this.Headers
= new WebHeaderCollection();
35 /// Initializes a new instance of the <see cref="DirectWebResponse"/> class.
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
;
54 /// Initializes a new instance of the <see cref="DirectWebResponse"/> class.
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
;
75 /// Gets the type of the content.
77 public ContentType ContentType { get; private set; }
80 /// Gets the content encoding.
82 public string ContentEncoding { get; private set; }
85 /// Gets the URI of the initial request.
87 public Uri RequestUri { get; private set; }
90 /// Gets the URI that finally responded to the request.
93 /// This can be different from the <see cref="RequestUri"/> in cases of
94 /// redirection during the request.
96 public Uri FinalUri { get; private set; }
99 /// Gets the headers that must be included in the response to the user agent.
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.
106 public WebHeaderCollection Headers { get; internal set; }
109 /// Gets the HTTP status code to use in the HTTP response.
111 public HttpStatusCode Status { get; internal set; }
114 /// Gets the body of the HTTP response.
116 public abstract Stream ResponseStream { get; }
119 /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
122 /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
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();
140 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
142 public void Dispose() {
144 GC
.SuppressFinalize(this);
148 /// Creates a text reader for the response stream.
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();
155 /// Gets an offline snapshot version of this instance.
157 /// <param name="maximumBytesToCache">The maximum bytes from the response stream to cache.</param>
158 /// <returns>A snapshot version of this instance.</returns>
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.
165 internal abstract CachedDirectWebResponse
GetSnapshot(int maximumBytesToCache
);
168 /// Releases unmanaged and - optionally - managed resources
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
) {
173 Stream responseStream
= this.ResponseStream
;
174 if (responseStream
!= null) {
175 responseStream
.Dispose();