aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Servers')
-rw-r--r--OpenSim/Framework/Servers/BaseOpenSimServer.cs8
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs10
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs474
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs10
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs9
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs17
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs8
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs21
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs2
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs3
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs379
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs6
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs7
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs15
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs49
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs6
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs20
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs14
-rw-r--r--OpenSim/Framework/Servers/MainServer.cs184
19 files changed, 717 insertions, 525 deletions
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index 87d04f8..9a2cd0e 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -320,7 +320,9 @@ namespace OpenSim.Framework.Servers
320 320
321 TimeSpan timeTaken = DateTime.Now - m_startuptime; 321 TimeSpan timeTaken = DateTime.Now - m_startuptime;
322 322
323 m_log.InfoFormat("[STARTUP]: Startup took {0}m {1}s", timeTaken.Minutes, timeTaken.Seconds); 323 m_log.InfoFormat(
324 "[STARTUP]: Non-script portion of startup took {0}m {1}s. PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED.",
325 timeTaken.Minutes, timeTaken.Seconds);
324 } 326 }
325 327
326 /// <summary> 328 /// <summary>
@@ -589,8 +591,8 @@ namespace OpenSim.Framework.Servers
589 { 591 {
590 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(); 592 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
591 FileStream fs = File.Create(path); 593 FileStream fs = File.Create(path);
592 System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); 594
593 Byte[] buf = enc.GetBytes(pidstring); 595 Byte[] buf = Encoding.ASCII.GetBytes(pidstring);
594 fs.Write(buf, 0, buf.Length); 596 fs.Write(buf, 0, buf.Length);
595 fs.Close(); 597 fs.Close();
596 m_pidFile = path; 598 m_pidFile = path;
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs
index 2fe9769..9f8f4a8 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs
@@ -33,9 +33,9 @@ namespace OpenSim.Framework.Servers.HttpServer
33 { 33 {
34 public abstract Hashtable Handle(string path, Hashtable Request); 34 public abstract Hashtable Handle(string path, Hashtable Request);
35 35
36 protected BaseHTTPHandler(string httpMethod, string path) 36 protected BaseHTTPHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
37 : base(httpMethod, path) 37
38 { 38 protected BaseHTTPHandler(string httpMethod, string path, string name, string description)
39 } 39 : base(httpMethod, path, name, description) {}
40 } 40 }
41} 41} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index a3a5029..24f986a 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -53,6 +53,8 @@ namespace OpenSim.Framework.Servers.HttpServer
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54 private HttpServerLogWriter httpserverlog = new HttpServerLogWriter(); 54 private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
55 55
56 public int DebugLevel { get; set; }
57
56 private volatile int NotSocketErrors = 0; 58 private volatile int NotSocketErrors = 0;
57 public volatile bool HTTPDRunning = false; 59 public volatile bool HTTPDRunning = false;
58 60
@@ -79,11 +81,6 @@ namespace OpenSim.Framework.Servers.HttpServer
79 81
80 private PollServiceRequestManager m_PollServiceManager; 82 private PollServiceRequestManager m_PollServiceManager;
81 83
82 /// <summary>
83 /// Control the printing of certain debug messages.
84 /// </summary>
85 public int DebugLevel { get; set; }
86
87 public uint SSLPort 84 public uint SSLPort
88 { 85 {
89 get { return m_sslport; } 86 get { return m_sslport; }
@@ -156,7 +153,7 @@ namespace OpenSim.Framework.Servers.HttpServer
156 } 153 }
157 } 154 }
158 155
159 public List<string> GetStreamHandlerKeys() 156 public List<string> GetStreamHandlerKeys()
160 { 157 {
161 lock (m_streamHandlers) 158 lock (m_streamHandlers)
162 return new List<string>(m_streamHandlers.Keys); 159 return new List<string>(m_streamHandlers.Keys);
@@ -356,7 +353,7 @@ namespace OpenSim.Framework.Servers.HttpServer
356 } 353 }
357 catch (Exception e) 354 catch (Exception e)
358 { 355 {
359 m_log.ErrorFormat("[BASE HTTP SERVER]: OnRequest() failed with {0}{1}", e.Message, e.StackTrace); 356 m_log.Error(String.Format("[BASE HTTP SERVER]: OnRequest() failed: {0} ", e.Message), e);
360 } 357 }
361 } 358 }
362 359
@@ -408,7 +405,12 @@ namespace OpenSim.Framework.Servers.HttpServer
408 string uriString = request.RawUrl; 405 string uriString = request.RawUrl;
409 406
410// string reqnum = "unknown"; 407// string reqnum = "unknown";
411 int tickstart = Environment.TickCount; 408 int requestStartTick = Environment.TickCount;
409
410 // Will be adjusted later on.
411 int requestEndTick = requestStartTick;
412
413 IRequestHandler requestHandler = null;
412 414
413 try 415 try
414 { 416 {
@@ -431,6 +433,7 @@ namespace OpenSim.Framework.Servers.HttpServer
431 { 433 {
432 if (HandleAgentRequest(agentHandler, request, response)) 434 if (HandleAgentRequest(agentHandler, request, response))
433 { 435 {
436 requestEndTick = Environment.TickCount;
434 return; 437 return;
435 } 438 }
436 } 439 }
@@ -438,20 +441,16 @@ namespace OpenSim.Framework.Servers.HttpServer
438 //response.KeepAlive = true; 441 //response.KeepAlive = true;
439 response.SendChunked = false; 442 response.SendChunked = false;
440 443
441 IRequestHandler requestHandler;
442
443 string path = request.RawUrl; 444 string path = request.RawUrl;
444 string handlerKey = GetHandlerKey(request.HttpMethod, path); 445 string handlerKey = GetHandlerKey(request.HttpMethod, path);
446 byte[] buffer = null;
445 447
446 if (TryGetStreamHandler(handlerKey, out requestHandler)) 448 if (TryGetStreamHandler(handlerKey, out requestHandler))
447 { 449 {
448 if (DebugLevel >= 1) 450 if (DebugLevel >= 3)
449 m_log.DebugFormat( 451 m_log.DebugFormat(
450 "[BASE HTTP SERVER]: Found stream handler for {0} {1}", 452 "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
451 request.HttpMethod, request.Url.PathAndQuery); 453 request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
452
453 // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler.
454 byte[] buffer = null;
455 454
456 response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. 455 response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
457 456
@@ -507,8 +506,8 @@ namespace OpenSim.Framework.Servers.HttpServer
507 //m_log.Warn("[HTTP]: " + requestBody); 506 //m_log.Warn("[HTTP]: " + requestBody);
508 507
509 } 508 }
510 DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response); 509
511 return; 510 buffer = DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response);
512 } 511 }
513 else 512 else
514 { 513 {
@@ -521,133 +520,99 @@ namespace OpenSim.Framework.Servers.HttpServer
521 buffer = memoryStream.ToArray(); 520 buffer = memoryStream.ToArray();
522 } 521 }
523 } 522 }
524
525 request.InputStream.Close();
526
527 // HTTP IN support. The script engine takes it from here
528 // Nothing to worry about for us.
529 //
530 if (buffer == null)
531 return;
532
533 if (!response.SendChunked)
534 response.ContentLength64 = buffer.LongLength;
535
536 try
537 {
538 response.OutputStream.Write(buffer, 0, buffer.Length);
539 //response.OutputStream.Close();
540 }
541 catch (HttpListenerException)
542 {
543 m_log.WarnFormat("[BASE HTTP SERVER]: HTTP request abnormally terminated.");
544 }
545 //response.OutputStream.Close();
546 try
547 {
548 response.Send();
549 //response.FreeContext();
550 }
551 catch (SocketException e)
552 {
553 // This has to be here to prevent a Linux/Mono crash
554 m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
555 }
556 catch (IOException e)
557 {
558 m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
559 }
560
561 return;
562 } 523 }
563 524 else
564 if (request.AcceptTypes != null && request.AcceptTypes.Length > 0)
565 { 525 {
566 foreach (string strAccept in request.AcceptTypes) 526 switch (request.ContentType)
567 { 527 {
568 if (strAccept.Contains("application/llsd+xml") || 528 case null:
569 strAccept.Contains("application/llsd+json")) 529 case "text/html":
570 { 530
571 if (DebugLevel >= 1) 531 if (DebugLevel >= 3)
572 m_log.DebugFormat(
573 "[BASE HTTP SERVER]: Found application/llsd+xml accept header handler for {0} {1}",
574 request.HttpMethod, request.Url.PathAndQuery);
575
576 HandleLLSDRequests(request, response);
577 return;
578 }
579 }
580 }
581
582 switch (request.ContentType)
583 {
584 case null:
585 case "text/html":
586
587 if (DebugLevel >= 1)
588 m_log.DebugFormat(
589 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
590 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
591
592 HandleHTTPRequest(request, response);
593 return;
594
595 case "application/llsd+xml":
596 case "application/xml+llsd":
597 case "application/llsd+json":
598
599 if (DebugLevel >= 1)
600 m_log.DebugFormat(
601 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
602 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
603
604 HandleLLSDRequests(request, response);
605 return;
606
607 case "text/xml":
608 case "application/xml":
609 case "application/json":
610 default:
611 //m_log.Info("[Debug BASE HTTP SERVER]: in default handler");
612 // Point of note.. the DoWeHaveA methods check for an EXACT path
613 // if (request.RawUrl.Contains("/CAPS/EQG"))
614 // {
615 // int i = 1;
616 // }
617 //m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
618 if (DoWeHaveALLSDHandler(request.RawUrl))
619 {
620 if (DebugLevel >= 1)
621 m_log.DebugFormat( 532 m_log.DebugFormat(
622 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", 533 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
623 request.ContentType, request.HttpMethod, request.Url.PathAndQuery); 534 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
624 535
625 HandleLLSDRequests(request, response); 536 buffer = HandleHTTPRequest(request, response);
626 return; 537 break;
627 } 538
628 539 case "application/llsd+xml":
629// m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl); 540 case "application/xml+llsd":
630 if (DoWeHaveAHTTPHandler(request.RawUrl)) 541 case "application/llsd+json":
631 { 542
632 if (DebugLevel >= 1) 543 if (DebugLevel >= 3)
633 m_log.DebugFormat( 544 m_log.DebugFormat(
634 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", 545 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
635 request.ContentType, request.HttpMethod, request.Url.PathAndQuery); 546 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
547
548 buffer = HandleLLSDRequests(request, response);
549 break;
550
551 case "text/xml":
552 case "application/xml":
553 case "application/json":
554 default:
555 //m_log.Info("[Debug BASE HTTP SERVER]: in default handler");
556 // Point of note.. the DoWeHaveA methods check for an EXACT path
557 // if (request.RawUrl.Contains("/CAPS/EQG"))
558 // {
559 // int i = 1;
560 // }
561 //m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
562 if (DoWeHaveALLSDHandler(request.RawUrl))
563 {
564 if (DebugLevel >= 3)
565 m_log.DebugFormat(
566 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
567 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
568
569 buffer = HandleLLSDRequests(request, response);
570 }
571 // m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl);
572 else if (DoWeHaveAHTTPHandler(request.RawUrl))
573 {
574 if (DebugLevel >= 3)
575 m_log.DebugFormat(
576 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
577 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
578
579 buffer = HandleHTTPRequest(request, response);
580 }
581 else
582 {
583 if (DebugLevel >= 3)
584 m_log.DebugFormat(
585 "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
586 request.HttpMethod, request.Url.PathAndQuery);
587
588 // generic login request.
589 buffer = HandleXmlRpcRequests(request, response);
590 }
591
592 break;
593 }
594 }
636 595
637 HandleHTTPRequest(request, response); 596 request.InputStream.Close();
638 return;
639 }
640
641 if (DebugLevel >= 1)
642 m_log.DebugFormat(
643 "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
644 request.HttpMethod, request.Url.PathAndQuery);
645 597
646 // generic login request. 598 if (buffer != null)
647 HandleXmlRpcRequests(request, response); 599 {
600 if (!response.SendChunked)
601 response.ContentLength64 = buffer.LongLength;
648 602
649 return; 603 response.OutputStream.Write(buffer, 0, buffer.Length);
650 } 604 }
605
606 // Do not include the time taken to actually send the response to the caller in the measurement
607 // time. This is to avoid logging when it's the client that is slow to process rather than the
608 // server
609 requestEndTick = Environment.TickCount;
610
611 response.Send();
612
613 //response.OutputStream.Close();
614
615 //response.FreeContext();
651 } 616 }
652 catch (SocketException e) 617 catch (SocketException e)
653 { 618 {
@@ -658,25 +623,33 @@ namespace OpenSim.Framework.Servers.HttpServer
658 // 623 //
659 // An alternative may be to turn off all response write exceptions on the HttpListener, but let's go 624 // An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
660 // with the minimum first 625 // with the minimum first
661 m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e); 626 m_log.Warn(String.Format("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux ", e.Message), e);
662 } 627 }
663 catch (IOException e) 628 catch (IOException e)
664 { 629 {
665 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e); 630 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e);
666 } 631 }
667 catch (Exception e) 632 catch (Exception e)
668 { 633 {
669 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e.StackTrace); 634 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e);
670 SendHTML500(response); 635 SendHTML500(response);
671 } 636 }
672 finally 637 finally
673 { 638 {
674 // Every month or so this will wrap and give bad numbers, not really a problem 639 // Every month or so this will wrap and give bad numbers, not really a problem
675 // since its just for reporting, tickdiff limit can be adjusted 640 // since its just for reporting
676 int tickdiff = Environment.TickCount - tickstart; 641 int tickdiff = requestEndTick - requestStartTick;
677 if (tickdiff > 3000) 642 if (tickdiff > 3000)
643 {
678 m_log.InfoFormat( 644 m_log.InfoFormat(
679 "[BASE HTTP SERVER]: slow {0} request for {1} from {2} took {3} ms", requestMethod, uriString, request.RemoteIPEndPoint.ToString(), tickdiff); 645 "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms",
646 requestMethod,
647 uriString,
648 requestHandler != null ? requestHandler.Name : "",
649 requestHandler != null ? requestHandler.Description : "",
650 request.RemoteIPEndPoint.ToString(),
651 tickdiff);
652 }
680 } 653 }
681 } 654 }
682 655
@@ -797,7 +770,7 @@ namespace OpenSim.Framework.Servers.HttpServer
797 /// </summary> 770 /// </summary>
798 /// <param name="request"></param> 771 /// <param name="request"></param>
799 /// <param name="response"></param> 772 /// <param name="response"></param>
800 private void HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response) 773 private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response)
801 { 774 {
802 Stream requestStream = request.InputStream; 775 Stream requestStream = request.InputStream;
803 776
@@ -816,8 +789,23 @@ namespace OpenSim.Framework.Servers.HttpServer
816 { 789 {
817 xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody); 790 xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
818 } 791 }
819 catch (XmlException) 792 catch (XmlException e)
820 { 793 {
794 if (DebugLevel >= 1)
795 {
796 if (DebugLevel >= 2)
797 m_log.Warn(
798 string.Format(
799 "[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}. XML was '{1}'. Sending blank response. Exception ",
800 request.RemoteIPEndPoint, requestBody),
801 e);
802 else
803 {
804 m_log.WarnFormat(
805 "[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}, length {1}. Sending blank response.",
806 request.RemoteIPEndPoint, requestBody.Length);
807 }
808 }
821 } 809 }
822 810
823 if (xmlRprcRequest != null) 811 if (xmlRprcRequest != null)
@@ -887,6 +875,7 @@ namespace OpenSim.Framework.Servers.HttpServer
887 String.Format("Requested method [{0}] not found", methodName)); 875 String.Format("Requested method [{0}] not found", methodName));
888 } 876 }
889 877
878 response.ContentType = "text/xml";
890 responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse); 879 responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse);
891 } 880 }
892 else 881 else
@@ -896,82 +885,25 @@ namespace OpenSim.Framework.Servers.HttpServer
896 response.StatusCode = 404; 885 response.StatusCode = 404;
897 response.StatusDescription = "Not Found"; 886 response.StatusDescription = "Not Found";
898 response.ProtocolVersion = "HTTP/1.0"; 887 response.ProtocolVersion = "HTTP/1.0";
899 byte[] buf = Encoding.UTF8.GetBytes("Not found"); 888 responseString = "Not found";
900 response.KeepAlive = false; 889 response.KeepAlive = false;
901 890
902 m_log.ErrorFormat( 891 m_log.ErrorFormat(
903 "[BASE HTTP SERVER]: Handler not found for http request {0} {1}", 892 "[BASE HTTP SERVER]: Handler not found for http request {0} {1}",
904 request.HttpMethod, request.Url.PathAndQuery); 893 request.HttpMethod, request.Url.PathAndQuery);
905
906 response.SendChunked = false;
907 response.ContentLength64 = buf.Length;
908 response.ContentEncoding = Encoding.UTF8;
909
910 try
911 {
912 response.OutputStream.Write(buf, 0, buf.Length);
913 }
914 catch (Exception ex)
915 {
916 m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
917 }
918 finally
919 {
920 try
921 {
922 response.Send();
923 //response.FreeContext();
924 }
925 catch (SocketException e)
926 {
927 // This has to be here to prevent a Linux/Mono crash
928 m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
929 }
930 catch (IOException e)
931 {
932 m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
933 }
934 }
935 return;
936 //responseString = "Error";
937 } 894 }
938 } 895 }
939 896
940 response.ContentType = "text/xml";
941
942 byte[] buffer = Encoding.UTF8.GetBytes(responseString); 897 byte[] buffer = Encoding.UTF8.GetBytes(responseString);
943 898
944 response.SendChunked = false; 899 response.SendChunked = false;
945 response.ContentLength64 = buffer.Length; 900 response.ContentLength64 = buffer.Length;
946 response.ContentEncoding = Encoding.UTF8; 901 response.ContentEncoding = Encoding.UTF8;
947 try 902
948 { 903 return buffer;
949 response.OutputStream.Write(buffer, 0, buffer.Length);
950 }
951 catch (Exception ex)
952 {
953 m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
954 }
955 finally
956 {
957 try
958 {
959 response.Send();
960 //response.FreeContext();
961 }
962 catch (SocketException e)
963 {
964 // This has to be here to prevent a Linux/Mono crash
965 m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
966 }
967 catch (IOException e)
968 {
969 m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
970 }
971 }
972 } 904 }
973 905
974 private void HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response) 906 private byte[] HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response)
975 { 907 {
976 //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); 908 //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request");
977 Stream requestStream = request.InputStream; 909 Stream requestStream = request.InputStream;
@@ -1057,34 +989,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1057 response.ContentEncoding = Encoding.UTF8; 989 response.ContentEncoding = Encoding.UTF8;
1058 response.KeepAlive = true; 990 response.KeepAlive = true;
1059 991
1060 try 992 return buffer;
1061 {
1062 response.OutputStream.Write(buffer, 0, buffer.Length);
1063 }
1064 catch (Exception ex)
1065 {
1066 m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
1067 }
1068 finally
1069 {
1070 //response.OutputStream.Close();
1071 try
1072 {
1073 response.Send();
1074 response.OutputStream.Flush();
1075 //response.FreeContext();
1076 //response.OutputStream.Close();
1077 }
1078 catch (IOException e)
1079 {
1080 m_log.WarnFormat("[BASE HTTP SERVER]: LLSD IOException {0}.", e);
1081 }
1082 catch (SocketException e)
1083 {
1084 // This has to be here to prevent a Linux/Mono crash
1085 m_log.WarnFormat("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux.", e);
1086 }
1087 }
1088 } 993 }
1089 994
1090 private byte[] BuildLLSDResponse(OSHttpRequest request, OSHttpResponse response, OSD llsdResponse) 995 private byte[] BuildLLSDResponse(OSHttpRequest request, OSHttpResponse response, OSD llsdResponse)
@@ -1334,8 +1239,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1334 catch (SocketException f) 1239 catch (SocketException f)
1335 { 1240 {
1336 // This has to be here to prevent a Linux/Mono crash 1241 // This has to be here to prevent a Linux/Mono crash
1337 m_log.WarnFormat( 1242 m_log.Warn(
1338 "[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f); 1243 String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", f.Message), f);
1339 } 1244 }
1340 } 1245 }
1341 catch(Exception) 1246 catch(Exception)
@@ -1349,7 +1254,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1349 1254
1350 } 1255 }
1351 1256
1352 public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response) 1257 public byte[] HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
1353 { 1258 {
1354// m_log.DebugFormat( 1259// m_log.DebugFormat(
1355// "[BASE HTTP SERVER]: HandleHTTPRequest for request to {0}, method {1}", 1260// "[BASE HTTP SERVER]: HandleHTTPRequest for request to {0}, method {1}",
@@ -1359,15 +1264,14 @@ namespace OpenSim.Framework.Servers.HttpServer
1359 { 1264 {
1360 case "OPTIONS": 1265 case "OPTIONS":
1361 response.StatusCode = (int)OSHttpStatusCode.SuccessOk; 1266 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
1362 return; 1267 return null;
1363 1268
1364 default: 1269 default:
1365 HandleContentVerbs(request, response); 1270 return HandleContentVerbs(request, response);
1366 return;
1367 } 1271 }
1368 } 1272 }
1369 1273
1370 private void HandleContentVerbs(OSHttpRequest request, OSHttpResponse response) 1274 private byte[] HandleContentVerbs(OSHttpRequest request, OSHttpResponse response)
1371 { 1275 {
1372// m_log.DebugFormat("[BASE HTTP SERVER]: HandleContentVerbs for request to {0}", request.RawUrl); 1276// m_log.DebugFormat("[BASE HTTP SERVER]: HandleContentVerbs for request to {0}", request.RawUrl);
1373 1277
@@ -1383,6 +1287,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1383 // to display the form, or process it. 1287 // to display the form, or process it.
1384 // a better way would be nifty. 1288 // a better way would be nifty.
1385 1289
1290 byte[] buffer;
1291
1386 Stream requestStream = request.InputStream; 1292 Stream requestStream = request.InputStream;
1387 1293
1388 Encoding encoding = Encoding.UTF8; 1294 Encoding encoding = Encoding.UTF8;
@@ -1443,14 +1349,14 @@ namespace OpenSim.Framework.Servers.HttpServer
1443 if (foundHandler) 1349 if (foundHandler)
1444 { 1350 {
1445 Hashtable responsedata1 = requestprocessor(keysvals); 1351 Hashtable responsedata1 = requestprocessor(keysvals);
1446 DoHTTPGruntWork(responsedata1,response); 1352 buffer = DoHTTPGruntWork(responsedata1,response);
1447 1353
1448 //SendHTML500(response); 1354 //SendHTML500(response);
1449 } 1355 }
1450 else 1356 else
1451 { 1357 {
1452// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found"); 1358// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found");
1453 SendHTML404(response, host); 1359 buffer = SendHTML404(response, host);
1454 } 1360 }
1455 } 1361 }
1456 else 1362 else
@@ -1460,16 +1366,18 @@ namespace OpenSim.Framework.Servers.HttpServer
1460 if (foundHandler) 1366 if (foundHandler)
1461 { 1367 {
1462 Hashtable responsedata2 = requestprocessor(keysvals); 1368 Hashtable responsedata2 = requestprocessor(keysvals);
1463 DoHTTPGruntWork(responsedata2, response); 1369 buffer = DoHTTPGruntWork(responsedata2, response);
1464 1370
1465 //SendHTML500(response); 1371 //SendHTML500(response);
1466 } 1372 }
1467 else 1373 else
1468 { 1374 {
1469// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found2"); 1375// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found2");
1470 SendHTML404(response, host); 1376 buffer = SendHTML404(response, host);
1471 } 1377 }
1472 } 1378 }
1379
1380 return buffer;
1473 } 1381 }
1474 1382
1475 private bool TryGetHTTPHandlerPathBased(string path, out GenericHTTPMethod httpHandler) 1383 private bool TryGetHTTPHandlerPathBased(string path, out GenericHTTPMethod httpHandler)
@@ -1537,7 +1445,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1537 } 1445 }
1538 } 1446 }
1539 1447
1540 internal void DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) 1448 internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
1541 { 1449 {
1542 int responsecode; 1450 int responsecode;
1543 string responseString; 1451 string responseString;
@@ -1631,38 +1539,10 @@ namespace OpenSim.Framework.Servers.HttpServer
1631 response.ContentLength64 = buffer.Length; 1539 response.ContentLength64 = buffer.Length;
1632 response.ContentEncoding = Encoding.UTF8; 1540 response.ContentEncoding = Encoding.UTF8;
1633 1541
1634 try 1542 return buffer;
1635 {
1636 response.OutputStream.Write(buffer, 0, buffer.Length);
1637 }
1638 catch (Exception ex)
1639 {
1640 m_log.Warn("[HTTPD]: Error - " + ex.Message);
1641 }
1642 finally
1643 {
1644 //response.OutputStream.Close();
1645 try
1646 {
1647 response.OutputStream.Flush();
1648 response.Send();
1649
1650 //if (!response.KeepAlive && response.ReuseContext)
1651 // response.FreeContext();
1652 }
1653 catch (SocketException e)
1654 {
1655 // This has to be here to prevent a Linux/Mono crash
1656 m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
1657 }
1658 catch (IOException e)
1659 {
1660 m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
1661 }
1662 }
1663 } 1543 }
1664 1544
1665 public void SendHTML404(OSHttpResponse response, string host) 1545 public byte[] SendHTML404(OSHttpResponse response, string host)
1666 { 1546 {
1667 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s 1547 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
1668 response.StatusCode = 404; 1548 response.StatusCode = 404;
@@ -1675,31 +1555,10 @@ namespace OpenSim.Framework.Servers.HttpServer
1675 response.ContentLength64 = buffer.Length; 1555 response.ContentLength64 = buffer.Length;
1676 response.ContentEncoding = Encoding.UTF8; 1556 response.ContentEncoding = Encoding.UTF8;
1677 1557
1678 try 1558 return buffer;
1679 {
1680 response.OutputStream.Write(buffer, 0, buffer.Length);
1681 }
1682 catch (Exception ex)
1683 {
1684 m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
1685 }
1686 finally
1687 {
1688 //response.OutputStream.Close();
1689 try
1690 {
1691 response.Send();
1692 //response.FreeContext();
1693 }
1694 catch (SocketException e)
1695 {
1696 // This has to be here to prevent a Linux/Mono crash
1697 m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
1698 }
1699 }
1700 } 1559 }
1701 1560
1702 public void SendHTML500(OSHttpResponse response) 1561 public byte[] SendHTML500(OSHttpResponse response)
1703 { 1562 {
1704 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s 1563 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
1705 response.StatusCode = (int)OSHttpStatusCode.SuccessOk; 1564 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
@@ -1711,28 +1570,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1711 response.SendChunked = false; 1570 response.SendChunked = false;
1712 response.ContentLength64 = buffer.Length; 1571 response.ContentLength64 = buffer.Length;
1713 response.ContentEncoding = Encoding.UTF8; 1572 response.ContentEncoding = Encoding.UTF8;
1714 try 1573
1715 { 1574 return buffer;
1716 response.OutputStream.Write(buffer, 0, buffer.Length);
1717 }
1718 catch (Exception ex)
1719 {
1720 m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
1721 }
1722 finally
1723 {
1724 //response.OutputStream.Close();
1725 try
1726 {
1727 response.Send();
1728 //response.FreeContext();
1729 }
1730 catch (SocketException e)
1731 {
1732 // This has to be here to prevent a Linux/Mono crash
1733 m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
1734 }
1735 }
1736 } 1575 }
1737 1576
1738 public void Start() 1577 public void Start()
@@ -1742,6 +1581,9 @@ namespace OpenSim.Framework.Servers.HttpServer
1742 1581
1743 private void StartHTTP() 1582 private void StartHTTP()
1744 { 1583 {
1584 m_log.InfoFormat(
1585 "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port);
1586
1745 try 1587 try
1746 { 1588 {
1747 //m_httpListener = new HttpListener(); 1589 //m_httpListener = new HttpListener();
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
index a2135a3..ae7aaf2 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
@@ -45,8 +45,16 @@ namespace OpenSim.Framework.Servers.HttpServer
45 45
46 private readonly string m_path; 46 private readonly string m_path;
47 47
48 protected BaseRequestHandler(string httpMethod, string path) 48 public string Name { get; private set; }
49
50 public string Description { get; private set; }
51
52 protected BaseRequestHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
53
54 protected BaseRequestHandler(string httpMethod, string path, string name, string description)
49 { 55 {
56 Name = name;
57 Description = description;
50 m_httpMethod = httpMethod; 58 m_httpMethod = httpMethod;
51 m_path = path; 59 m_path = path;
52 } 60 }
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
index f1cde74..6342983 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
@@ -34,8 +34,9 @@ namespace OpenSim.Framework.Servers.HttpServer
34 public abstract byte[] Handle(string path, Stream request, 34 public abstract byte[] Handle(string path, Stream request,
35 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse); 35 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse);
36 36
37 protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path) 37 protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
38 { 38
39 } 39 protected BaseStreamHandler(string httpMethod, string path, string name, string description)
40 : base(httpMethod, path, name, description) {}
40 } 41 }
41} 42} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs
index 1699233..b94bfb4 100644
--- a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs
@@ -36,6 +36,15 @@ namespace OpenSim.Framework.Servers.HttpServer
36 { 36 {
37 private BinaryMethod m_method; 37 private BinaryMethod m_method;
38 38
39 public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
40 : this(httpMethod, path, binaryMethod, null, null) {}
41
42 public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod, string name, string description)
43 : base(httpMethod, path, name, description)
44 {
45 m_method = binaryMethod;
46 }
47
39 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 48 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
40 { 49 {
41 byte[] data = ReadFully(request); 50 byte[] data = ReadFully(request);
@@ -45,12 +54,6 @@ namespace OpenSim.Framework.Servers.HttpServer
45 return Encoding.UTF8.GetBytes(responseString); 54 return Encoding.UTF8.GetBytes(responseString);
46 } 55 }
47 56
48 public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
49 : base(httpMethod, path)
50 {
51 m_method = binaryMethod;
52 }
53
54 private static byte[] ReadFully(Stream stream) 57 private static byte[] ReadFully(Stream stream)
55 { 58 {
56 byte[] buffer = new byte[1024]; 59 byte[] buffer = new byte[1024];
@@ -70,4 +73,4 @@ namespace OpenSim.Framework.Servers.HttpServer
70 } 73 }
71 } 74 }
72 } 75 }
73} 76} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs
index 33a1663..f61b090 100644
--- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs
@@ -128,11 +128,5 @@ namespace OpenSim.Framework.Servers.HttpServer
128 /// <param name="value">string containing the header field 128 /// <param name="value">string containing the header field
129 /// value</param> 129 /// value</param>
130 void AddHeader(string key, string value); 130 void AddHeader(string key, string value);
131
132 /// <summary>
133 /// Send the response back to the remote client
134 /// </summary>
135 void Send();
136 } 131 }
137} 132} \ No newline at end of file
138
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
index a449c2d..cb5cce5 100644
--- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
@@ -32,6 +32,25 @@ namespace OpenSim.Framework.Servers.HttpServer
32{ 32{
33 public interface IRequestHandler 33 public interface IRequestHandler
34 { 34 {
35
36 /// <summary>
37 /// Name for this handler.
38 /// </summary>
39 /// <remarks>
40 /// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none
41 /// specified.
42 /// </remarks>
43 string Name { get; }
44
45 /// <summary>
46 /// Description for this handler.
47 /// </summary>
48 /// <remarks>
49 /// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none
50 /// specified.
51 /// </remarks>
52 string Description { get; }
53
35 // Return response content type 54 // Return response content type
36 string ContentType { get; } 55 string ContentType { get; }
37 56
@@ -58,4 +77,4 @@ namespace OpenSim.Framework.Servers.HttpServer
58 { 77 {
59 Hashtable Handle(string path, Hashtable request); 78 Hashtable Handle(string path, Hashtable request);
60 } 79 }
61} 80} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
index fc8daf3..3171759 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
@@ -107,7 +107,7 @@ namespace OpenSim.Framework.Servers.HttpServer
107 107
108 public bool IsSecured 108 public bool IsSecured
109 { 109 {
110 get { return _context.Secured; } 110 get { return _context.IsSecured; }
111 } 111 }
112 112
113 public bool KeepAlive 113 public bool KeepAlive
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs
index f9227ac..89fb5d4 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs
@@ -321,13 +321,12 @@ namespace OpenSim.Framework.Servers.HttpServer
321 { 321 {
322 _httpResponse.Body.Flush(); 322 _httpResponse.Body.Flush();
323 _httpResponse.Send(); 323 _httpResponse.Send();
324
325 } 324 }
325
326 public void FreeContext() 326 public void FreeContext()
327 { 327 {
328 if (_httpClientContext != null) 328 if (_httpClientContext != null)
329 _httpClientContext.Close(); 329 _httpClientContext.Close();
330 } 330 }
331
332 } 331 }
333} \ No newline at end of file 332} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs
index 5625227..a736c8b 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs
@@ -28,143 +28,252 @@
28namespace OpenSim.Framework.Servers.HttpServer 28namespace OpenSim.Framework.Servers.HttpServer
29{ 29{
30 /// <summary> 30 /// <summary>
31 /// HTTP status codes (almost) as defined by W3C in 31 /// HTTP status codes (almost) as defined by W3C in http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html and IETF in http://tools.ietf.org/html/rfc6585
32 /// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
33 /// </summary> 32 /// </summary>
34 public enum OSHttpStatusCode: int 33 public enum OSHttpStatusCode : int
35 { 34 {
36 // 1xx Informational status codes providing a provisional 35 #region 1xx Informational status codes providing a provisional response.
37 // response. 36
38 // 100 Tells client that to keep on going sending its request 37 /// <summary>
39 InfoContinue = 100, 38 /// 100 Tells client that to keep on going sending its request
40 // 101 Server understands request, proposes to switch to different 39 /// </summary>
41 // application level protocol 40 InfoContinue = 100,
42 InfoSwitchingProtocols = 101, 41
43 42 /// <summary>
44 43 /// 101 Server understands request, proposes to switch to different application level protocol
45 // 2xx Success codes 44 /// </summary>
46 // 200 Request successful 45 InfoSwitchingProtocols = 101,
47 SuccessOk = 200, 46
48 // 201 Request successful, new resource created 47 #endregion
49 SuccessOkCreated = 201, 48
50 // 202 Request accepted, processing still on-going 49 #region 2xx Success codes
51 SuccessOkAccepted = 202, 50
52 // 203 Request successful, meta information not authoritative 51 /// <summary>
53 SuccessOkNonAuthoritativeInformation = 203, 52 /// 200 Request successful
54 // 204 Request successful, nothing to return in the body 53 /// </summary>
55 SuccessOkNoContent = 204, 54 SuccessOk = 200,
56 // 205 Request successful, reset displayed content 55
57 SuccessOkResetContent = 205, 56 /// <summary>
58 // 206 Request successful, partial content returned 57 /// 201 Request successful, new resource created
59 SuccessOkPartialContent = 206, 58 /// </summary>
60 59 SuccessOkCreated = 201,
61 // 3xx Redirect code: user agent needs to go somewhere else 60
62 // 300 Redirect: different presentation forms available, take 61 /// <summary>
63 // a pick 62 /// 202 Request accepted, processing still on-going
64 RedirectMultipleChoices = 300, 63 /// </summary>
65 // 301 Redirect: requested resource has moved and now lives 64 SuccessOkAccepted = 202,
66 // somewhere else 65
67 RedirectMovedPermanently = 301, 66 /// <summary>
68 // 302 Redirect: Resource temporarily somewhere else, location 67 /// 203 Request successful, meta information not authoritative
69 // might change 68 /// </summary>
70 RedirectFound = 302, 69 SuccessOkNonAuthoritativeInformation = 203,
71 // 303 Redirect: See other as result of a POST 70
72 RedirectSeeOther = 303, 71 /// <summary>
73 // 304 Redirect: Resource still the same as before 72 /// 204 Request successful, nothing to return in the body
74 RedirectNotModified = 304, 73 /// </summary>
75 // 305 Redirect: Resource must be accessed via proxy provided 74 SuccessOkNoContent = 204,
76 // in location field 75
77 RedirectUseProxy = 305, 76 /// <summary>
78 // 307 Redirect: Resource temporarily somewhere else, location 77 /// 205 Request successful, reset displayed content
79 // might change 78 /// </summary>
80 RedirectMovedTemporarily = 307, 79 SuccessOkResetContent = 205,
81 80
82 // 4xx Client error: the client borked the request 81 /// <summary>
83 // 400 Client error: bad request, server does not grok what 82 /// 206 Request successful, partial content returned
84 // the client wants 83 /// </summary>
85 ClientErrorBadRequest = 400, 84 SuccessOkPartialContent = 206,
86 // 401 Client error: the client is not authorized, response 85
87 // provides WWW-Authenticate header field with a challenge 86 #endregion
88 ClientErrorUnauthorized = 401, 87
89 // 402 Client error: Payment required (reserved for future use) 88 #region 3xx Redirect code: user agent needs to go somewhere else
90 ClientErrorPaymentRequired = 402, 89
91 // 403 Client error: Server understood request, will not 90 /// <summary>
92 // deliver, do not try again. 91 /// 300 Redirect: different presentation forms available, take a pick
93 ClientErrorForbidden = 403, 92 /// </summary>
94 // 404 Client error: Server cannot find anything matching the 93 RedirectMultipleChoices = 300,
95 // client request. 94
96 ClientErrorNotFound = 404, 95 /// <summary>
97 // 405 Client error: The method specified by the client in the 96 /// 301 Redirect: requested resource has moved and now lives somewhere else
98 // request is not allowed for the resource requested 97 /// </summary>
99 ClientErrorMethodNotAllowed = 405, 98 RedirectMovedPermanently = 301,
100 // 406 Client error: Server cannot generate suitable response 99
101 // for the resource and content characteristics requested by 100 /// <summary>
102 // the client 101 /// 302 Redirect: Resource temporarily somewhere else, location might change
103 ClientErrorNotAcceptable = 406, 102 /// </summary>
104 // 407 Client error: Similar to 401, Server requests that 103 RedirectFound = 302,
105 // client authenticate itself with the proxy first 104
106 ClientErrorProxyAuthRequired = 407, 105 /// <summary>
107 // 408 Client error: Server got impatient with client and 106 /// 303 Redirect: See other as result of a POST
108 // decided to give up waiting for the client's request to 107 /// </summary>
109 // arrive 108 RedirectSeeOther = 303,
110 ClientErrorRequestTimeout = 408, 109
111 // 409 Client error: Server could not fulfill the request for 110 /// <summary>
112 // a resource as there is a conflict with the current state of 111 /// 304 Redirect: Resource still the same as before
113 // the resource but thinks client can do something about this 112 /// </summary>
114 ClientErrorConflict = 409, 113 RedirectNotModified = 304,
115 // 410 Client error: The resource has moved somewhere else, 114
116 // but server has no clue where. 115 /// <summary>
117 ClientErrorGone = 410, 116 /// 305 Redirect: Resource must be accessed via proxy provided in location field
118 // 411 Client error: The server is picky again and insists on 117 /// </summary>
119 // having a content-length header field in the request 118 RedirectUseProxy = 305,
120 ClientErrorLengthRequired = 411, 119
121 // 412 Client error: one or more preconditions supplied in the 120 /// <summary>
122 // client's request is false 121 /// 307 Redirect: Resource temporarily somewhere else, location might change
123 ClientErrorPreconditionFailed = 412, 122 /// </summary>
124 // 413 Client error: For fear of reflux, the server refuses to 123 RedirectMovedTemporarily = 307,
125 // swallow that much data. 124
126 ClientErrorRequestEntityToLarge = 413, 125 #endregion
127 // 414 Client error: The server considers the Request-URI to 126
128 // be indecently long and refuses to even look at it. 127 #region 4xx Client error: the client borked the request
129 ClientErrorRequestURITooLong = 414, 128
130 // 415 Client error: The server has no clue about the media 129 /// <summary>
131 // type requested by the client (contrary to popular belief it 130 /// 400 Client error: bad request, server does not grok what the client wants
132 // is not a warez server) 131 /// </summary>
133 ClientErrorUnsupportedMediaType = 415, 132 ClientErrorBadRequest = 400,
134 // 416 Client error: The requested range cannot be delivered 133
135 // by the server. 134 /// <summary>
135 /// 401 Client error: the client is not authorized, response provides WWW-Authenticate header field with a challenge
136 /// </summary>
137 ClientErrorUnauthorized = 401,
138
139 /// <summary>
140 /// 402 Client error: Payment required (reserved for future use)
141 /// </summary>
142 ClientErrorPaymentRequired = 402,
143
144 /// <summary>
145 /// 403 Client error: Server understood request, will not deliver, do not try again.
146 ClientErrorForbidden = 403,
147
148 /// <summary>
149 /// 404 Client error: Server cannot find anything matching the client request.
150 /// </summary>
151 ClientErrorNotFound = 404,
152
153 /// <summary>
154 /// 405 Client error: The method specified by the client in the request is not allowed for the resource requested
155 /// </summary>
156 ClientErrorMethodNotAllowed = 405,
157
158 /// <summary>
159 /// 406 Client error: Server cannot generate suitable response for the resource and content characteristics requested by the client
160 /// </summary>
161 ClientErrorNotAcceptable = 406,
162
163 /// <summary>
164 /// 407 Client error: Similar to 401, Server requests that client authenticate itself with the proxy first
165 /// </summary>
166 ClientErrorProxyAuthRequired = 407,
167
168 /// <summary>
169 /// 408 Client error: Server got impatient with client and decided to give up waiting for the client's request to arrive
170 /// </summary>
171 ClientErrorRequestTimeout = 408,
172
173 /// <summary>
174 /// 409 Client error: Server could not fulfill the request for a resource as there is a conflict with the current state of the resource but thinks client can do something about this
175 /// </summary>
176 ClientErrorConflict = 409,
177
178 /// <summary>
179 /// 410 Client error: The resource has moved somewhere else, but server has no clue where.
180 /// </summary>
181 ClientErrorGone = 410,
182
183 /// <summary>
184 /// 411 Client error: The server is picky again and insists on having a content-length header field in the request
185 /// </summary>
186 ClientErrorLengthRequired = 411,
187
188 /// <summary>
189 /// 412 Client error: one or more preconditions supplied in the client's request is false
190 /// </summary>
191 ClientErrorPreconditionFailed = 412,
192
193 /// <summary>
194 /// 413 Client error: For fear of reflux, the server refuses to swallow that much data.
195 /// </summary>
196 ClientErrorRequestEntityToLarge = 413,
197
198 /// <summary>
199 /// 414 Client error: The server considers the Request-URI to be indecently long and refuses to even look at it.
200 /// </summary>
201 ClientErrorRequestURITooLong = 414,
202
203 /// <summary>
204 /// 415 Client error: The server has no clue about the media type requested by the client (contrary to popular belief it is not a warez server)
205 /// </summary>
206 ClientErrorUnsupportedMediaType = 415,
207
208 /// <summary>
209 /// 416 Client error: The requested range cannot be delivered by the server.
210 /// </summary>
136 ClientErrorRequestRangeNotSatisfiable = 416, 211 ClientErrorRequestRangeNotSatisfiable = 416,
137 // 417 Client error: The expectations of the client as 212
138 // expressed in one or more Expect header fields cannot be met 213 /// <summary>
139 // by the server, the server is awfully sorry about this. 214 /// 417 Client error: The expectations of the client as expressed in one or more Expect header fields cannot be met by the server, the server is awfully sorry about this.
140 ClientErrorExpectationFailed = 417, 215 /// </summary>
141 // 499 Client error: Wildcard error. 216 ClientErrorExpectationFailed = 417,
142 ClientErrorJoker = 499, 217
143 218 /// <summary>
144 // 5xx Server errors (rare) 219 /// 428 Client error :The 428 status code indicates that the origin server requires the request to be conditional.
145 // 500 Server error: something really strange and unexpected 220 /// </summary>
146 // happened 221 ClientErrorPreconditionRequired = 428,
147 ServerErrorInternalError = 500, 222
148 // 501 Server error: The server does not do the functionality 223 /// <summary>
149 // required to carry out the client request. not at 224 /// 429 Client error: The 429 status code indicates that the user has sent too many requests in a given amount of time ("rate limiting").
150 // all. certainly not before breakfast. but also not after 225 /// </summary>
151 // breakfast. 226 ClientErrorTooManyRequests = 429,
152 ServerErrorNotImplemented = 501, 227
153 // 502 Server error: While acting as a proxy or a gateway, the 228 /// <summary>
154 // server got ditched by the upstream server and as a 229 /// 431 Client error: The 431 status code indicates that the server is unwilling to process the request because its header fields are too large. The request MAY be resubmitted after reducing the size of the request header fields.
155 // consequence regretfully cannot fulfill the client's request 230 /// </summary>
156 ServerErrorBadGateway = 502, 231 ClientErrorRequestHeaderFieldsTooLarge = 431,
157 // 503 Server error: Due to unforseen circumstances the server 232
158 // cannot currently deliver the service requested. Retry-After 233 /// <summary>
159 // header might indicate when to try again. 234 /// 499 Client error: Wildcard error.
160 ServerErrorServiceUnavailable = 503, 235 /// </summary>
161 // 504 Server error: The server blames the upstream server 236 ClientErrorJoker = 499,
162 // for not being able to deliver the service requested and 237
163 // claims that the upstream server is too slow delivering the 238 #endregion
164 // goods. 239
165 ServerErrorGatewayTimeout = 504, 240 #region 5xx Server errors (rare)
166 // 505 Server error: The server does not support the HTTP 241
167 // version conveyed in the client's request. 242 /// <summary>
168 ServerErrorHttpVersionNotSupported = 505, 243 /// 500 Server error: something really strange and unexpected happened
244 /// </summary>
245 ServerErrorInternalError = 500,
246
247 /// <summary>
248 /// 501 Server error: The server does not do the functionality required to carry out the client request. not at all. certainly not before breakfast. but also not after breakfast.
249 /// </summary>
250 ServerErrorNotImplemented = 501,
251
252 /// <summary>
253 /// 502 Server error: While acting as a proxy or a gateway, the server got ditched by the upstream server and as a consequence regretfully cannot fulfill the client's request
254 /// </summary>
255 ServerErrorBadGateway = 502,
256
257 /// <summary>
258 /// 503 Server error: Due to unforseen circumstances the server cannot currently deliver the service requested. Retry-After header might indicate when to try again.
259 /// </summary>
260 ServerErrorServiceUnavailable = 503,
261
262 /// <summary>
263 /// 504 Server error: The server blames the upstream server for not being able to deliver the service requested and claims that the upstream server is too slow delivering the goods.
264 /// </summary>
265 ServerErrorGatewayTimeout = 504,
266
267 /// <summary>
268 /// 505 Server error: The server does not support the HTTP version conveyed in the client's request.
269 /// </summary>
270 ServerErrorHttpVersionNotSupported = 505,
271
272 /// <summary>
273 /// 511 Server error: The 511 status code indicates that the client needs to authenticate to gain network access.
274 /// </summary>
275 ServerErrorNetworkAuthenticationRequired = 511,
276
277 #endregion
169 } 278 }
170} 279}
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
index 7c92a50..bb43cd2 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using OpenMetaverse; 30using OpenMetaverse;
31
31namespace OpenSim.Framework.Servers.HttpServer 32namespace OpenSim.Framework.Servers.HttpServer
32{ 33{
33 public delegate void RequestMethod(UUID requestID, Hashtable request); 34 public delegate void RequestMethod(UUID requestID, Hashtable request);
@@ -53,7 +54,10 @@ namespace OpenSim.Framework.Servers.HttpServer
53 LslHttp = 1 54 LslHttp = 1
54 } 55 }
55 56
56 public PollServiceEventArgs(RequestMethod pRequest, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, UUID pId, int pTimeOutms) 57 public PollServiceEventArgs(
58 RequestMethod pRequest,
59 HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
60 UUID pId, int pTimeOutms)
57 { 61 {
58 Request = pRequest; 62 Request = pRequest;
59 HasEvents = pHasEvents; 63 HasEvents = pHasEvents;
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs
index 553a7eb..723530a 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs
@@ -31,7 +31,6 @@ using OpenMetaverse;
31 31
32namespace OpenSim.Framework.Servers.HttpServer 32namespace OpenSim.Framework.Servers.HttpServer
33{ 33{
34
35 public class PollServiceHttpRequest 34 public class PollServiceHttpRequest
36 { 35 {
37 public readonly PollServiceEventArgs PollServiceArgs; 36 public readonly PollServiceEventArgs PollServiceArgs;
@@ -39,7 +38,9 @@ namespace OpenSim.Framework.Servers.HttpServer
39 public readonly IHttpRequest Request; 38 public readonly IHttpRequest Request;
40 public readonly int RequestTime; 39 public readonly int RequestTime;
41 public readonly UUID RequestID; 40 public readonly UUID RequestID;
42 public PollServiceHttpRequest(PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) 41
42 public PollServiceHttpRequest(
43 PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
43 { 44 {
44 PollServiceArgs = pPollServiceArgs; 45 PollServiceArgs = pPollServiceArgs;
45 HttpContext = pHttpContext; 46 HttpContext = pHttpContext;
@@ -48,4 +49,4 @@ namespace OpenSim.Framework.Servers.HttpServer
48 RequestID = UUID.Random(); 49 RequestID = UUID.Random();
49 } 50 }
50 } 51 }
51} 52} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 6f87c85..3a14b6f 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -70,6 +70,7 @@ namespace OpenSim.Framework.Servers.HttpServer
70 ThreadPriority.Normal, 70 ThreadPriority.Normal,
71 false, 71 false,
72 true, 72 true,
73 null,
73 int.MaxValue); 74 int.MaxValue);
74 } 75 }
75 76
@@ -79,6 +80,7 @@ namespace OpenSim.Framework.Servers.HttpServer
79 ThreadPriority.Normal, 80 ThreadPriority.Normal,
80 false, 81 false,
81 true, 82 true,
83 null,
82 1000 * 60 * 10); 84 1000 * 60 * 10);
83 } 85 }
84 86
@@ -144,9 +146,8 @@ namespace OpenSim.Framework.Servers.HttpServer
144 foreach (object o in m_requests) 146 foreach (object o in m_requests)
145 { 147 {
146 PollServiceHttpRequest req = (PollServiceHttpRequest) o; 148 PollServiceHttpRequest req = (PollServiceHttpRequest) o;
147 m_server.DoHTTPGruntWork( 149 PollServiceWorkerThread.DoHTTPGruntWork(
148 req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), 150 m_server, req, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
149 new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext));
150 } 151 }
151 152
152 m_requests.Clear(); 153 m_requests.Clear();
@@ -155,6 +156,7 @@ namespace OpenSim.Framework.Servers.HttpServer
155 { 156 {
156 t.Abort(); 157 t.Abort();
157 } 158 }
159
158 m_running = false; 160 m_running = false;
159 } 161 }
160 } 162 }
@@ -184,7 +186,7 @@ namespace OpenSim.Framework.Servers.HttpServer
184 private bool m_running = true; 186 private bool m_running = true;
185 private int slowCount = 0; 187 private int slowCount = 0;
186 188
187// private int m_timeout = 1000; // increase timeout 250; now use the event one 189 // private int m_timeout = 250; // increase timeout 250; now use the event one
188 190
189 public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout) 191 public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout)
190 { 192 {
@@ -202,6 +204,7 @@ namespace OpenSim.Framework.Servers.HttpServer
202 ThreadPriority.Normal, 204 ThreadPriority.Normal,
203 false, 205 false,
204 true, 206 true,
207 null,
205 int.MaxValue); 208 int.MaxValue);
206 } 209 }
207 210
@@ -211,6 +214,7 @@ namespace OpenSim.Framework.Servers.HttpServer
211 ThreadPriority.Normal, 214 ThreadPriority.Normal,
212 false, 215 false,
213 true, 216 true,
217 null,
214 1000 * 60 * 10); 218 1000 * 60 * 10);
215 } 219 }
216 220
@@ -368,8 +372,7 @@ namespace OpenSim.Framework.Servers.HttpServer
368 } 372 }
369 else 373 else
370 { 374 {
371// if ((Environment.TickCount - req.RequestTime) > m_timeout) 375 // if ((Environment.TickCount - req.RequestTime) > m_timeout)
372
373 if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) 376 if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
374 { 377 {
375 m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), 378 m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id),
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
index 7cd27e5..1e3fbf0 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
@@ -94,8 +94,7 @@ namespace OpenSim.Framework.Servers.HttpServer
94 try 94 try
95 { 95 {
96 Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); 96 Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd());
97 m_server.DoHTTPGruntWork(responsedata, 97 DoHTTPGruntWork(m_server, req, responsedata);
98 new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext));
99 } 98 }
100 catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream 99 catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
101 { 100 {
@@ -106,8 +105,10 @@ namespace OpenSim.Framework.Servers.HttpServer
106 { 105 {
107 if ((Environment.TickCount - req.RequestTime) > m_timeout) 106 if ((Environment.TickCount - req.RequestTime) > m_timeout)
108 { 107 {
109 m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), 108 DoHTTPGruntWork(
110 new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext)); 109 m_server,
110 req,
111 req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
111 } 112 }
112 else 113 else
113 { 114 {
@@ -128,6 +129,46 @@ namespace OpenSim.Framework.Servers.HttpServer
128 { 129 {
129 m_request.Enqueue(pPollServiceHttpRequest); 130 m_request.Enqueue(pPollServiceHttpRequest);
130 } 131 }
132
133 /// <summary>
134 /// FIXME: This should be part of BaseHttpServer
135 /// </summary>
136 internal static void DoHTTPGruntWork(BaseHttpServer server, PollServiceHttpRequest req, Hashtable responsedata)
137 {
138 OSHttpResponse response
139 = new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext);
140
141 byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
142
143 response.SendChunked = false;
144 response.ContentLength64 = buffer.Length;
145 response.ContentEncoding = Encoding.UTF8;
146
147 try
148 {
149 response.OutputStream.Write(buffer, 0, buffer.Length);
150 }
151 catch (Exception ex)
152 {
153 m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex));
154 }
155 finally
156 {
157 //response.OutputStream.Close();
158 try
159 {
160 response.OutputStream.Flush();
161 response.Send();
162
163 //if (!response.KeepAlive && response.ReuseContext)
164 // response.FreeContext();
165 }
166 catch (Exception e)
167 {
168 m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e));
169 }
170 }
171 }
131 } 172 }
132} 173}
133*/ \ No newline at end of file 174*/ \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
index a467a83..07082a8 100644
--- a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
@@ -39,7 +39,11 @@ namespace OpenSim.Framework.Servers.HttpServer
39 private RestDeserialiseMethod<TRequest, TResponse> m_method; 39 private RestDeserialiseMethod<TRequest, TResponse> m_method;
40 40
41 public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method) 41 public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method)
42 : base(httpMethod, path) 42 : this(httpMethod, path, method, null, null) {}
43
44 public RestDeserialiseHandler(
45 string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method, string name, string description)
46 : base(httpMethod, path, name, description)
43 { 47 {
44 m_method = method; 48 m_method = method;
45 } 49 }
diff --git a/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs
index 1f23cac..7f89839 100644
--- a/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs
@@ -38,19 +38,25 @@ namespace OpenSim.Framework.Servers.HttpServer
38 get { return m_dhttpMethod; } 38 get { return m_dhttpMethod; }
39 } 39 }
40 40
41 public override Hashtable Handle(string path, Hashtable request) 41 public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod)
42 : base(httpMethod, path)
42 { 43 {
44 m_dhttpMethod = dhttpMethod;
45 }
46
47 public RestHTTPHandler(
48 string httpMethod, string path, GenericHTTPMethod dhttpMethod, string name, string description)
49 : base(httpMethod, path, name, description)
50 {
51 m_dhttpMethod = dhttpMethod;
52 }
43 53
54 public override Hashtable Handle(string path, Hashtable request)
55 {
44 string param = GetParam(path); 56 string param = GetParam(path);
45 request.Add("param", param); 57 request.Add("param", param);
46 request.Add("path", path); 58 request.Add("path", path);
47 return m_dhttpMethod(request); 59 return m_dhttpMethod(request);
48 } 60 }
49
50 public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod)
51 : base(httpMethod, path)
52 {
53 m_dhttpMethod = dhttpMethod;
54 }
55 } 61 }
56} 62}
diff --git a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs
index d2c4002..1f17fee 100644
--- a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs
@@ -39,6 +39,15 @@ namespace OpenSim.Framework.Servers.HttpServer
39 get { return m_restMethod; } 39 get { return m_restMethod; }
40 } 40 }
41 41
42 public RestStreamHandler(string httpMethod, string path, RestMethod restMethod)
43 : this(httpMethod, path, restMethod, null, null) {}
44
45 public RestStreamHandler(string httpMethod, string path, RestMethod restMethod, string name, string description)
46 : base(httpMethod, path, name, description)
47 {
48 m_restMethod = restMethod;
49 }
50
42 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 51 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
43 { 52 {
44 Encoding encoding = Encoding.UTF8; 53 Encoding encoding = Encoding.UTF8;
@@ -52,10 +61,5 @@ namespace OpenSim.Framework.Servers.HttpServer
52 61
53 return Encoding.UTF8.GetBytes(responseString); 62 return Encoding.UTF8.GetBytes(responseString);
54 } 63 }
55
56 public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base(httpMethod, path)
57 {
58 m_restMethod = restMethod;
59 }
60 } 64 }
61} 65}
diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs
index b8ab8d9..8dc0e3a 100644
--- a/OpenSim/Framework/Servers/MainServer.cs
+++ b/OpenSim/Framework/Servers/MainServer.cs
@@ -25,57 +25,209 @@
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
28using System;
28using System.Collections.Generic; 29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using System.Net; 31using System.Net;
31using log4net; 32using log4net;
33using OpenSim.Framework;
34using OpenSim.Framework.Console;
32using OpenSim.Framework.Servers.HttpServer; 35using OpenSim.Framework.Servers.HttpServer;
33 36
34namespace OpenSim.Framework.Servers 37namespace OpenSim.Framework.Servers
35{ 38{
36 public class MainServer 39 public class MainServer
37 { 40 {
38 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 41// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
39 42
40 private static BaseHttpServer instance = null; 43 private static BaseHttpServer instance = null;
41 private static Dictionary<uint, BaseHttpServer> m_Servers = 44 private static Dictionary<uint, BaseHttpServer> m_Servers = new Dictionary<uint, BaseHttpServer>();
42 new Dictionary<uint, BaseHttpServer>();
43 45
46 /// <summary>
47 /// Control the printing of certain debug messages.
48 /// </summary>
49 /// <remarks>
50 /// If DebugLevel >= 1, then short warnings are logged when receiving bad input data.
51 /// If DebugLevel >= 2, then long warnings are logged when receiving bad input data.
52 /// If DebugLevel >= 3, then short notices about all incoming non-poll HTTP requests are logged.
53 /// </remarks>
54 public static int DebugLevel
55 {
56 get { return s_debugLevel; }
57 set
58 {
59 s_debugLevel = value;
60
61 lock (m_Servers)
62 foreach (BaseHttpServer server in m_Servers.Values)
63 server.DebugLevel = s_debugLevel;
64 }
65 }
66
67 private static int s_debugLevel;
68
69 /// <summary>
70 /// Set the main HTTP server instance.
71 /// </summary>
72 /// <remarks>
73 /// This will be used to register all handlers that listen to the default port.
74 /// </remarks>
75 /// <exception cref='Exception'>
76 /// Thrown if the HTTP server has not already been registered via AddHttpServer()
77 /// </exception>
44 public static BaseHttpServer Instance 78 public static BaseHttpServer Instance
45 { 79 {
46 get { return instance; } 80 get { return instance; }
47 set { instance = value; } 81
82 set
83 {
84 lock (m_Servers)
85 if (!m_Servers.ContainsValue(value))
86 throw new Exception("HTTP server must already have been registered to be set as the main instance");
87
88 instance = value;
89 }
48 } 90 }
49 91
50 public static IHttpServer GetHttpServer(uint port) 92 /// <summary>
93 /// Get all the registered servers.
94 /// </summary>
95 /// <remarks>
96 /// Returns a copy of the dictionary so this can be iterated through without locking.
97 /// </remarks>
98 /// <value></value>
99 public static Dictionary<uint, BaseHttpServer> Servers
100 {
101 get { return new Dictionary<uint, BaseHttpServer>(m_Servers); }
102 }
103
104
105 public static void RegisterHttpConsoleCommands(ICommandConsole console)
106 {
107 console.Commands.AddCommand(
108 "Debug", false, "debug http", "debug http [<level>]",
109 "Turn on inbound non-poll http request debugging.",
110 "If level <= 0, then no extra logging is done.\n"
111 + "If level >= 1, then short warnings are logged when receiving bad input data.\n"
112 + "If level >= 2, then long warnings are logged when receiving bad input data.\n"
113 + "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n"
114 + "If no level is specified then the current level is returned.",
115 HandleDebugHttpCommand);
116 }
117
118 /// <summary>
119 /// Turn on some debugging values for OpenSim.
120 /// </summary>
121 /// <param name="args"></param>
122 private static void HandleDebugHttpCommand(string module, string[] args)
51 { 123 {
52 return GetHttpServer(port,null); 124 if (args.Length == 3)
125 {
126 int newDebug;
127 if (int.TryParse(args[2], out newDebug))
128 {
129 MainServer.DebugLevel = newDebug;
130 MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug);
131 }
132 }
133 else if (args.Length == 2)
134 {
135 MainConsole.Instance.OutputFormat("Current debug http level is {0}", MainServer.DebugLevel);
136 }
137 else
138 {
139 MainConsole.Instance.Output("Usage: debug http 0..3");
140 }
53 } 141 }
54 142
143 /// <summary>
144 /// Register an already started HTTP server to the collection of known servers.
145 /// </summary>
146 /// <param name='server'></param>
55 public static void AddHttpServer(BaseHttpServer server) 147 public static void AddHttpServer(BaseHttpServer server)
56 { 148 {
57 m_Servers.Add(server.Port, server); 149 lock (m_Servers)
150 {
151 if (m_Servers.ContainsKey(server.Port))
152 throw new Exception(string.Format("HTTP server for port {0} already exists.", server.Port));
153
154 m_Servers.Add(server.Port, server);
155 }
156 }
157
158 /// <summary>
159 /// Removes the http server listening on the given port.
160 /// </summary>
161 /// <remarks>
162 /// It is the responsibility of the caller to do clean up.
163 /// </remarks>
164 /// <param name='port'></param>
165 /// <returns></returns>
166 public static bool RemoveHttpServer(uint port)
167 {
168 lock (m_Servers)
169 return m_Servers.Remove(port);
170 }
171
172 /// <summary>
173 /// Does this collection of servers contain one with the given port?
174 /// </summary>
175 /// <remarks>
176 /// Unlike GetHttpServer, this will not instantiate a server if one does not exist on that port.
177 /// </remarks>
178 /// <param name='port'></param>
179 /// <returns>true if a server with the given port is registered, false otherwise.</returns>
180 public static bool ContainsHttpServer(uint port)
181 {
182 lock (m_Servers)
183 return m_Servers.ContainsKey(port);
58 } 184 }
59 185
186 /// <summary>
187 /// Get the default http server or an http server for a specific port.
188 /// </summary>
189 /// <remarks>
190 /// If the requested HTTP server doesn't already exist then a new one is instantiated and started.
191 /// </remarks>
192 /// <returns></returns>
193 /// <param name='port'>If 0 then the default HTTP server is returned.</param>
194 public static IHttpServer GetHttpServer(uint port)
195 {
196 return GetHttpServer(port, null);
197 }
198
199 /// <summary>
200 /// Get the default http server, an http server for a specific port
201 /// and/or an http server bound to a specific address
202 /// </summary>
203 /// <remarks>
204 /// If the requested HTTP server doesn't already exist then a new one is instantiated and started.
205 /// </remarks>
206 /// <returns></returns>
207 /// <param name='port'>If 0 then the default HTTP server is returned.</param>
208 /// <param name='ipaddr'>A specific IP address to bind to. If null then the default IP address is used.</param>
60 public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr) 209 public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr)
61 { 210 {
62 if (port == 0) 211 if (port == 0)
63 return Instance; 212 return Instance;
213
64 if (instance != null && port == Instance.Port) 214 if (instance != null && port == Instance.Port)
65 return Instance; 215 return Instance;
66 216
67 if (m_Servers.ContainsKey(port)) 217 lock (m_Servers)
68 return m_Servers[port]; 218 {
219 if (m_Servers.ContainsKey(port))
220 return m_Servers[port];
69 221
70 m_Servers[port] = new BaseHttpServer(port); 222 m_Servers[port] = new BaseHttpServer(port);
71 223
72 if (ipaddr != null) 224 if (ipaddr != null)
73 m_Servers[port].ListenIPAddress = ipaddr; 225 m_Servers[port].ListenIPAddress = ipaddr;
74 226
75 m_log.InfoFormat("[MAIN HTTP SERVER]: Starting main http server on port {0}", port); 227 m_Servers[port].Start();
76 m_Servers[port].Start();
77 228
78 return m_Servers[port]; 229 return m_Servers[port];
230 }
79 } 231 }
80 } 232 }
81} 233} \ No newline at end of file