diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Servers/OSHttpResponse.cs | 305 |
1 files changed, 255 insertions, 50 deletions
diff --git a/OpenSim/Framework/Servers/OSHttpResponse.cs b/OpenSim/Framework/Servers/OSHttpResponse.cs index e1ab005..352c6f6 100644 --- a/OpenSim/Framework/Servers/OSHttpResponse.cs +++ b/OpenSim/Framework/Servers/OSHttpResponse.cs | |||
@@ -25,141 +25,346 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | ||
28 | using System.Collections; | 29 | using System.Collections; |
29 | using System.IO; | 30 | using System.IO; |
30 | using System.Net; | 31 | using System.Net; |
31 | using System.Text; | 32 | using System.Text; |
33 | using HttpServer; | ||
32 | 34 | ||
33 | namespace OpenSim.Framework.Servers | 35 | namespace OpenSim.Framework.Servers |
34 | { | 36 | { |
37 | /// <summary> | ||
38 | /// OSHttpResponse is the OpenSim representation of an HTTP | ||
39 | /// response. | ||
40 | /// </summary> | ||
41 | /// <remarks> | ||
42 | /// OSHttpResponse is currently dual "homed" in that it support | ||
43 | /// both the .NET HttpListenerResponse and the HttpServer | ||
44 | /// HttpResponse (similar to OSHttpRequest); this duality is only | ||
45 | /// temporary and the .NET usage will disappear once the switch to | ||
46 | /// HttpServer is completed. | ||
47 | /// </remarks> | ||
35 | public class OSHttpResponse | 48 | public class OSHttpResponse |
36 | { | 49 | { |
37 | private string _contentType; | 50 | |
38 | private bool _contentTypeSet; | 51 | // property code below is a bit messy, will all resolve to |
52 | // harmony once we've completed the switch | ||
53 | |||
54 | /// <summary> | ||
55 | /// Content type property. | ||
56 | /// </summary> | ||
57 | /// <remarks> | ||
58 | /// Setting this property will also set IsContentTypeSet to | ||
59 | /// true. | ||
60 | /// </remarks> | ||
39 | public string ContentType | 61 | public string ContentType |
40 | { | 62 | { |
41 | get { return _contentType; } | 63 | get |
64 | { | ||
65 | return HttpServer ? _httpResponse.ContentType : _contentType; | ||
66 | } | ||
42 | set | 67 | set |
43 | { | 68 | { |
44 | _contentType = value; | 69 | if (HttpServer) |
45 | _contentTypeSet = true; | 70 | { |
71 | _httpResponse.ContentType = value; | ||
72 | } | ||
73 | else | ||
74 | { | ||
75 | _contentType = value; | ||
76 | _contentTypeSet = true; | ||
77 | } | ||
46 | } | 78 | } |
47 | } | 79 | } |
80 | private string _contentType; | ||
81 | |||
82 | /// <summary> | ||
83 | /// Boolean property indicating whether the content type | ||
84 | /// property actively has been set. | ||
85 | /// </summary> | ||
86 | /// <remarks> | ||
87 | /// IsContentTypeSet will go away together with .NET base. | ||
88 | /// </remarks> | ||
48 | public bool IsContentTypeSet | 89 | public bool IsContentTypeSet |
49 | { | 90 | { |
50 | get { return _contentTypeSet; } | 91 | get { return _contentTypeSet; } |
51 | } | 92 | } |
93 | private bool _contentTypeSet; | ||
52 | 94 | ||
53 | private long _contentLength64; | 95 | |
54 | public long ContentLength64 | 96 | /// <summary> |
97 | /// Length of the body content; 0 if there is no body. | ||
98 | /// </summary> | ||
99 | public long ContentLength | ||
55 | { | 100 | { |
56 | get { return _contentLength64; } | 101 | get |
102 | { | ||
103 | return HttpServer ? _httpResponse.ContentLength : _contentLength; | ||
104 | } | ||
57 | set | 105 | set |
58 | { | 106 | { |
59 | _contentLength64 = value; | 107 | if (HttpServer) |
60 | if (null != _resp) _resp.ContentLength64 = value; | 108 | _httpResponse.ContentLength = value; |
109 | else | ||
110 | _contentLength = value; | ||
61 | } | 111 | } |
62 | } | 112 | } |
113 | private long _contentLength; | ||
63 | 114 | ||
64 | private Encoding _contentEncoding; | 115 | /// <summary> |
116 | /// Aliases for ContentLength. | ||
117 | /// </summary> | ||
118 | public long ContentLength64 | ||
119 | { | ||
120 | get { return ContentLength; } | ||
121 | set { ContentLength = value; } | ||
122 | } | ||
123 | |||
124 | /// <summary> | ||
125 | /// Encoding of the body content. | ||
126 | /// </summary> | ||
65 | public Encoding ContentEncoding | 127 | public Encoding ContentEncoding |
66 | { | 128 | { |
67 | get { return _contentEncoding; } | 129 | get { |
130 | return HttpServer ? _httpResponse.Encoding : _contentEncoding; | ||
131 | } | ||
68 | set | 132 | set |
69 | { | 133 | { |
70 | _contentEncoding = value; | 134 | if (HttpServer) |
71 | if (null != _resp) _resp.ContentEncoding = value; | 135 | _httpResponse.Encoding = value; |
136 | else | ||
137 | _contentEncoding = value; | ||
72 | } | 138 | } |
73 | } | 139 | } |
140 | private Encoding _contentEncoding; | ||
74 | 141 | ||
75 | public WebHeaderCollection Headers; | 142 | /// <summary> |
76 | // public CookieCollection Cookies; | 143 | /// Headers of the response. |
144 | /// </summary> | ||
145 | public WebHeaderCollection Headers | ||
146 | { | ||
147 | get | ||
148 | { | ||
149 | return HttpServer ? null : _headers; | ||
150 | } | ||
151 | } | ||
152 | private WebHeaderCollection _headers; | ||
77 | 153 | ||
78 | private bool _keepAlive; | 154 | /// <summary> |
155 | /// Get or set the keep alive property. | ||
156 | /// </summary> | ||
79 | public bool KeepAlive | 157 | public bool KeepAlive |
80 | { | 158 | { |
81 | get { return _keepAlive; } | 159 | get |
160 | { | ||
161 | if (HttpServer) | ||
162 | return _httpResponse.Connection == ConnectionType.KeepAlive; | ||
163 | else | ||
164 | return _keepAlive; | ||
165 | } | ||
82 | set | 166 | set |
83 | { | 167 | { |
84 | _keepAlive = value; | 168 | if (HttpServer) |
85 | if (null != _resp) _resp.KeepAlive = value; | 169 | _httpResponse.Connection = ConnectionType.KeepAlive; |
170 | else | ||
171 | _keepAlive = value; | ||
86 | } | 172 | } |
87 | } | 173 | } |
174 | private bool _keepAlive; | ||
88 | 175 | ||
89 | public Stream OutputStream; | 176 | /// <summary> |
177 | /// Return the output stream feeding the body. | ||
178 | /// </summary> | ||
179 | /// <remarks> | ||
180 | /// On its way out... | ||
181 | /// </remarks> | ||
182 | public Stream OutputStream | ||
183 | { | ||
184 | get | ||
185 | { | ||
186 | return HttpServer ? _httpResponse.Body : _outputStream; | ||
187 | } | ||
188 | } | ||
189 | private Stream _outputStream; | ||
190 | |||
191 | |||
192 | /// <summary> | ||
193 | /// Return the output stream feeding the body. | ||
194 | /// </summary> | ||
195 | public Stream Body | ||
196 | { | ||
197 | get | ||
198 | { | ||
199 | if (HttpServer) | ||
200 | return _httpResponse.Body; | ||
201 | throw new Exception("[OSHttpResponse] mixed .NET and HttpServer access"); | ||
202 | } | ||
203 | } | ||
90 | 204 | ||
91 | private string _redirectLocation; | 205 | /// <summary> |
206 | /// Set a redirct location. | ||
207 | /// </summary> | ||
92 | public string RedirectLocation | 208 | public string RedirectLocation |
93 | { | 209 | { |
94 | get { return _redirectLocation; } | 210 | // get { return _redirectLocation; } |
95 | set | 211 | set |
96 | { | 212 | { |
97 | _redirectLocation = value; | 213 | if (HttpServer) |
98 | if (null != _resp) _resp.RedirectLocation = value; | 214 | _httpResponse.Redirect(value); |
215 | // else | ||
216 | // _redirectLocation = value; | ||
99 | } | 217 | } |
100 | } | 218 | } |
219 | // private string _redirectLocation; | ||
101 | 220 | ||
102 | private bool _sendChunked; | 221 | |
222 | |||
223 | /// <summary> | ||
224 | /// Chunk transfers. | ||
225 | /// </summary> | ||
103 | public bool SendChunked | 226 | public bool SendChunked |
104 | { | 227 | { |
105 | get { return _sendChunked; } | 228 | get |
229 | { | ||
230 | return HttpServer ? _httpResponse.Chunked :_sendChunked; | ||
231 | } | ||
232 | |||
106 | set | 233 | set |
107 | { | 234 | { |
108 | _sendChunked = value; | 235 | if (HttpServer) |
109 | if (null != _resp) _resp.SendChunked = value; | 236 | _httpResponse.Chunked = value; |
237 | else | ||
238 | _sendChunked = value; | ||
110 | } | 239 | } |
111 | } | 240 | } |
241 | private bool _sendChunked; | ||
112 | 242 | ||
113 | private int _statusCode; | 243 | |
244 | /// <summary> | ||
245 | /// HTTP status code. | ||
246 | /// </summary> | ||
114 | public int StatusCode | 247 | public int StatusCode |
115 | { | 248 | { |
116 | get { return _statusCode; } | 249 | get |
250 | { | ||
251 | return HttpServer ? (int)_httpResponse.Status : _statusCode; | ||
252 | } | ||
253 | |||
117 | set | 254 | set |
118 | { | 255 | { |
119 | _statusCode = value; | 256 | if (HttpServer) |
120 | if (null != _resp) _resp.StatusCode = value; | 257 | _httpResponse.Status = (HttpStatusCode)value; |
258 | else | ||
259 | _statusCode = value; | ||
121 | } | 260 | } |
122 | } | 261 | } |
262 | private int _statusCode; | ||
123 | 263 | ||
124 | private string _statusDescription; | 264 | |
265 | /// <summary> | ||
266 | /// HTTP status description. | ||
267 | /// </summary> | ||
125 | public string StatusDescription | 268 | public string StatusDescription |
126 | { | 269 | { |
127 | get { return _statusDescription; } | 270 | get |
271 | { | ||
272 | return HttpServer ? _httpResponse.Reason : _statusDescription; | ||
273 | } | ||
274 | |||
128 | set | 275 | set |
129 | { | 276 | { |
130 | _statusDescription = value; | 277 | if (HttpServer) |
131 | if (null != _resp) _resp.StatusDescription = value; | 278 | _httpResponse.Reason = value; |
279 | else | ||
280 | _statusDescription = value; | ||
132 | } | 281 | } |
133 | } | 282 | } |
283 | private string _statusDescription; | ||
134 | 284 | ||
135 | private HttpListenerResponse _resp; | 285 | private HttpResponse _httpResponse; |
286 | |||
287 | internal bool HttpServer | ||
288 | { | ||
289 | get { return null != _httpResponse; } | ||
290 | } | ||
291 | |||
292 | internal HttpResponse HttpResponse | ||
293 | { | ||
294 | get { return _httpResponse; } | ||
295 | } | ||
136 | 296 | ||
137 | public OSHttpResponse() | 297 | public OSHttpResponse() |
138 | { | 298 | { |
139 | } | 299 | } |
140 | 300 | ||
301 | /// <summary> | ||
302 | /// Instantiate an OSHttpResponse object based on an | ||
303 | /// underlying .NET HttpListenerResponse. | ||
304 | /// </summary> | ||
305 | /// <remarks> | ||
306 | /// Almost deprecated; will go west to make once HttpServer | ||
307 | /// base takes over. | ||
308 | /// </remarks> | ||
141 | public OSHttpResponse(HttpListenerResponse resp) | 309 | public OSHttpResponse(HttpListenerResponse resp) |
142 | { | 310 | { |
143 | ContentEncoding = resp.ContentEncoding; | 311 | _contentEncoding = resp.ContentEncoding; |
144 | ContentLength64 = resp.ContentLength64; | 312 | _contentLength = resp.ContentLength64; |
145 | _contentType = resp.ContentType; | 313 | _contentType = resp.ContentType; |
146 | Headers = resp.Headers; | 314 | _headers = resp.Headers; |
147 | // Cookies = resp.Cookies; | 315 | // _cookies = resp.Cookies; |
148 | KeepAlive = resp.KeepAlive; | 316 | _keepAlive = resp.KeepAlive; |
149 | OutputStream = resp.OutputStream; | 317 | _outputStream = resp.OutputStream; |
150 | RedirectLocation = resp.RedirectLocation; | 318 | // _redirectLocation = resp.RedirectLocation; |
151 | SendChunked = resp.SendChunked; | 319 | _sendChunked = resp.SendChunked; |
152 | StatusCode = resp.StatusCode; | 320 | _statusCode = resp.StatusCode; |
153 | StatusDescription = resp.StatusDescription; | 321 | _statusDescription = resp.StatusDescription; |
154 | 322 | ||
155 | _contentTypeSet = false; | 323 | _contentTypeSet = false; |
156 | 324 | ||
157 | _resp = resp; | 325 | // _resp = resp; |
158 | } | 326 | } |
159 | 327 | ||
328 | /// <summary> | ||
329 | /// Instantiate an OSHttpResponse object from an OSHttpRequest | ||
330 | /// object. | ||
331 | /// </summary | ||
332 | /// <param name="req">Incoming OSHttpRequest to which we are | ||
333 | /// replying</param> | ||
334 | public OSHttpResponse(OSHttpRequest req) | ||
335 | { | ||
336 | _httpResponse = new HttpResponse(req.HttpClientContext, req.HttpRequest); | ||
337 | } | ||
338 | |||
339 | /// <summary> | ||
340 | /// Add a header field and content to the response. | ||
341 | /// </summary> | ||
342 | /// <param name="key">string containing the header field | ||
343 | /// name</param> | ||
344 | /// <param name="value">string containing the header field | ||
345 | /// value</param> | ||
160 | public void AddHeader(string key, string value) | 346 | public void AddHeader(string key, string value) |
161 | { | 347 | { |
162 | Headers.Add(key, value); | 348 | if (HttpServer) |
349 | _headers.Add(key, value); | ||
350 | else | ||
351 | _httpResponse.AddHeader(key, value); | ||
352 | } | ||
353 | |||
354 | /// <summary> | ||
355 | /// Send the response back to the remote client | ||
356 | /// </summary> | ||
357 | public void Send() | ||
358 | { | ||
359 | if (HttpServer) | ||
360 | { | ||
361 | _httpResponse.Body.Flush(); | ||
362 | _httpResponse.Send(); | ||
363 | } | ||
364 | else | ||
365 | { | ||
366 | OutputStream.Close(); | ||
367 | } | ||
163 | } | 368 | } |
164 | } | 369 | } |
165 | } | 370 | } |