diff options
Diffstat (limited to 'OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs')
-rw-r--r-- | OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 474 |
1 files changed, 158 insertions, 316 deletions
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(); |