2010-07-05 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels.Http / HttpContextInfo.cs
1 //
2 // HttpContextInfo.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2010 Novell, Inc.  http://www.novell.com
8 //
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:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
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.
27 //
28 using System;
29 using System.Collections.Generic;
30 using System.Collections.Specialized;
31 using System.Globalization;
32 using System.IO;
33 using System.Net;
34 using System.Security.Principal;
35 using System.ServiceModel;
36 using System.Text;
37 using System.Threading;
38 using System.Web;
39
40 namespace System.ServiceModel.Channels.Http
41 {
42         // Context
43         
44         abstract class HttpContextInfo
45         {
46                 public abstract HttpRequestInfo Request { get; }
47                 public abstract HttpResponseInfo Response { get; }
48
49                 public abstract string User { get; }
50                 public abstract string Password { get; }
51                 public abstract void ReturnUnauthorized ();
52
53                 public void Abort ()
54                 {
55                         Response.Abort ();
56                         OnContextClosed ();
57                 }
58
59                 public void Close ()
60                 {
61                         Response.Close ();
62                         OnContextClosed ();
63                 }
64                 
65                 protected virtual void OnContextClosed ()
66                 {
67                 }
68         }
69
70         class HttpStandaloneContextInfo : HttpContextInfo
71         {
72                 public HttpStandaloneContextInfo (HttpListenerContext ctx)
73                 {
74                         this.ctx = ctx;
75                         request = new HttpStandaloneRequestInfo (ctx.Request);
76                         response = new HttpStandaloneResponseInfo (ctx.Response);
77                 }
78                 
79                 HttpListenerContext ctx;
80                 HttpStandaloneRequestInfo request;
81                 HttpStandaloneResponseInfo response;
82
83                 public HttpListenerContext Source {
84                         get { return ctx; }
85                 }
86
87                 public override HttpRequestInfo Request {
88                         get { return request; }
89                 }
90
91                 public override HttpResponseInfo Response {
92                         get { return response; }
93                 }
94
95                 public override string User {
96                         get { return ctx.User != null ? ((HttpListenerBasicIdentity) ctx.User.Identity).Name : null; }
97                 }
98
99                 public override string Password {
100                         get { return ctx.User != null ? ((HttpListenerBasicIdentity) ctx.User.Identity).Password : null; }
101                 }
102
103                 public override void ReturnUnauthorized ()
104                 {
105                         ctx.Response.StatusCode = 401;
106                 }
107         }
108
109         class AspNetHttpContextInfo : HttpContextInfo
110         {
111                 public AspNetHttpContextInfo (SvcHttpHandler handler, HttpContext ctx)
112                 {
113                         this.ctx = ctx;
114                         this.handler = handler;
115                         this.request = new AspNetHttpRequestInfo (ctx.Request);
116                         this.response = new AspNetHttpResponseInfo (ctx.Response);
117                 }
118                 
119                 HttpContext ctx;
120                 SvcHttpHandler handler;
121                 AspNetHttpRequestInfo request;
122                 AspNetHttpResponseInfo response;
123
124                 public HttpContext Source {
125                         get { return ctx; }
126                 }
127                 
128                 public override HttpRequestInfo Request {
129                         get { return request; }
130                 }
131
132                 public override HttpResponseInfo Response {
133                         get { return response; }
134                 }
135
136                 public override string User {
137                         get { return ctx.User != null ? ((GenericIdentity) ctx.User.Identity).Name : null; }
138                 }
139
140                 // FIXME: how to acquire this?
141                 public override string Password {
142                         get { return null; }
143                 }
144
145                 public override void ReturnUnauthorized ()
146                 {
147                         ctx.Response.StatusCode = 401;
148                 }
149
150                 protected override void OnContextClosed ()
151                 {
152                         handler.EndHttpRequest (ctx);
153                 }
154         }
155
156         // Request
157
158         abstract class HttpRequestInfo
159         {
160                 public abstract NameValueCollection QueryString { get; }
161                 public abstract NameValueCollection Headers { get; }
162                 public abstract Uri Url { get; }
163                 public abstract string ContentType { get; }
164                 public abstract string HttpMethod { get; }
165                 public abstract Stream InputStream { get; }
166         }
167
168         class HttpStandaloneRequestInfo : HttpRequestInfo
169         {
170                 public HttpStandaloneRequestInfo (HttpListenerRequest request)
171                 {
172                         this.req = request;
173                 }
174                 
175                 HttpListenerRequest req;
176
177                 public override NameValueCollection QueryString {
178                         get { return req.QueryString; }
179                 }
180                 public override NameValueCollection Headers {
181                         get { return req.Headers; }
182                 }
183                 public override Uri Url {
184                         get { return req.Url; }
185                 }
186                 public override string ContentType {
187                         get { return req.ContentType; }
188                 }
189                 public override string HttpMethod {
190                         get { return req.HttpMethod; }
191                 }
192                 public override Stream InputStream {
193                         get { return req.InputStream; }
194                 }
195         }
196
197         class AspNetHttpRequestInfo : HttpRequestInfo
198         {
199                 public AspNetHttpRequestInfo (HttpRequest request)
200                 {
201                         this.req = request;
202                 }
203                 
204                 HttpRequest req;
205
206                 public override NameValueCollection QueryString {
207                         get { return req.QueryString; }
208                 }
209                 public override NameValueCollection Headers {
210                         get { return req.Headers; }
211                 }
212                 public override Uri Url {
213                         get { return req.Url; }
214                 }
215                 public override string ContentType {
216                         get { return req.ContentType; }
217                 }
218                 public override string HttpMethod {
219                         get { return req.HttpMethod; }
220                 }
221                 public override Stream InputStream {
222                         get { return req.InputStream; }
223                 }
224         }
225         
226         // Response
227         
228         abstract class HttpResponseInfo
229         {
230                 public abstract string ContentType { get; set; }
231                 public abstract NameValueCollection Headers { get; }
232                 public abstract Stream OutputStream { get; }
233                 public abstract int StatusCode { get; set; }
234                 public abstract string StatusDescription { get; set; }
235                 public abstract void Abort ();
236                 public abstract void Close ();
237                 public abstract void SetLength (long value);
238                 
239                 public virtual bool SuppressContent { get; set; }
240         }
241
242         class HttpStandaloneResponseInfo : HttpResponseInfo
243         {
244                 public HttpStandaloneResponseInfo (HttpListenerResponse response)
245                 {
246                         this.res = response;
247                 }
248                 
249                 HttpListenerResponse res;
250
251                 public override string ContentType {
252                         get { return res.ContentType; }
253                         set { res.ContentType = value; }
254                 }
255                 public override NameValueCollection Headers {
256                         get { return res.Headers; }
257                 }
258                 public override int StatusCode {
259                         get { return res.StatusCode; }
260                         set { res.StatusCode = value; }
261                 }
262                 public override string StatusDescription {
263                         get { return res.StatusDescription; }
264                         set { res.StatusDescription = value; }
265                 }
266                 public override Stream OutputStream {
267                         get { return res.OutputStream; }
268                 }
269                 
270                 public override void Abort ()
271                 {
272                         res.Abort ();
273                 }
274                 
275                 public override void Close ()
276                 {
277                         res.Close ();
278                 }
279                 
280                 public override void SetLength (long value)
281                 {
282                         res.ContentLength64 = value;
283                 }
284         }
285
286         class AspNetHttpResponseInfo : HttpResponseInfo
287         {
288                 public AspNetHttpResponseInfo (HttpResponse response)
289                 {
290                         this.res = response;
291                 }
292                 
293                 HttpResponse res;
294                 
295                 public override bool SuppressContent {
296                         get { return res.SuppressContent; }
297                         set { res.SuppressContent = value; }
298                 }
299                 public override string ContentType {
300                         get { return res.ContentType; }
301                         set { res.ContentType = value; }
302                 }
303                 public override NameValueCollection Headers {
304                         get { return res.Headers; }
305                 }
306                 public override int StatusCode {
307                         get { return res.StatusCode; }
308                         set { res.StatusCode = value; }
309                 }
310                 
311                 public override string StatusDescription {
312                         get { return res.StatusDescription; }
313                         set { res.StatusDescription = value; }
314                 }
315                 public override Stream OutputStream {
316                         get { return res.OutputStream; }
317                 }
318                 
319                 public override void Abort ()
320                 {
321                         res.Flush ();
322                         res.Close ();
323                 }
324                 
325                 public override void Close ()
326                 {
327                         res.Flush ();
328                         res.Close ();
329                 }
330                 
331                 public override void SetLength (long value)
332                 {
333                         res.AddHeader ("Content-Length", value.ToString (CultureInfo.InvariantCulture));
334                 }
335         }
336 }