5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2010 Novell, Inc. http://www.novell.com
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Collections.Generic;
30 using System.Collections.Specialized;
31 using System.Globalization;
34 using System.Security.Principal;
35 using System.ServiceModel;
37 using System.Threading;
40 namespace System.ServiceModel.Channels.Http
44 abstract class HttpContextInfo
46 public abstract HttpRequestInfo Request { get; }
47 public abstract HttpResponseInfo Response { get; }
49 public abstract string User { get; }
50 public abstract string Password { get; }
51 public abstract void ReturnUnauthorized ();
65 protected virtual void OnContextClosed ()
70 class HttpStandaloneContextInfo : HttpContextInfo
72 public HttpStandaloneContextInfo (HttpListenerContext ctx)
75 request = new HttpStandaloneRequestInfo (ctx.Request);
76 response = new HttpStandaloneResponseInfo (ctx.Response);
79 HttpListenerContext ctx;
80 HttpStandaloneRequestInfo request;
81 HttpStandaloneResponseInfo response;
83 public HttpListenerContext Source {
87 public override HttpRequestInfo Request {
88 get { return request; }
91 public override HttpResponseInfo Response {
92 get { return response; }
95 public override string User {
96 get { return ctx.User != null ? ((HttpListenerBasicIdentity) ctx.User.Identity).Name : null; }
99 public override string Password {
100 get { return ctx.User != null ? ((HttpListenerBasicIdentity) ctx.User.Identity).Password : null; }
103 public override void ReturnUnauthorized ()
105 ctx.Response.StatusCode = 401;
109 class AspNetHttpContextInfo : HttpContextInfo
111 public AspNetHttpContextInfo (SvcHttpHandler handler, HttpContext ctx)
114 this.handler = handler;
115 this.request = new AspNetHttpRequestInfo (ctx.Request);
116 this.response = new AspNetHttpResponseInfo (ctx.Response);
120 SvcHttpHandler handler;
121 AspNetHttpRequestInfo request;
122 AspNetHttpResponseInfo response;
124 public HttpContext Source {
128 public override HttpRequestInfo Request {
129 get { return request; }
132 public override HttpResponseInfo Response {
133 get { return response; }
136 public override string User {
137 get { return ctx.User != null ? ((GenericIdentity) ctx.User.Identity).Name : null; }
140 // FIXME: how to acquire this?
141 public override string Password {
145 public override void ReturnUnauthorized ()
147 ctx.Response.StatusCode = 401;
150 protected override void OnContextClosed ()
152 handler.EndHttpRequest (ctx);
158 abstract class HttpRequestInfo
160 public abstract long ContentLength64 { get; }
161 public abstract NameValueCollection QueryString { get; }
162 public abstract NameValueCollection Headers { get; }
163 public abstract Uri Url { get; }
164 public abstract string ContentType { get; }
165 public abstract string HttpMethod { get; }
166 public abstract Stream InputStream { get; }
169 class HttpStandaloneRequestInfo : HttpRequestInfo
171 public HttpStandaloneRequestInfo (HttpListenerRequest request)
176 HttpListenerRequest req;
178 public override long ContentLength64 {
179 get { return req.ContentLength64; }
181 public override NameValueCollection QueryString {
182 get { return req.QueryString; }
184 public override NameValueCollection Headers {
185 get { return req.Headers; }
187 public override Uri Url {
188 get { return req.Url; }
190 public override string ContentType {
191 get { return req.ContentType; }
193 public override string HttpMethod {
194 get { return req.HttpMethod; }
196 public override Stream InputStream {
197 get { return req.InputStream; }
201 class AspNetHttpRequestInfo : HttpRequestInfo
203 public AspNetHttpRequestInfo (HttpRequest request)
210 public override long ContentLength64 {
211 get { return req.ContentLength; }
213 public override NameValueCollection QueryString {
214 get { return req.QueryString; }
216 public override NameValueCollection Headers {
217 get { return req.Headers; }
219 public override Uri Url {
220 get { return req.Url; }
222 public override string ContentType {
223 get { return req.ContentType; }
225 public override string HttpMethod {
226 get { return req.HttpMethod; }
228 public override Stream InputStream {
229 get { return req.InputStream; }
235 abstract class HttpResponseInfo
237 public abstract string ContentType { get; set; }
238 public abstract NameValueCollection Headers { get; }
239 public abstract Stream OutputStream { get; }
240 public abstract int StatusCode { get; set; }
241 public abstract string StatusDescription { get; set; }
242 public abstract void Abort ();
243 public abstract void Close ();
244 public abstract void SetLength (long value);
246 public virtual bool SuppressContent { get; set; }
249 class HttpStandaloneResponseInfo : HttpResponseInfo
251 public HttpStandaloneResponseInfo (HttpListenerResponse response)
256 HttpListenerResponse res;
258 public override string ContentType {
259 get { return res.ContentType; }
260 set { res.ContentType = value; }
262 public override NameValueCollection Headers {
263 get { return res.Headers; }
265 public override int StatusCode {
266 get { return res.StatusCode; }
267 set { res.StatusCode = value; }
269 public override string StatusDescription {
270 get { return res.StatusDescription; }
271 set { res.StatusDescription = value; }
273 public override Stream OutputStream {
274 get { return res.OutputStream; }
277 public override void Abort ()
282 public override void Close ()
287 public override void SetLength (long value)
289 res.ContentLength64 = value;
293 class AspNetHttpResponseInfo : HttpResponseInfo
295 public AspNetHttpResponseInfo (HttpResponse response)
302 public override bool SuppressContent {
303 get { return res.SuppressContent; }
304 set { res.SuppressContent = value; }
306 public override string ContentType {
307 get { return res.ContentType; }
308 set { res.ContentType = value; }
310 public override NameValueCollection Headers {
311 get { return res.Headers; }
313 public override int StatusCode {
314 get { return res.StatusCode; }
315 set { res.StatusCode = value; }
318 public override string StatusDescription {
319 get { return res.StatusDescription; }
320 set { res.StatusDescription = value; }
322 public override Stream OutputStream {
323 get { return res.OutputStream; }
326 public override void Abort ()
331 public override void Close ()
333 // We must not close the response here, as everything is taking place in the
334 // HttpApplication's pipeline context and the output is sent to the client
335 // _after_ we leave this method. Closing the response here will stop any
336 // output from reaching the client.
339 public override void SetLength (long value)
341 res.AddHeader ("Content-Length", value.ToString (CultureInfo.InvariantCulture));