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; }
167 public abstract string ClientIPAddress { get; }
168 public abstract int ClientPort { get; }
171 class HttpStandaloneRequestInfo : HttpRequestInfo
173 public HttpStandaloneRequestInfo (HttpListenerRequest request)
178 HttpListenerRequest req;
180 public override long ContentLength64 {
181 get { return req.ContentLength64; }
183 public override NameValueCollection QueryString {
184 get { return req.QueryString; }
186 public override NameValueCollection Headers {
187 get { return req.Headers; }
189 public override Uri Url {
190 get { return req.Url; }
192 public override string ContentType {
193 get { return req.ContentType; }
195 public override string HttpMethod {
196 get { return req.HttpMethod; }
198 public override Stream InputStream {
199 get { return req.InputStream; }
201 public override string ClientIPAddress {
202 get { return req.RemoteEndPoint.Address.ToString (); }
204 public override int ClientPort {
205 get { return req.RemoteEndPoint.Port; }
209 class AspNetHttpRequestInfo : HttpRequestInfo
211 public AspNetHttpRequestInfo (HttpRequest request)
218 public override long ContentLength64 {
219 get { return req.ContentLength; }
221 public override NameValueCollection QueryString {
222 get { return req.QueryString; }
224 public override NameValueCollection Headers {
225 get { return req.Headers; }
227 public override Uri Url {
228 get { return req.Url; }
230 public override string ContentType {
231 get { return req.ContentType; }
233 public override string HttpMethod {
234 get { return req.HttpMethod; }
236 public override Stream InputStream {
237 get { return req.InputStream; }
239 public override string ClientIPAddress {
240 get { return req.UserHostAddress; }
242 public override int ClientPort {
243 get { return -1; } // cannot retrieve
249 abstract class HttpResponseInfo
251 public abstract string ContentType { get; set; }
252 public abstract NameValueCollection Headers { get; }
253 public abstract Stream OutputStream { get; }
254 public abstract int StatusCode { get; set; }
255 public abstract string StatusDescription { get; set; }
256 public abstract void Abort ();
257 public abstract void Close ();
258 public abstract void SetLength (long value);
260 public virtual bool SuppressContent { get; set; }
263 class HttpStandaloneResponseInfo : HttpResponseInfo
265 public HttpStandaloneResponseInfo (HttpListenerResponse response)
270 HttpListenerResponse res;
272 public override string ContentType {
273 get { return res.ContentType; }
274 set { res.ContentType = value; }
276 public override NameValueCollection Headers {
277 get { return res.Headers; }
279 public override int StatusCode {
280 get { return res.StatusCode; }
281 set { res.StatusCode = value; }
283 public override string StatusDescription {
284 get { return res.StatusDescription; }
285 set { res.StatusDescription = value; }
287 public override Stream OutputStream {
288 get { return res.OutputStream; }
291 public override void Abort ()
296 public override void Close ()
301 public override void SetLength (long value)
303 res.ContentLength64 = value;
307 class AspNetHttpResponseInfo : HttpResponseInfo
309 public AspNetHttpResponseInfo (HttpResponse response)
316 public override bool SuppressContent {
317 get { return res.SuppressContent; }
318 set { res.SuppressContent = value; }
320 public override string ContentType {
321 get { return res.ContentType; }
322 set { res.ContentType = value; }
324 public override NameValueCollection Headers {
325 get { return res.Headers; }
327 public override int StatusCode {
328 get { return res.StatusCode; }
329 set { res.StatusCode = value; }
332 public override string StatusDescription {
333 get { return res.StatusDescription; }
334 set { res.StatusDescription = value; }
336 public override Stream OutputStream {
337 get { return res.OutputStream; }
340 public override void Abort ()
345 public override void Close ()
347 // We must not close the response here, as everything is taking place in the
348 // HttpApplication's pipeline context and the output is sent to the client
349 // _after_ we leave this method. Closing the response here will stop any
350 // output from reaching the client.
353 public override void SetLength (long value)
355 res.AddHeader ("Content-Length", value.ToString (CultureInfo.InvariantCulture));