diff options
author | Justin Clark-Casey (justincc) | 2012-06-13 00:03:44 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-06-13 00:03:44 +0100 |
commit | c6e375291a8fa3dbdcbd25cfb64bf0d536707fb0 (patch) | |
tree | 1d86b771a74c688932ea51160cd648cfe9b45829 | |
parent | Remove accidental timeout left in during earlier debugging. Has been in sinc... (diff) | |
download | opensim-SC_OLD-c6e375291a8fa3dbdcbd25cfb64bf0d536707fb0.zip opensim-SC_OLD-c6e375291a8fa3dbdcbd25cfb64bf0d536707fb0.tar.gz opensim-SC_OLD-c6e375291a8fa3dbdcbd25cfb64bf0d536707fb0.tar.bz2 opensim-SC_OLD-c6e375291a8fa3dbdcbd25cfb64bf0d536707fb0.tar.xz |
Don't include time to transmit response back to requester when assessing slow handling of requests.
This is to avoid logging a 'slow' request when the source of delay is the viewer in processing a response.
This is not something we can do much about on the server end - it's server-side delay that we're interested in.
To ensure consistency, this commit also had to refactor and simplify inbound non-poll network request handling, though there should be no functional change.
IOSHttpResponse no longer exposes the Send() method, only classes in OpenSim.Framework.Servers.HttpServer should be doing this.
Only the GetTextureHandler was sending its own response. Now it leaves this to BaseHttpServer, like all other core handlers.
7 files changed, 169 insertions, 317 deletions
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs index db62d52..cb88695 100644 --- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs +++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs | |||
@@ -539,7 +539,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory | |||
539 | /// path has not already been registered, the method is added to the active | 539 | /// path has not already been registered, the method is added to the active |
540 | /// handler table. | 540 | /// handler table. |
541 | /// </summary> | 541 | /// </summary> |
542 | |||
543 | public void AddStreamHandler(string httpMethod, string path, RestMethod method) | 542 | public void AddStreamHandler(string httpMethod, string path, RestMethod method) |
544 | { | 543 | { |
545 | if (!IsEnabled) | 544 | if (!IsEnabled) |
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index abdbc72..ae6c44b 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs | |||
@@ -77,7 +77,6 @@ namespace OpenSim.Capabilities.Handlers | |||
77 | { | 77 | { |
78 | m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); | 78 | m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); |
79 | httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; | 79 | httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; |
80 | return null; | ||
81 | } | 80 | } |
82 | 81 | ||
83 | UUID textureID; | 82 | UUID textureID; |
@@ -115,7 +114,6 @@ namespace OpenSim.Capabilities.Handlers | |||
115 | // "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}", | 114 | // "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}", |
116 | // textureID, httpResponse.StatusCode, httpResponse.ContentLength); | 115 | // textureID, httpResponse.StatusCode, httpResponse.ContentLength); |
117 | 116 | ||
118 | httpResponse.Send(); | ||
119 | return null; | 117 | return null; |
120 | } | 118 | } |
121 | 119 | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 401dfd3..ef6e259 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | |||
@@ -408,7 +408,10 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
408 | string uriString = request.RawUrl; | 408 | string uriString = request.RawUrl; |
409 | 409 | ||
410 | // string reqnum = "unknown"; | 410 | // string reqnum = "unknown"; |
411 | int tickstart = Environment.TickCount; | 411 | int requestStartTick = Environment.TickCount; |
412 | |||
413 | // Will be adjusted later on. | ||
414 | int requestEndTick = requestStartTick; | ||
412 | 415 | ||
413 | IRequestHandler requestHandler = null; | 416 | IRequestHandler requestHandler = null; |
414 | 417 | ||
@@ -433,6 +436,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
433 | { | 436 | { |
434 | if (HandleAgentRequest(agentHandler, request, response)) | 437 | if (HandleAgentRequest(agentHandler, request, response)) |
435 | { | 438 | { |
439 | requestEndTick = Environment.TickCount; | ||
436 | return; | 440 | return; |
437 | } | 441 | } |
438 | } | 442 | } |
@@ -442,6 +446,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
442 | 446 | ||
443 | string path = request.RawUrl; | 447 | string path = request.RawUrl; |
444 | string handlerKey = GetHandlerKey(request.HttpMethod, path); | 448 | string handlerKey = GetHandlerKey(request.HttpMethod, path); |
449 | byte[] buffer = null; | ||
445 | 450 | ||
446 | if (TryGetStreamHandler(handlerKey, out requestHandler)) | 451 | if (TryGetStreamHandler(handlerKey, out requestHandler)) |
447 | { | 452 | { |
@@ -450,9 +455,6 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
450 | "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}", | 455 | "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}", |
451 | request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description); | 456 | request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description); |
452 | 457 | ||
453 | // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler. | ||
454 | byte[] buffer = null; | ||
455 | |||
456 | response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. | 458 | response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. |
457 | 459 | ||
458 | if (requestHandler is IStreamedRequestHandler) | 460 | if (requestHandler is IStreamedRequestHandler) |
@@ -507,8 +509,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
507 | //m_log.Warn("[HTTP]: " + requestBody); | 509 | //m_log.Warn("[HTTP]: " + requestBody); |
508 | 510 | ||
509 | } | 511 | } |
510 | DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response); | 512 | |
511 | return; | 513 | buffer = DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response); |
512 | } | 514 | } |
513 | else | 515 | else |
514 | { | 516 | { |
@@ -521,133 +523,100 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
521 | buffer = memoryStream.ToArray(); | 523 | buffer = memoryStream.ToArray(); |
522 | } | 524 | } |
523 | } | 525 | } |
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.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); | ||
555 | } | ||
556 | catch (IOException e) | ||
557 | { | ||
558 | m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}. ", e.Message), e); | ||
559 | } | ||
560 | |||
561 | return; | ||
562 | } | 526 | } |
563 | 527 | else | |
564 | if (request.AcceptTypes != null && request.AcceptTypes.Length > 0) | ||
565 | { | 528 | { |
566 | foreach (string strAccept in request.AcceptTypes) | 529 | switch (request.ContentType) |
567 | { | 530 | { |
568 | if (strAccept.Contains("application/llsd+xml") || | 531 | case null: |
569 | strAccept.Contains("application/llsd+json")) | 532 | case "text/html": |
570 | { | 533 | |
571 | if (DebugLevel >= 1) | ||
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) | 534 | if (DebugLevel >= 1) |
621 | m_log.DebugFormat( | 535 | m_log.DebugFormat( |
622 | "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", | 536 | "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", |
623 | request.ContentType, request.HttpMethod, request.Url.PathAndQuery); | 537 | request.ContentType, request.HttpMethod, request.Url.PathAndQuery); |
624 | 538 | ||
625 | HandleLLSDRequests(request, response); | 539 | buffer = HandleHTTPRequest(request, response); |
626 | return; | 540 | break; |
627 | } | 541 | |
628 | 542 | case "application/llsd+xml": | |
629 | // m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl); | 543 | case "application/xml+llsd": |
630 | if (DoWeHaveAHTTPHandler(request.RawUrl)) | 544 | case "application/llsd+json": |
631 | { | 545 | |
632 | if (DebugLevel >= 1) | 546 | if (DebugLevel >= 1) |
633 | m_log.DebugFormat( | 547 | m_log.DebugFormat( |
634 | "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", | 548 | "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", |
635 | request.ContentType, request.HttpMethod, request.Url.PathAndQuery); | 549 | request.ContentType, request.HttpMethod, request.Url.PathAndQuery); |
550 | |||
551 | buffer = HandleLLSDRequests(request, response); | ||
552 | break; | ||
553 | |||
554 | case "text/xml": | ||
555 | case "application/xml": | ||
556 | case "application/json": | ||
557 | default: | ||
558 | //m_log.Info("[Debug BASE HTTP SERVER]: in default handler"); | ||
559 | // Point of note.. the DoWeHaveA methods check for an EXACT path | ||
560 | // if (request.RawUrl.Contains("/CAPS/EQG")) | ||
561 | // { | ||
562 | // int i = 1; | ||
563 | // } | ||
564 | //m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler"); | ||
565 | if (DoWeHaveALLSDHandler(request.RawUrl)) | ||
566 | { | ||
567 | if (DebugLevel >= 1) | ||
568 | m_log.DebugFormat( | ||
569 | "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", | ||
570 | request.ContentType, request.HttpMethod, request.Url.PathAndQuery); | ||
571 | |||
572 | buffer = HandleLLSDRequests(request, response); | ||
573 | } | ||
574 | // m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl); | ||
575 | else if (DoWeHaveAHTTPHandler(request.RawUrl)) | ||
576 | { | ||
577 | if (DebugLevel >= 1) | ||
578 | m_log.DebugFormat( | ||
579 | "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", | ||
580 | request.ContentType, request.HttpMethod, request.Url.PathAndQuery); | ||
581 | |||
582 | buffer = HandleHTTPRequest(request, response); | ||
583 | } | ||
584 | else | ||
585 | { | ||
586 | |||
587 | if (DebugLevel >= 1) | ||
588 | m_log.DebugFormat( | ||
589 | "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}", | ||
590 | request.HttpMethod, request.Url.PathAndQuery); | ||
591 | |||
592 | // generic login request. | ||
593 | buffer = HandleXmlRpcRequests(request, response); | ||
594 | } | ||
595 | |||
596 | break; | ||
597 | } | ||
598 | } | ||
636 | 599 | ||
637 | HandleHTTPRequest(request, response); | 600 | 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 | 601 | ||
646 | // generic login request. | 602 | if (buffer != null) |
647 | HandleXmlRpcRequests(request, response); | 603 | { |
604 | if (!response.SendChunked) | ||
605 | response.ContentLength64 = buffer.LongLength; | ||
648 | 606 | ||
649 | return; | 607 | response.OutputStream.Write(buffer, 0, buffer.Length); |
650 | } | 608 | } |
609 | |||
610 | // Do not include the time taken to actually send the response to the caller in the measurement | ||
611 | // time. This is to avoid logging when it's the client that is slow to process rather than the | ||
612 | // server | ||
613 | requestEndTick = Environment.TickCount; | ||
614 | |||
615 | response.Send(); | ||
616 | |||
617 | //response.OutputStream.Close(); | ||
618 | |||
619 | //response.FreeContext(); | ||
651 | } | 620 | } |
652 | catch (SocketException e) | 621 | catch (SocketException e) |
653 | { | 622 | { |
@@ -672,8 +641,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
672 | finally | 641 | finally |
673 | { | 642 | { |
674 | // Every month or so this will wrap and give bad numbers, not really a problem | 643 | // 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 | 644 | // since its just for reporting |
676 | int tickdiff = Environment.TickCount - tickstart; | 645 | int tickdiff = requestEndTick - requestStartTick; |
677 | if (tickdiff > 3000) | 646 | if (tickdiff > 3000) |
678 | { | 647 | { |
679 | m_log.InfoFormat( | 648 | m_log.InfoFormat( |
@@ -805,7 +774,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
805 | /// </summary> | 774 | /// </summary> |
806 | /// <param name="request"></param> | 775 | /// <param name="request"></param> |
807 | /// <param name="response"></param> | 776 | /// <param name="response"></param> |
808 | private void HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response) | 777 | private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response) |
809 | { | 778 | { |
810 | Stream requestStream = request.InputStream; | 779 | Stream requestStream = request.InputStream; |
811 | 780 | ||
@@ -817,7 +786,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
817 | requestStream.Close(); | 786 | requestStream.Close(); |
818 | //m_log.Debug(requestBody); | 787 | //m_log.Debug(requestBody); |
819 | requestBody = requestBody.Replace("<base64></base64>", ""); | 788 | requestBody = requestBody.Replace("<base64></base64>", ""); |
820 | string responseString = String.Empty; | 789 | string responseString = null; |
821 | XmlRpcRequest xmlRprcRequest = null; | 790 | XmlRpcRequest xmlRprcRequest = null; |
822 | 791 | ||
823 | try | 792 | try |
@@ -895,6 +864,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
895 | String.Format("Requested method [{0}] not found", methodName)); | 864 | String.Format("Requested method [{0}] not found", methodName)); |
896 | } | 865 | } |
897 | 866 | ||
867 | response.ContentType = "text/xml"; | ||
898 | responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse); | 868 | responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse); |
899 | } | 869 | } |
900 | else | 870 | else |
@@ -904,82 +874,25 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
904 | response.StatusCode = 404; | 874 | response.StatusCode = 404; |
905 | response.StatusDescription = "Not Found"; | 875 | response.StatusDescription = "Not Found"; |
906 | response.ProtocolVersion = "HTTP/1.0"; | 876 | response.ProtocolVersion = "HTTP/1.0"; |
907 | byte[] buf = Encoding.UTF8.GetBytes("Not found"); | 877 | responseString = "Not found"; |
908 | response.KeepAlive = false; | 878 | response.KeepAlive = false; |
909 | 879 | ||
910 | m_log.ErrorFormat( | 880 | m_log.ErrorFormat( |
911 | "[BASE HTTP SERVER]: Handler not found for http request {0} {1}", | 881 | "[BASE HTTP SERVER]: Handler not found for http request {0} {1}", |
912 | request.HttpMethod, request.Url.PathAndQuery); | 882 | request.HttpMethod, request.Url.PathAndQuery); |
913 | |||
914 | response.SendChunked = false; | ||
915 | response.ContentLength64 = buf.Length; | ||
916 | response.ContentEncoding = Encoding.UTF8; | ||
917 | |||
918 | try | ||
919 | { | ||
920 | response.OutputStream.Write(buf, 0, buf.Length); | ||
921 | } | ||
922 | catch (Exception ex) | ||
923 | { | ||
924 | m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message); | ||
925 | } | ||
926 | finally | ||
927 | { | ||
928 | try | ||
929 | { | ||
930 | response.Send(); | ||
931 | //response.FreeContext(); | ||
932 | } | ||
933 | catch (SocketException e) | ||
934 | { | ||
935 | // This has to be here to prevent a Linux/Mono crash | ||
936 | m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); | ||
937 | } | ||
938 | catch (IOException e) | ||
939 | { | ||
940 | m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e); | ||
941 | } | ||
942 | } | ||
943 | return; | ||
944 | //responseString = "Error"; | ||
945 | } | 883 | } |
946 | } | 884 | } |
947 | 885 | ||
948 | response.ContentType = "text/xml"; | ||
949 | |||
950 | byte[] buffer = Encoding.UTF8.GetBytes(responseString); | 886 | byte[] buffer = Encoding.UTF8.GetBytes(responseString); |
951 | 887 | ||
952 | response.SendChunked = false; | 888 | response.SendChunked = false; |
953 | response.ContentLength64 = buffer.Length; | 889 | response.ContentLength64 = buffer.Length; |
954 | response.ContentEncoding = Encoding.UTF8; | 890 | response.ContentEncoding = Encoding.UTF8; |
955 | try | 891 | |
956 | { | 892 | return buffer; |
957 | response.OutputStream.Write(buffer, 0, buffer.Length); | ||
958 | } | ||
959 | catch (Exception ex) | ||
960 | { | ||
961 | m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message); | ||
962 | } | ||
963 | finally | ||
964 | { | ||
965 | try | ||
966 | { | ||
967 | response.Send(); | ||
968 | //response.FreeContext(); | ||
969 | } | ||
970 | catch (SocketException e) | ||
971 | { | ||
972 | // This has to be here to prevent a Linux/Mono crash | ||
973 | m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); | ||
974 | } | ||
975 | catch (IOException e) | ||
976 | { | ||
977 | m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e); | ||
978 | } | ||
979 | } | ||
980 | } | 893 | } |
981 | 894 | ||
982 | private void HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response) | 895 | private byte[] HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response) |
983 | { | 896 | { |
984 | //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); | 897 | //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); |
985 | Stream requestStream = request.InputStream; | 898 | Stream requestStream = request.InputStream; |
@@ -1065,34 +978,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1065 | response.ContentEncoding = Encoding.UTF8; | 978 | response.ContentEncoding = Encoding.UTF8; |
1066 | response.KeepAlive = true; | 979 | response.KeepAlive = true; |
1067 | 980 | ||
1068 | try | 981 | return buffer; |
1069 | { | ||
1070 | response.OutputStream.Write(buffer, 0, buffer.Length); | ||
1071 | } | ||
1072 | catch (Exception ex) | ||
1073 | { | ||
1074 | m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message); | ||
1075 | } | ||
1076 | finally | ||
1077 | { | ||
1078 | //response.OutputStream.Close(); | ||
1079 | try | ||
1080 | { | ||
1081 | response.Send(); | ||
1082 | response.OutputStream.Flush(); | ||
1083 | //response.FreeContext(); | ||
1084 | //response.OutputStream.Close(); | ||
1085 | } | ||
1086 | catch (IOException e) | ||
1087 | { | ||
1088 | m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD IOException {0} ", e.Message), e); | ||
1089 | } | ||
1090 | catch (SocketException e) | ||
1091 | { | ||
1092 | // This has to be here to prevent a Linux/Mono crash | ||
1093 | m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); | ||
1094 | } | ||
1095 | } | ||
1096 | } | 982 | } |
1097 | 983 | ||
1098 | private byte[] BuildLLSDResponse(OSHttpRequest request, OSHttpResponse response, OSD llsdResponse) | 984 | private byte[] BuildLLSDResponse(OSHttpRequest request, OSHttpResponse response, OSD llsdResponse) |
@@ -1357,7 +1243,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1357 | 1243 | ||
1358 | } | 1244 | } |
1359 | 1245 | ||
1360 | public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response) | 1246 | public byte[] HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response) |
1361 | { | 1247 | { |
1362 | // m_log.DebugFormat( | 1248 | // m_log.DebugFormat( |
1363 | // "[BASE HTTP SERVER]: HandleHTTPRequest for request to {0}, method {1}", | 1249 | // "[BASE HTTP SERVER]: HandleHTTPRequest for request to {0}, method {1}", |
@@ -1367,15 +1253,14 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1367 | { | 1253 | { |
1368 | case "OPTIONS": | 1254 | case "OPTIONS": |
1369 | response.StatusCode = (int)OSHttpStatusCode.SuccessOk; | 1255 | response.StatusCode = (int)OSHttpStatusCode.SuccessOk; |
1370 | return; | 1256 | return null; |
1371 | 1257 | ||
1372 | default: | 1258 | default: |
1373 | HandleContentVerbs(request, response); | 1259 | return HandleContentVerbs(request, response); |
1374 | return; | ||
1375 | } | 1260 | } |
1376 | } | 1261 | } |
1377 | 1262 | ||
1378 | private void HandleContentVerbs(OSHttpRequest request, OSHttpResponse response) | 1263 | private byte[] HandleContentVerbs(OSHttpRequest request, OSHttpResponse response) |
1379 | { | 1264 | { |
1380 | // m_log.DebugFormat("[BASE HTTP SERVER]: HandleContentVerbs for request to {0}", request.RawUrl); | 1265 | // m_log.DebugFormat("[BASE HTTP SERVER]: HandleContentVerbs for request to {0}", request.RawUrl); |
1381 | 1266 | ||
@@ -1391,6 +1276,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1391 | // to display the form, or process it. | 1276 | // to display the form, or process it. |
1392 | // a better way would be nifty. | 1277 | // a better way would be nifty. |
1393 | 1278 | ||
1279 | byte[] buffer; | ||
1280 | |||
1394 | Stream requestStream = request.InputStream; | 1281 | Stream requestStream = request.InputStream; |
1395 | 1282 | ||
1396 | Encoding encoding = Encoding.UTF8; | 1283 | Encoding encoding = Encoding.UTF8; |
@@ -1451,14 +1338,14 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1451 | if (foundHandler) | 1338 | if (foundHandler) |
1452 | { | 1339 | { |
1453 | Hashtable responsedata1 = requestprocessor(keysvals); | 1340 | Hashtable responsedata1 = requestprocessor(keysvals); |
1454 | DoHTTPGruntWork(responsedata1,response); | 1341 | buffer = DoHTTPGruntWork(responsedata1,response); |
1455 | 1342 | ||
1456 | //SendHTML500(response); | 1343 | //SendHTML500(response); |
1457 | } | 1344 | } |
1458 | else | 1345 | else |
1459 | { | 1346 | { |
1460 | // m_log.Warn("[BASE HTTP SERVER]: Handler Not Found"); | 1347 | // m_log.Warn("[BASE HTTP SERVER]: Handler Not Found"); |
1461 | SendHTML404(response, host); | 1348 | buffer = SendHTML404(response, host); |
1462 | } | 1349 | } |
1463 | } | 1350 | } |
1464 | else | 1351 | else |
@@ -1468,16 +1355,18 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1468 | if (foundHandler) | 1355 | if (foundHandler) |
1469 | { | 1356 | { |
1470 | Hashtable responsedata2 = requestprocessor(keysvals); | 1357 | Hashtable responsedata2 = requestprocessor(keysvals); |
1471 | DoHTTPGruntWork(responsedata2, response); | 1358 | buffer = DoHTTPGruntWork(responsedata2, response); |
1472 | 1359 | ||
1473 | //SendHTML500(response); | 1360 | //SendHTML500(response); |
1474 | } | 1361 | } |
1475 | else | 1362 | else |
1476 | { | 1363 | { |
1477 | // m_log.Warn("[BASE HTTP SERVER]: Handler Not Found2"); | 1364 | // m_log.Warn("[BASE HTTP SERVER]: Handler Not Found2"); |
1478 | SendHTML404(response, host); | 1365 | buffer = SendHTML404(response, host); |
1479 | } | 1366 | } |
1480 | } | 1367 | } |
1368 | |||
1369 | return buffer; | ||
1481 | } | 1370 | } |
1482 | 1371 | ||
1483 | private bool TryGetHTTPHandlerPathBased(string path, out GenericHTTPMethod httpHandler) | 1372 | private bool TryGetHTTPHandlerPathBased(string path, out GenericHTTPMethod httpHandler) |
@@ -1545,14 +1434,13 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1545 | } | 1434 | } |
1546 | } | 1435 | } |
1547 | 1436 | ||
1548 | internal void DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) | 1437 | internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) |
1549 | { | 1438 | { |
1550 | //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); | 1439 | //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); |
1551 | int responsecode = (int)responsedata["int_response_code"]; | 1440 | int responsecode = (int)responsedata["int_response_code"]; |
1552 | string responseString = (string)responsedata["str_response_string"]; | 1441 | string responseString = (string)responsedata["str_response_string"]; |
1553 | string contentType = (string)responsedata["content_type"]; | 1442 | string contentType = (string)responsedata["content_type"]; |
1554 | 1443 | ||
1555 | |||
1556 | if (responsedata.ContainsKey("error_status_text")) | 1444 | if (responsedata.ContainsKey("error_status_text")) |
1557 | { | 1445 | { |
1558 | response.StatusDescription = (string)responsedata["error_status_text"]; | 1446 | response.StatusDescription = (string)responsedata["error_status_text"]; |
@@ -1616,38 +1504,10 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1616 | response.ContentLength64 = buffer.Length; | 1504 | response.ContentLength64 = buffer.Length; |
1617 | response.ContentEncoding = Encoding.UTF8; | 1505 | response.ContentEncoding = Encoding.UTF8; |
1618 | 1506 | ||
1619 | try | 1507 | return buffer; |
1620 | { | ||
1621 | response.OutputStream.Write(buffer, 0, buffer.Length); | ||
1622 | } | ||
1623 | catch (Exception ex) | ||
1624 | { | ||
1625 | m_log.Warn("[HTTPD]: Error - " + ex.Message); | ||
1626 | } | ||
1627 | finally | ||
1628 | { | ||
1629 | //response.OutputStream.Close(); | ||
1630 | try | ||
1631 | { | ||
1632 | response.OutputStream.Flush(); | ||
1633 | response.Send(); | ||
1634 | |||
1635 | //if (!response.KeepAlive && response.ReuseContext) | ||
1636 | // response.FreeContext(); | ||
1637 | } | ||
1638 | catch (SocketException e) | ||
1639 | { | ||
1640 | // This has to be here to prevent a Linux/Mono crash | ||
1641 | m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); | ||
1642 | } | ||
1643 | catch (IOException e) | ||
1644 | { | ||
1645 | m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e); | ||
1646 | } | ||
1647 | } | ||
1648 | } | 1508 | } |
1649 | 1509 | ||
1650 | public void SendHTML404(OSHttpResponse response, string host) | 1510 | public byte[] SendHTML404(OSHttpResponse response, string host) |
1651 | { | 1511 | { |
1652 | // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s | 1512 | // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s |
1653 | response.StatusCode = 404; | 1513 | response.StatusCode = 404; |
@@ -1660,31 +1520,10 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1660 | response.ContentLength64 = buffer.Length; | 1520 | response.ContentLength64 = buffer.Length; |
1661 | response.ContentEncoding = Encoding.UTF8; | 1521 | response.ContentEncoding = Encoding.UTF8; |
1662 | 1522 | ||
1663 | try | 1523 | return buffer; |
1664 | { | ||
1665 | response.OutputStream.Write(buffer, 0, buffer.Length); | ||
1666 | } | ||
1667 | catch (Exception ex) | ||
1668 | { | ||
1669 | m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message); | ||
1670 | } | ||
1671 | finally | ||
1672 | { | ||
1673 | //response.OutputStream.Close(); | ||
1674 | try | ||
1675 | { | ||
1676 | response.Send(); | ||
1677 | //response.FreeContext(); | ||
1678 | } | ||
1679 | catch (SocketException e) | ||
1680 | { | ||
1681 | // This has to be here to prevent a Linux/Mono crash | ||
1682 | m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); | ||
1683 | } | ||
1684 | } | ||
1685 | } | 1524 | } |
1686 | 1525 | ||
1687 | public void SendHTML500(OSHttpResponse response) | 1526 | public byte[] SendHTML500(OSHttpResponse response) |
1688 | { | 1527 | { |
1689 | // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s | 1528 | // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s |
1690 | response.StatusCode = (int)OSHttpStatusCode.SuccessOk; | 1529 | response.StatusCode = (int)OSHttpStatusCode.SuccessOk; |
@@ -1696,28 +1535,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1696 | response.SendChunked = false; | 1535 | response.SendChunked = false; |
1697 | response.ContentLength64 = buffer.Length; | 1536 | response.ContentLength64 = buffer.Length; |
1698 | response.ContentEncoding = Encoding.UTF8; | 1537 | response.ContentEncoding = Encoding.UTF8; |
1699 | try | 1538 | |
1700 | { | 1539 | return buffer; |
1701 | response.OutputStream.Write(buffer, 0, buffer.Length); | ||
1702 | } | ||
1703 | catch (Exception ex) | ||
1704 | { | ||
1705 | m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message); | ||
1706 | } | ||
1707 | finally | ||
1708 | { | ||
1709 | //response.OutputStream.Close(); | ||
1710 | try | ||
1711 | { | ||
1712 | response.Send(); | ||
1713 | //response.FreeContext(); | ||
1714 | } | ||
1715 | catch (SocketException e) | ||
1716 | { | ||
1717 | // This has to be here to prevent a Linux/Mono crash | ||
1718 | m_log.Warn(String.Format("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); | ||
1719 | } | ||
1720 | } | ||
1721 | } | 1540 | } |
1722 | 1541 | ||
1723 | public void Start() | 1542 | public void Start() |
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/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/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index f96fd1f..3252251 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | |||
@@ -140,9 +140,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
140 | foreach (object o in m_requests) | 140 | foreach (object o in m_requests) |
141 | { | 141 | { |
142 | PollServiceHttpRequest req = (PollServiceHttpRequest) o; | 142 | PollServiceHttpRequest req = (PollServiceHttpRequest) o; |
143 | m_server.DoHTTPGruntWork( | 143 | PollServiceWorkerThread.DoHTTPGruntWork( |
144 | req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), | 144 | m_server, req, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); |
145 | new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext)); | ||
146 | } | 145 | } |
147 | 146 | ||
148 | m_requests.Clear(); | 147 | m_requests.Clear(); |
@@ -151,6 +150,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
151 | { | 150 | { |
152 | t.Abort(); | 151 | t.Abort(); |
153 | } | 152 | } |
153 | |||
154 | m_running = false; | 154 | m_running = false; |
155 | } | 155 | } |
156 | } | 156 | } |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs index 5e171f0..2995421 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs | |||
@@ -90,15 +90,16 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
90 | } | 90 | } |
91 | 91 | ||
92 | Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); | 92 | Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); |
93 | m_server.DoHTTPGruntWork(responsedata, | 93 | DoHTTPGruntWork(m_server, req, responsedata); |
94 | new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext)); | ||
95 | } | 94 | } |
96 | else | 95 | else |
97 | { | 96 | { |
98 | if ((Environment.TickCount - req.RequestTime) > m_timeout) | 97 | if ((Environment.TickCount - req.RequestTime) > m_timeout) |
99 | { | 98 | { |
100 | m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), | 99 | DoHTTPGruntWork( |
101 | new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext)); | 100 | m_server, |
101 | req, | ||
102 | req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | ||
102 | } | 103 | } |
103 | else | 104 | else |
104 | { | 105 | { |
@@ -119,5 +120,47 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
119 | { | 120 | { |
120 | m_request.Enqueue(pPollServiceHttpRequest); | 121 | m_request.Enqueue(pPollServiceHttpRequest); |
121 | } | 122 | } |
123 | |||
124 | /// <summary> | ||
125 | /// FIXME: This should be part of BaseHttpServer | ||
126 | /// </summary> | ||
127 | internal static void DoHTTPGruntWork(BaseHttpServer server, PollServiceHttpRequest req, Hashtable responsedata) | ||
128 | { | ||
129 | OSHttpResponse response | ||
130 | = new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext); | ||
131 | |||
132 | byte[] buffer | ||
133 | = server.DoHTTPGruntWork( | ||
134 | responsedata, new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext)); | ||
135 | |||
136 | response.SendChunked = false; | ||
137 | response.ContentLength64 = buffer.Length; | ||
138 | response.ContentEncoding = Encoding.UTF8; | ||
139 | |||
140 | try | ||
141 | { | ||
142 | response.OutputStream.Write(buffer, 0, buffer.Length); | ||
143 | } | ||
144 | catch (Exception ex) | ||
145 | { | ||
146 | m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex)); | ||
147 | } | ||
148 | finally | ||
149 | { | ||
150 | //response.OutputStream.Close(); | ||
151 | try | ||
152 | { | ||
153 | response.OutputStream.Flush(); | ||
154 | response.Send(); | ||
155 | |||
156 | //if (!response.KeepAlive && response.ReuseContext) | ||
157 | // response.FreeContext(); | ||
158 | } | ||
159 | catch (Exception e) | ||
160 | { | ||
161 | m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e)); | ||
162 | } | ||
163 | } | ||
164 | } | ||
122 | } | 165 | } |
123 | } | 166 | } \ No newline at end of file |