diff options
author | ubit | 2012-07-17 02:07:21 +0200 |
---|---|---|
committer | ubit | 2012-07-17 02:07:21 +0200 |
commit | e925b0654d12c534ff9f837355ad43483dbd22cb (patch) | |
tree | e8a05e918e55ec8034dd724c38f143aac31493b2 /OpenSim/Framework/Servers | |
parent | Merge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork (diff) | |
parent | Merge branch 'avination' into ubitwork (diff) | |
download | opensim-SC-e925b0654d12c534ff9f837355ad43483dbd22cb.zip opensim-SC-e925b0654d12c534ff9f837355ad43483dbd22cb.tar.gz opensim-SC-e925b0654d12c534ff9f837355ad43483dbd22cb.tar.bz2 opensim-SC-e925b0654d12c534ff9f837355ad43483dbd22cb.tar.xz |
Merge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork
Diffstat (limited to '')
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 @@ | |||
28 | namespace OpenSim.Framework.Servers.HttpServer | 28 | namespace 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 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using OpenMetaverse; | 30 | using OpenMetaverse; |
31 | |||
31 | namespace OpenSim.Framework.Servers.HttpServer | 32 | namespace 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 | ||
32 | namespace OpenSim.Framework.Servers.HttpServer | 32 | namespace 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 | ||
28 | using System; | ||
28 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
29 | using System.Reflection; | 30 | using System.Reflection; |
30 | using System.Net; | 31 | using System.Net; |
31 | using log4net; | 32 | using log4net; |
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Framework.Console; | ||
32 | using OpenSim.Framework.Servers.HttpServer; | 35 | using OpenSim.Framework.Servers.HttpServer; |
33 | 36 | ||
34 | namespace OpenSim.Framework.Servers | 37 | namespace 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 |