aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Servers/BaseHttpServer.cs69
-rw-r--r--OpenSim/Framework/Servers/IHttpAgentHandler.cs4
-rw-r--r--OpenSim/Framework/Servers/OSHttpStatusCodes.cs168
3 files changed, 220 insertions, 21 deletions
diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs
index a5e256b..91b5718 100644
--- a/OpenSim/Framework/Servers/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/BaseHttpServer.cs
@@ -120,6 +120,10 @@ namespace OpenSim.Framework.Servers
120 return false; 120 return false;
121 } 121 }
122 122
123 // Note that the agent string is provided simply to differentiate
124 // the handlers - it is NOT required to be an actual agent header
125 // value.
126
123 public bool AddAgentHandler(string agent, IHttpAgentHandler handler) 127 public bool AddAgentHandler(string agent, IHttpAgentHandler handler)
124 { 128 {
125 if (!m_agentHandlers.ContainsKey(agent)) 129 if (!m_agentHandlers.ContainsKey(agent))
@@ -149,7 +153,7 @@ namespace OpenSim.Framework.Servers
149 { 153 {
150 HttpListenerContext context = (HttpListenerContext) stateinfo; 154 HttpListenerContext context = (HttpListenerContext) stateinfo;
151 155
152 OSHttpRequest request = new OSHttpRequest(context.Request); 156 OSHttpRequest request = new OSHttpRequest(context.Request);
153 OSHttpResponse response = new OSHttpResponse(context.Response); 157 OSHttpResponse response = new OSHttpResponse(context.Response);
154 158
155 if (request.UserAgent != null) 159 if (request.UserAgent != null)
@@ -157,11 +161,11 @@ namespace OpenSim.Framework.Servers
157 161
158 IHttpAgentHandler agentHandler; 162 IHttpAgentHandler agentHandler;
159 163
160 if (TryGetAgentHandler(request.UserAgent, out agentHandler)) 164 if (TryGetAgentHandler(request, response, out agentHandler))
161 { 165 {
162 m_log.DebugFormat("[HTTP-AGENT] Handler located for {0}", request.UserAgent); 166 // m_log.DebugFormat("[HTTP-AGENT] Handler located for {0}", request.UserAgent);
163 HandleAgentRequest(agentHandler, request, response); 167 if(HandleAgentRequest(agentHandler, request, response))
164 return; 168 return;
165 } 169 }
166 } 170 }
167 171
@@ -301,14 +305,14 @@ namespace OpenSim.Framework.Servers
301 } 305 }
302 } 306 }
303 307
304 private bool TryGetAgentHandler(string agent, out IHttpAgentHandler agentHandler) 308 private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler)
305 { 309 {
306 agentHandler = null; 310 agentHandler = null;
307 try 311 try
308 { 312 {
309 foreach(IHttpAgentHandler handler in m_agentHandlers.Values) 313 foreach(IHttpAgentHandler handler in m_agentHandlers.Values)
310 { 314 {
311 if(handler.Match(agent)) 315 if(handler.Match(request, response))
312 { 316 {
313 agentHandler = handler; 317 agentHandler = handler;
314 return true; 318 return true;
@@ -472,7 +476,7 @@ namespace OpenSim.Framework.Servers
472 /// <param name="request"></param> 476 /// <param name="request"></param>
473 /// <param name="response"></param> 477 /// <param name="response"></param>
474 478
475 private void HandleAgentRequest(IHttpAgentHandler handler, OSHttpRequest request, OSHttpResponse response) 479 private bool HandleAgentRequest(IHttpAgentHandler handler, OSHttpRequest request, OSHttpResponse response)
476 { 480 {
477 481
478 // In the case of REST, then handler is responsible for ALL aspects of 482 // In the case of REST, then handler is responsible for ALL aspects of
@@ -480,17 +484,27 @@ namespace OpenSim.Framework.Servers
480 484
481 try 485 try
482 { 486 {
483 handler.Handle(request, response); 487 return handler.Handle(request, response);
484 } 488 }
485 catch (Exception e) 489 catch (Exception e)
486 { 490 {
487 m_log.Warn("[HTTP-AGENT]: Error - " + e.Message); 491 // If the handler did in fact close the stream, then this will blow
488 response.SendChunked = false; 492 // chunks, so that that doesn;t disturb anybody we throw away any
489 response.KeepAlive = false; 493 // and all exceptions raised. We've done our best to release the
490 response.StatusCode = 500; 494 // client.
491 response.OutputStream.Close(); 495 try
496 {
497 m_log.Warn("[HTTP-AGENT]: Error - " + e.Message);
498 response.SendChunked = false;
499 response.KeepAlive = false;
500 response.StatusCode = (int)OSHttpStatusCode.ServerErrorInternalError;
501 response.OutputStream.Close();
502 }
503 catch(Exception){}
492 } 504 }
493 505
506 return true;
507
494 } 508 }
495 509
496 public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response) 510 public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
@@ -498,7 +512,7 @@ namespace OpenSim.Framework.Servers
498 switch (request.HttpMethod) 512 switch (request.HttpMethod)
499 { 513 {
500 case "OPTIONS": 514 case "OPTIONS":
501 response.StatusCode = 200; 515 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
502 return; 516 return;
503 517
504 default: 518 default:
@@ -599,9 +613,9 @@ namespace OpenSim.Framework.Servers
599 // We're forgoing the usual error status codes here because the client 613 // We're forgoing the usual error status codes here because the client
600 // ignores anything but 200 and 301 614 // ignores anything but 200 and 301
601 615
602 response.StatusCode = 200; 616 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
603 617
604 if (responsecode == 301) 618 if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently)
605 { 619 {
606 response.RedirectLocation = (string)responsedata["str_redirect_location"]; 620 response.RedirectLocation = (string)responsedata["str_redirect_location"];
607 response.StatusCode = responsecode; 621 response.StatusCode = responsecode;
@@ -632,7 +646,7 @@ namespace OpenSim.Framework.Servers
632 public void SendHTML404(OSHttpResponse response, string host) 646 public void SendHTML404(OSHttpResponse response, string host)
633 { 647 {
634 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s 648 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
635 response.StatusCode = 200; 649 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
636 response.AddHeader("Content-type", "text/html"); 650 response.AddHeader("Content-type", "text/html");
637 651
638 string responseString = GetHTTP404(host); 652 string responseString = GetHTTP404(host);
@@ -659,7 +673,7 @@ namespace OpenSim.Framework.Servers
659 public void SendHTML500(OSHttpResponse response) 673 public void SendHTML500(OSHttpResponse response)
660 { 674 {
661 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s 675 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
662 response.StatusCode = 200; 676 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
663 response.AddHeader("Content-type", "text/html"); 677 response.AddHeader("Content-type", "text/html");
664 678
665 string responseString = GetHTTP500(); 679 string responseString = GetHTTP500();
@@ -738,6 +752,23 @@ namespace OpenSim.Framework.Servers
738 m_HTTPHandlers.Remove(GetHandlerKey(httpMethod, path)); 752 m_HTTPHandlers.Remove(GetHandlerKey(httpMethod, path));
739 } 753 }
740 754
755 // Remove the agent IF it is registered. Intercept the possible
756 // exception.
757
758 public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler)
759 {
760 try
761 {
762 if(handler == m_agentHandlers[agent])
763 {
764 m_agentHandlers.Remove(agent);
765 return true;
766 }
767 }
768 catch(KeyNotFoundException) {}
769 return false;
770 }
771
741 public string GetHTTP404(string host) 772 public string GetHTTP404(string host)
742 { 773 {
743 string file = Path.Combine(Util.configDir(), "http_404.html"); 774 string file = Path.Combine(Util.configDir(), "http_404.html");
diff --git a/OpenSim/Framework/Servers/IHttpAgentHandler.cs b/OpenSim/Framework/Servers/IHttpAgentHandler.cs
index 9bca150..ff3a5b9 100644
--- a/OpenSim/Framework/Servers/IHttpAgentHandler.cs
+++ b/OpenSim/Framework/Servers/IHttpAgentHandler.cs
@@ -33,7 +33,7 @@ namespace OpenSim.Framework.Servers
33{ 33{
34 public interface IHttpAgentHandler 34 public interface IHttpAgentHandler
35 { 35 {
36 void Handle(OSHttpRequest req, OSHttpResponse resp); 36 bool Handle(OSHttpRequest req, OSHttpResponse resp);
37 bool Match(string agent); 37 bool Match(OSHttpRequest req, OSHttpResponse resp);
38 } 38 }
39} 39}
diff --git a/OpenSim/Framework/Servers/OSHttpStatusCodes.cs b/OpenSim/Framework/Servers/OSHttpStatusCodes.cs
new file mode 100644
index 0000000..2e001cf
--- /dev/null
+++ b/OpenSim/Framework/Servers/OSHttpStatusCodes.cs
@@ -0,0 +1,168 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Framework.Servers
29{
30 /// <summary>
31 /// HTTP status codes (almost) as defined by W3C in
32 /// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
33 /// </summary>
34 public enum OSHttpStatusCode: int
35 {
36 // 1xx Informational status codes providing a provisional
37 // response.
38 // 100 Tells client that to keep on going sending its request
39 InfoContinue = 100,
40 // 101 Server understands request, proposes to switch to different
41 // application level protocol
42 InfoSwitchingProtocols = 101,
43
44
45 // 2xx Success codes
46 // 200 Request successful
47 SuccessOk = 200,
48 // 201 Request successful, new resource created
49 SuccessOkCreated = 201,
50 // 202 Request accepted, processing still on-going
51 SuccessOkAccepted = 202,
52 // 203 Request successful, meta information not authoritative
53 SuccessOkNonAuthoritativeInformation = 203,
54 // 204 Request successful, nothing to return in the body
55 SuccessOkNoContent = 204,
56 // 205 Request successful, reset displayed content
57 SuccessOkResetContent = 205,
58 // 206 Request successful, partial content returned
59 SuccessOkPartialContent = 206,
60
61 // 3xx Redirect code: user agent needs to go somewhere else
62 // 300 Redirect: different presentation forms available, take
63 // a pick
64 RedirectMultipleChoices = 300,
65 // 301 Redirect: requested resource has moved and now lives
66 // somewhere else
67 RedirectMovedPermanently = 301,
68 // 302 Redirect: Resource temporarily somewhere else, location
69 // might change
70 RedirectFound = 302,
71 // 303 Redirect: See other as result of a POST
72 RedirectSeeOther = 303,
73 // 304 Redirect: Resource still the same as before
74 RedirectNotModified = 304,
75 // 305 Redirect: Resource must be accessed via proxy provided
76 // in location field
77 RedirectUseProxy = 305,
78 // 307 Redirect: Resource temporarily somewhere else, location
79 // might change
80 RedirectMovedTemporarily = 307,
81
82 // 4xx Client error: the client borked the request
83 // 400 Client error: bad request, server does not grok what
84 // the client wants
85 ClientErrorBadRequest = 400,
86 // 401 Client error: the client is not authorized, response
87 // provides WWW-Authenticate header field with a challenge
88 ClientErrorUnauthorized = 401,
89 // 402 Client error: Payment required (reserved for future use)
90 ClientErrorPaymentRequired = 402,
91 // 403 Client error: Server understood request, will not
92 // deliver, do not try again.
93 ClientErrorForbidden = 403,
94 // 404 Client error: Server cannot find anything matching the
95 // client request.
96 ClientErrorNotFound = 404,
97 // 405 Client error: The method specified by the client in the
98 // request is not allowed for the resource requested
99 ClientErrorMethodNotAllowed = 405,
100 // 406 Client error: Server cannot generate suitable response
101 // for the resource and content characteristics requested by
102 // the client
103 ClientErrorNotAcceptable = 406,
104 // 407 Client error: Similar to 401, Server requests that
105 // client authenticate itself with the proxy first
106 ClientErrorProxyAuthRequired = 407,
107 // 408 Client error: Server got impatient with client and
108 // decided to give up waiting for the client's request to
109 // arrive
110 ClientErrorRequestTimeout = 408,
111 // 409 Client error: Server could not fulfill the request for
112 // a resource as there is a conflict with the current state of
113 // the resource but thinks client can do something about this
114 ClientErrorConflict = 409,
115 // 410 Client error: The resource has moved somewhere else,
116 // but server has no clue where.
117 ClientErrorGone = 410,
118 // 411 Client error: The server is picky again and insists on
119 // having a content-length header field in the request
120 ClientErrorLengthRequired = 411,
121 // 412 Client error: one or more preconditions supplied in the
122 // client's request is false
123 ClientErrorPreconditionFailed = 412,
124 // 413 Client error: For fear of reflux, the server refuses to
125 // swallow that much data.
126 ClientErrorRequestEntityToLarge = 413,
127 // 414 Client error: The server considers the Request-URI to
128 // be indecently long and refuses to even look at it.
129 ClientErrorRequestURITooLong = 414,
130 // 415 Client error: The server has no clue about the media
131 // type requested by the client (contrary to popular belief it
132 // is not a warez server)
133 ClientErrorUnsupportedMediaType = 415,
134 // 416 Client error: The requested range cannot be delivered
135 // by the server.
136 ClientErrorRequestRangeNotSatisfiable = 416,
137 // 417 Client error: The expectations of the client as
138 // expressed in one or more Expect header fields cannot be met
139 // by the server, the server is awfully sorry about this.
140 ClientErrorExpectationFailed = 417,
141
142 // 5xx Server errors (rare)
143 // 500 Server error: something really strange and unexpected
144 // happened
145 ServerErrorInternalError = 500,
146 // 501 Server error: The server does not do the functionality
147 // required to carry out the client request. not at
148 // all. certainly not before breakfast. but also not after
149 // breakfast.
150 ServerErrorNotImplemented = 501,
151 // 502 Server error: While acting as a proxy or a gateway, the
152 // server got ditched by the upstream server and as a
153 // consequence regretfully cannot fulfill the client's request
154 ServerErrorBadGateway = 502,
155 // 503 Server error: Due to unforseen circumstances the server
156 // cannot currently deliver the service requested. Retry-After
157 // header might indicate when to try again.
158 ServerErrorServiceUnavailable = 503,
159 // 504 Server error: The server blames the upstream server
160 // for not being able to deliver the service requested and
161 // claims that the upstream server is too slow delivering the
162 // goods.
163 ServerErrorGatewayTimeout = 504,
164 // 505 Server error: The server does not support the HTTP
165 // version conveyed in the client's request.
166 ServerErrorHttpVersionNotSupported = 505,
167 }
168}