summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenId/UntrustedWebResponse.cs
blob: 0834125f1a9a4043477c9cde6cdd2b4d233d2dd9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
namespace DotNetOpenId {
	using System;
	using System.Net;
	using System.Collections.Specialized;
	using System.IO;
	using System.Text;
	using System.Net.Mime;
	using System.Diagnostics;
	using System.Globalization;

	[Serializable]
	[DebuggerDisplay("{StatusCode} {ContentType.MediaType}: {ReadResponseString().Substring(4,50)}")]
	internal class UntrustedWebResponse {
		const string DefaultContentEncoding = "ISO-8859-1";
		
		public Stream ResponseStream { get; private set; }
		public HttpStatusCode StatusCode { get; private set; }
		public ContentType ContentType { get; private set; }
		public string ContentEncoding { get; private set; }
		public WebHeaderCollection Headers { get; private set; }
		public Uri RequestUri { get; private set; }
		public Uri FinalUri { get; private set; }

		public UntrustedWebResponse(Uri requestUri, Uri finalRequestUri, HttpWebResponse response, Stream responseStream) {
			if (requestUri == null) throw new ArgumentNullException("requestUri");
			if (finalRequestUri == null) throw new ArgumentNullException("finalRequestUri");
			if (response == null) throw new ArgumentNullException("response");
			if (responseStream == null) throw new ArgumentNullException("responseStream");
			this.RequestUri = requestUri;
			this.ResponseStream = responseStream;
			StatusCode = response.StatusCode;
			if (!string.IsNullOrEmpty(response.ContentType)) {
				try {
					ContentType = new ContentType(response.ContentType);
				} catch (FormatException) {
					Logger.ErrorFormat("HTTP response to {0} included an invalid Content-Type header value: {1}", response.ResponseUri.AbsoluteUri, response.ContentType);
				}
			}
			ContentEncoding = string.IsNullOrEmpty(response.ContentEncoding) ? DefaultContentEncoding : response.ContentEncoding;
			Headers = response.Headers;
			FinalUri = finalRequestUri;
		}

		/// <summary>
		/// Constructs a mock web response.
		/// </summary>
		internal UntrustedWebResponse(Uri requestUri, Uri responseUri, WebHeaderCollection headers,
			HttpStatusCode statusCode, string contentType, string contentEncoding, Stream responseStream) {
			if (requestUri == null) throw new ArgumentNullException("requestUri");
			if (responseStream == null) throw new ArgumentNullException("responseStream");
			RequestUri = requestUri;
			ResponseStream = responseStream;
			StatusCode = statusCode;
			if (!string.IsNullOrEmpty(contentType)) {
				try {
					ContentType = new ContentType(contentType);
				} catch (FormatException) {
					Logger.ErrorFormat("HTTP response to {0} included an invalid Content-Type header value: {1}", responseUri.AbsoluteUri, contentType);
				}
			}
			ContentEncoding = string.IsNullOrEmpty(contentEncoding) ? DefaultContentEncoding : contentEncoding;
			Headers = headers;
			FinalUri = responseUri;
		}

		public string ReadResponseString() {
			// We do NOT put a using clause around this or dispose of the StreamReader
			// because that would dispose of the underlying stream, preventing this
			// method from being called again.
			StreamReader sr = new StreamReader(ResponseStream, Encoding.GetEncoding(ContentEncoding));
			long oldPosition = ResponseStream.Position;
			string result = sr.ReadToEnd();
			ResponseStream.Seek(oldPosition, SeekOrigin.Begin);
			return result;
		}

		public override string ToString() {
			StringBuilder sb = new StringBuilder();
			sb.AppendLine(string.Format(CultureInfo.CurrentCulture, "RequestUri = {0}", RequestUri));
			sb.AppendLine(string.Format(CultureInfo.CurrentCulture, "ResponseUri = {0}", FinalUri));
			sb.AppendLine(string.Format(CultureInfo.CurrentCulture, "StatusCode = {0}", StatusCode));
			sb.AppendLine(string.Format(CultureInfo.CurrentCulture, "ContentType = {0}", ContentType));
			sb.AppendLine(string.Format(CultureInfo.CurrentCulture, "ContentEncoding = {0}", ContentEncoding));
			sb.AppendLine("Headers:");
			foreach (string header in Headers) {
				sb.AppendLine(string.Format(CultureInfo.CurrentCulture, "\t{0}: {1}", header, Headers[header]));
			}
			sb.AppendLine("Response:");
			sb.AppendLine(ReadResponseString());
			return sb.ToString();
		}
	}
}