Branch: refs/heads/master
Home:
https://github.com/mono/xsp
Compare:
https://github.com/mono/xsp/compare/5c41b358a442...2ddb9782907e
Commit: ec24d68ce4c17106ab9bd2f862936eaf577309f1
Author: Leonardo Taglialegne <
cmt.mi...@gmail.com> (miniBill)
Date: 2013-08-16 07:25:01 GMT
URL:
https://github.com/mono/xsp/commit/ec24d68ce4c17106ab9bd2f862936eaf577309f1
[Test] Wrap server start to automatically close the socket
Changed paths:
M src/Mono.WebServer.Test/HelloWorld.cs
M src/Mono.WebServer.Test/Mono.WebServer.Test.csproj
M src/Mono.WebServer.Test/Stress.cs
M src/Mono.WebServer.XSP/
AssemblyInfo.cs.in M src/Mono.WebServer.XSP/main.cs
Added paths:
A src/Mono.WebServer.Test/DebugServer.cs
Added: src/Mono.WebServer.Test/DebugServer.cs
===================================================================
@@ -0,0 +1,23 @@
+using System;
+using Mono.WebServer.XSP;
+
+namespace Mono.WebServer.Test
+{
+ public class DebugServer : IDisposable
+ {
+ ApplicationServer server;
+
+ public void Dispose ()
+ {
+ if (server != null)
+ server.Stop ();
+ }
+
+ public int Run ()
+ {
+ Tuple<int, string, ApplicationServer> res = Server.DebugMain (new [] { "--applications", "/:.", "--port", "9000", "--nonstop" });
+ server = res.Item3;
+ return res.Item1;
+ }
+ }
+}
Modified: src/Mono.WebServer.Test/HelloWorld.cs
===================================================================
@@ -1,6 +1,5 @@
using System;
using NUnit.Framework;
-using Mono.WebServer.XSP;
using System.Net;
namespace Mono.WebServer.Test
@@ -19,14 +18,16 @@ public void Init ()
[Test]
public void TestCase ()
{
- int result = Server.Main (new []{"--applications", "/:.","--port", "9000","--nonstop"});
- Assert.AreEqual (0, result);
- var wc = new WebClient ();
- try {
- string downloaded = wc.DownloadString ("
http://localhost:9000/");
- Assert.AreEqual (Environment.CurrentDirectory, downloaded);
- } catch (WebException e) {
- Assert.Fail(e.Message);
+ int i = 0;
+ using (var server = new DebugServer()) {
+ Assert.AreEqual (0, server.Run ());
+ var wc = new WebClient ();
+ try {
+ string downloaded = wc.DownloadString ("
http://localhost:9000/");
+ Assert.AreEqual (Environment.CurrentDirectory, downloaded);
+ } catch (WebException e) {
+ Assert.Fail (e.Message);
+ }
}
}
}
Modified: src/Mono.WebServer.Test/Mono.WebServer.Test.csproj
===================================================================
@@ -47,6 +47,7 @@
<Compile Include="Stress.cs" />
<Compile Include="FailLogger.cs" />
<Compile Include="CompatArraySegmentTest.cs" />
+ <Compile Include="DebugServer.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
Modified: src/Mono.WebServer.Test/Stress.cs
===================================================================
@@ -21,49 +21,51 @@ public void Init ()
[Test]
public void ValidConnections ()
{
- int result = Server.Main (new []{"--applications", "/:.","--port", "9000","--nonstop"});
- Assert.AreEqual (0, result);
- const int count = 1000;
- var threads = new Thread [count];
- try {
- for(int i = 0; i < count; i++) {
- threads [i] = new Thread (() => {
- var wc = new WebClient ();
- string downloaded = wc.DownloadString ("
http://localhost:9000/");
- Assert.AreEqual (Environment.CurrentDirectory, downloaded);
- });
- threads [i].Start ();
- }
+ using (var server = new DebugServer()) {
+ Assert.AreEqual (0, server.Run ());
+ const int count = 1000;
+ var threads = new Thread [count];
+ try {
+ for (int i = 0; i < count; i++) {
+ threads [i] = new Thread (() => {
+ var wc = new WebClient ();
+ string downloaded = wc.DownloadString ("
http://localhost:9000/");
+ Assert.AreEqual (Environment.CurrentDirectory, downloaded);
+ });
+ threads [i].Start ();
+ }
- foreach (Thread thread in threads)
- thread.Join();
- } catch (WebException e) {
- Assert.Fail(e.Message);
+ foreach (Thread thread in threads)
+ thread.Join ();
+ } catch (WebException e) {
+ Assert.Fail (e.Message);
+ }
}
}
[Test]
public void InvalidConnections ()
{
- int result = Server.Main (new []{"--applications", "/:.","--port", "9000","--nonstop"});
- Assert.AreEqual (0, result);
- const int count = 1000;
- var threads = new Thread [count];
- try {
- for(int i = 0; i < count; i++) {
- threads [i] = new Thread (() => {
- var client = new TcpClient ("localhost", 9000);
- using(var sw = new StreamWriter(client.GetStream()))
- sw.Write("\0\0\0\0");
- client.Close ();
- });
- threads [i].Start ();
- }
+ using (var server = new DebugServer()) {
+ Assert.AreEqual (0, server.Run ());
+ const int count = 1000;
+ var threads = new Thread [count];
+ try {
+ for (int i = 0; i < count; i++) {
+ threads [i] = new Thread (() => {
+ var client = new TcpClient ("localhost", 9000);
+ using (var sw = new StreamWriter(client.GetStream()))
+ sw.Write ("\0\0\0\0");
+ client.Close ();
+ });
+ threads [i].Start ();
+ }
- foreach (Thread thread in threads)
- thread.Join();
- } catch (WebException e) {
- Assert.Fail(e.Message);
+ foreach (Thread thread in threads)
+ thread.Join ();
+ } catch (WebException e) {
+ Assert.Fail (e.Message);
+ }
}
}
}
Modified: src/Mono.WebServer.XSP/
AssemblyInfo.cs.in
===================================================================
@@ -33,3 +33,9 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyDescription ("Minimalistic web server for testing System.Web")]
[assembly: AssemblyCopyright ("(C) 2002-2011 Novell, Inc.")]
[assembly: AssemblyCompany ("Novell, Inc.")]
+[assembly: InternalsVisibleTo ("Mono.WebServer.Test, PublicKey = 0024000004800000940000000602000" +
+ "00024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1a" +
+ "fcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fb" +
+ "e2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c508" +
+ "1dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284db" +
+ "dd35f46cdff12a1bd78e4ef0065d016df")]
Modified: src/Mono.WebServer.XSP/main.cs
===================================================================
@@ -43,6 +43,8 @@ public class Server : MarshalByRefObject
{
static RSA key;
+ static readonly Tuple<int, string, ApplicationServer> success = new Tuple<int,string,ApplicationServer> (0, null, null);
+
static AsymmetricAlgorithm GetPrivateKey (X509Certificate certificate, string targetHost)
{
return key;
@@ -61,11 +63,16 @@ public static void CurrentDomain_UnhandledException (object sender, UnhandledExc
public static int Main (string [] args)
{
+ return DebugMain (args).Item1;
+ }
+
+ internal static Tuple<int, string, ApplicationServer> DebugMain (string [] args)
+ {
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
bool quiet = false;
while (true) {
try {
- return new Server ().RealMain (args, true, null, quiet);
+ return new Server ().DebugMain (args, true, null, quiet);
} catch (ThreadAbortException ex) {
Logger.Write (ex);
// Single-app mode and
ASP.NET appdomain unloaded
@@ -75,22 +82,28 @@ public static int Main (string [] args)
}
}
- //
- // Parameters:
- //
- // args - original args passed to the program
- // root - true means caller is in the root domain
- // ext_apphost - used when single app mode is used, in a recursive call to
- // RealMain from the single app domain
- // quiet - don't show messages. Used to avoid double printing of the banner
- //
+ /// <param name="args">Original args passed to the program.</param>
+ /// <param name="root">If set to <c>true</c> it means the caller is in the root domain.</param>
+ /// <param name="ext_apphost">Used when single app mode is used, in a recursive call to RealMain from the single app domain.</param>
+ /// <param name="quiet">If set to <c>true</c> don't show messages. Used to avoid double printing of the banner.</param>
public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bool quiet)
{
+ return DebugMain (args, root, ext_apphost, quiet).Item1;
+ }
+
+ /// <param name="args">Original args passed to the program.</param>
+ /// <param name="root">If set to <c>true</c> it means the caller is in the root domain.</param>
+ /// <param name="ext_apphost">Used when single app mode is used, in a recursive call to RealMain from the single app domain.</param>
+ /// <param name="quiet">If set to <c>true</c> don't show messages. Used to avoid double printing of the banner.</param>
+ public Tuple<int, string, ApplicationServer> DebugMain (string [] args, bool root, IApplicationHost ext_apphost, bool quiet)
+ {
var configurationManager = new ConfigurationManager (quiet);
var security = new SecurityConfiguration ();
+
+ ApplicationServer server = null;
if (!ParseOptions (configurationManager, args, security))
- return 1;
+ return Tuple.Create (1, "Error while parsing options", server);
// Show the help and exit.
if (configurationManager.Help) {
@@ -99,17 +112,17 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
Console.WriteLine ("Press any key...");
Console.ReadKey ();
#endif
- return 0;
+ return success;
}
// Show the version and exit.
if (configurationManager.Version) {
Version.Show ();
- return 0;
+ return success;
}
if (!configurationManager.LoadConfigFile ())
- return 1;
+ return Tuple.Create (1, "Error while loading the configuration file", server);
configurationManager.SetupLogger ();
@@ -125,13 +138,13 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
}
catch (CryptographicException ce) {
Logger.Write (ce);
- return 1;
+ return Tuple.Create (1, "Error while setting up https", server);
}
} else {
webSource = new XSPWebSource (configurationManager.Address, configurationManager.Port, !root);
}
- var server = new ApplicationServer (webSource, configurationManager.Root) {
+ server = new ApplicationServer (webSource, configurationManager.Root) {
Verbose = configurationManager.Verbose,
SingleApplication = !root
};
@@ -155,7 +168,7 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
vh.CreateHost (server, webSource);
var svr = (Server) vh.AppHost.Domain.CreateInstanceAndUnwrap (GetType ().Assembly.GetName ().ToString (), GetType ().FullName);
webSource.Dispose ();
- return svr.RealMain (args, false, vh.AppHost, configurationManager.Quiet);
+ return svr.DebugMain (args, false, vh.AppHost, configurationManager.Quiet);
}
server.AppHost = ext_apphost;
@@ -166,8 +179,8 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
}
try {
- if (server.Start (!configurationManager.NonStop, (int)configurationManager.Backlog) == false)
- return 2;
+ if (!server.Start (!configurationManager.NonStop, (int)configurationManager.Backlog))
+ return Tuple.Create (2, "Error while starting server", server);
if (!configurationManager.Quiet) {
// MonoDevelop depends on this string. If you change it, let them know.
@@ -203,10 +216,10 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
Logger.Write (e);
else
server.ShutdownSockets ();
- return 1;
+ return Tuple.Create (1, "Error running server", server);
}
- return 0;
+ return Tuple.Create (0, String.Empty, server);
}
static bool ParseOptions (ConfigurationManager manager, string[] args, SecurityConfiguration security)
Commit: 0f69298ae61887cc5b3e4826139b826de449f46d
Author: Leonardo Taglialegne <
cmt.mi...@gmail.com> (miniBill)
Date: 2013-08-16 11:46:05 GMT
URL:
https://github.com/mono/xsp/commit/0f69298ae61887cc5b3e4826139b826de449f46d
[Test] Fix test compilation
Changed paths:
M src/Mono.WebServer.FastCgi/main.cs
M src/Mono.WebServer.Test/DebugServer.cs
M src/Mono.WebServer.Test/HelloWorld.cs
M src/Mono.WebServer.XSP/Mono.WebServer.XSP.csproj
M src/Mono.WebServer.XSP/main.cs
M test-fpm/index.aspx
Added paths:
A src/Mono.WebServer.XSP/CompatTuple.cs
Modified: src/Mono.WebServer.FastCgi/main.cs
===================================================================
@@ -291,8 +291,8 @@ public static bool TryCreateSocket (ConfigurationManager configurationManager, o
var socket_type = configurationManager.Socket;
Uri uri;
- if (Uri.TryCreate (socket_type, UriKind.Absolute, out uri))
- return TryCreateSocketFromUri (uri, out socket);
+ if (Uri.TryCreate (socket_type, UriKind.Absolute, out uri) && TryCreateSocketFromUri (uri, out socket))
+ return true;
string[] socket_parts = socket_type.Split (new[] {':'}, 3);
@@ -367,7 +367,7 @@ static bool TryCreateTcpSocket (string ip, int port, out Socket socket)
IPAddress address;
if (!IPAddress.TryParse (ip, out address)) {
- Logger.Write (LogLevel.Error, "Error in argument \"address\". \"{0}\" cannot be converted to an IP address.", ip);
+ Logger.Write (LogLevel.Debug, "\"{0}\" cannot be converted to an IP address.", ip);
return false;
}
Modified: src/Mono.WebServer.Test/DebugServer.cs
===================================================================
@@ -15,7 +15,7 @@ public void Dispose ()
public int Run ()
{
- Tuple<int, string, ApplicationServer> res = Server.DebugMain (new [] { "--applications", "/:.", "--port", "9000", "--nonstop" });
+ CompatTuple<int, string, ApplicationServer> res = Server.DebugMain (new [] { "--applications", "/:.", "--port", "9000", "--nonstop" });
server = res.Item3;
return res.Item1;
}
Modified: src/Mono.WebServer.Test/HelloWorld.cs
===================================================================
@@ -18,7 +18,6 @@ public void Init ()
[Test]
public void TestCase ()
{
- int i = 0;
using (var server = new DebugServer()) {
Assert.AreEqual (0, server.Run ());
var wc = new WebClient ();
Added: src/Mono.WebServer.XSP/CompatTuple.cs
===================================================================
@@ -0,0 +1,47 @@
+//
+// CompatTuple.cs
+//
+// Author:
+// Leonardo Taglialegne <
leonardo.t...@gmail.com>
+//
+// Copyright (c) 2013 Leonardo Taglialegne.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace Mono.WebServer.XSP
+{
+ [Serializable]
+ struct CompatTuple<T1, T2, T3> {
+ public T1 Item1;
+ public T2 Item2;
+ public T3 Item3;
+
+ public CompatTuple (T1 item1, T2 item2, T3 item3)
+ {
+ Item1 = item1;
+ Item2 = item2;
+ Item3 = item3;
+ }
+ }
+
+}
Modified: src/Mono.WebServer.XSP/Mono.WebServer.XSP.csproj
===================================================================
@@ -74,6 +74,7 @@
<Compile Include="XSPWorker.cs" />
<Compile Include="XSPWorkerRequest.cs" />
<Compile Include="AssemblyInfo.cs" />
+ <Compile Include="CompatTuple.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mono.WebServer\Mono.WebServer.csproj">
Modified: src/Mono.WebServer.XSP/main.cs
===================================================================
@@ -43,7 +43,7 @@ public class Server : MarshalByRefObject
{
static RSA key;
- static readonly Tuple<int, string, ApplicationServer> success = new Tuple<int,string,ApplicationServer> (0, null, null);
+ static readonly CompatTuple<int, string, ApplicationServer> success = new CompatTuple<int,string,ApplicationServer> (0, null, null);
static AsymmetricAlgorithm GetPrivateKey (X509Certificate certificate, string targetHost)
{
@@ -66,7 +66,7 @@ public static int Main (string [] args)
return DebugMain (args).Item1;
}
- internal static Tuple<int, string, ApplicationServer> DebugMain (string [] args)
+ internal static CompatTuple<int, string, ApplicationServer> DebugMain (string [] args)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
bool quiet = false;
@@ -95,7 +95,7 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
/// <param name="root">If set to <c>true</c> it means the caller is in the root domain.</param>
/// <param name="ext_apphost">Used when single app mode is used, in a recursive call to RealMain from the single app domain.</param>
/// <param name="quiet">If set to <c>true</c> don't show messages. Used to avoid double printing of the banner.</param>
- public Tuple<int, string, ApplicationServer> DebugMain (string [] args, bool root, IApplicationHost ext_apphost, bool quiet)
+ internal CompatTuple<int, string, ApplicationServer> DebugMain (string [] args, bool root, IApplicationHost ext_apphost, bool quiet)
{
var configurationManager = new ConfigurationManager (quiet);
var security = new SecurityConfiguration ();
@@ -103,7 +103,7 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
ApplicationServer server = null;
if (!ParseOptions (configurationManager, args, security))
- return Tuple.Create (1, "Error while parsing options", server);
+ return new CompatTuple<int,string,ApplicationServer> (1, "Error while parsing options", server);
// Show the help and exit.
if (configurationManager.Help) {
@@ -122,7 +122,7 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
}
if (!configurationManager.LoadConfigFile ())
- return Tuple.Create (1, "Error while loading the configuration file", server);
+ return new CompatTuple<int,string,ApplicationServer> (1, "Error while loading the configuration file", server);
configurationManager.SetupLogger ();
@@ -138,7 +138,7 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
}
catch (CryptographicException ce) {
Logger.Write (ce);
- return Tuple.Create (1, "Error while setting up https", server);
+ return new CompatTuple<int,string,ApplicationServer> (1, "Error while setting up https", server);
}
} else {
webSource = new XSPWebSource (configurationManager.Address, configurationManager.Port, !root);
@@ -180,7 +180,7 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
try {
if (!server.Start (!configurationManager.NonStop, (int)configurationManager.Backlog))
- return Tuple.Create (2, "Error while starting server", server);
+ return new CompatTuple<int,string,ApplicationServer> (2, "Error while starting server", server);
if (!configurationManager.Quiet) {
// MonoDevelop depends on this string. If you change it, let them know.
@@ -216,10 +216,10 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
Logger.Write (e);
else
server.ShutdownSockets ();
- return Tuple.Create (1, "Error running server", server);
+ return new CompatTuple<int,string,ApplicationServer> (1, "Error running server", server);
}
- return Tuple.Create (0, String.Empty, server);
+ return new CompatTuple<int,string,ApplicationServer> (0, null, server);
}
static bool ParseOptions (ConfigurationManager manager, string[] args, SecurityConfiguration security)
Modified: test-fpm/index.aspx
===================================================================
@@ -1 +1,3 @@
-<%= "Hallo" %>
+<%
+for (int i = 0; i < 100; i++)
+ Response.Write (String.Format ("<p>Hallo {0}</p>\n", i)); %>
Commit: c84a8e541022f6c596dcea587d072d33499ce7e3
Author: Leonardo Taglialegne <
cmt.mi...@gmail.com> (miniBill)
Date: 2013-08-16 17:46:42 GMT
URL:
https://github.com/mono/xsp/commit/c84a8e541022f6c596dcea587d072d33499ce7e3
Merge branch 'master' of
https://github.com/mono/xsp into HEAD
Changed paths:
M src/Mono.WebServer.Apache/ModMonoRequest.cs
M src/Mono.WebServer.Apache/ModMonoWebSource.cs
M src/Mono.WebServer.FastCgi/Connection.cs
M src/Mono.WebServer.FastCgi/Server/GenericServer.cs
M src/Mono.WebServer.FastCgi/main.cs
M src/Mono.WebServer.XSP/XSPWorkerRequest.cs
M src/Mono.WebServer/ApplicationServer.cs
M src/Mono.WebServer/VPathToHost.cs
Modified: src/Mono.WebServer.Apache/ModMonoRequest.cs
===================================================================
@@ -182,7 +182,9 @@ void FillBuffer (uint count)
void Send ()
{
- client.Send (writer_ms.GetBuffer (), (int) writer_ms.Length, SocketFlags.None);
+ int sent = client.Send (writer_ms.GetBuffer (), (int) writer_ms.Length, SocketFlags.None);
+ if (sent != (int) writer_ms.Length)
+ throw new IOException ("Blocking send did not send entire buffer");
writer_ms.Position = 0;
writer_ms.SetLength (0);
}
@@ -302,7 +304,9 @@ public void SendResponseFromMemory (IntPtr ptr, int length)
writer.Write (length);
Send ();
if (use_libc) {
- Send (ptr, length);
+ int sent = Send (ptr, length);
+ if (sent != length)
+ throw new IOException ("Blocking send did not send entire buffer");
return;
}
@@ -318,7 +322,9 @@ public void SendResponseFromMemory (IntPtr ptr, int length)
Marshal.Copy (ptr, buf, 0, size);
length -= size;
unsafe { ptr = (IntPtr)((byte*)ptr.ToPointer () + size); }
- client.Send (buf, size, SocketFlags.None);
+ int sent = client.Send (buf, size, SocketFlags.None);
+ if (sent != size)
+ throw new IOException ("Blocking send did not send entire buffer");
}
}
@@ -350,7 +356,9 @@ public void SendResponseFromMemory (byte [] data, int position, int length)
writer.Write ((int) ModMonoCmd.SEND_FROM_MEMORY);
writer.Write (length);
Send ();
- client.Send (data, position, length, SocketFlags.None);
+ int sent = client.Send (data, position, length, SocketFlags.None);
+ if (sent != length)
+ throw new IOException ("Blocking send did not send entire buffer");
}
public void SendFile (string filename)
Modified: src/Mono.WebServer.Apache/ModMonoWebSource.cs
===================================================================
@@ -88,7 +88,9 @@ protected bool SendShutdownCommandAndClose (Socket sock)
var b = new byte [] {0};
bool result = true;
try {
- sock.Send (b);
+ int sent = sock.Send (b);
+ if (sent != b.Length)
+ throw new IOException ("Blocking send did not send entire buffer");
} catch {
result = false;
}
Modified: src/Mono.WebServer.FastCgi/Connection.cs
===================================================================
@@ -139,7 +139,7 @@ public void Run ()
HandleRequest (record, request);
}
while (!stop && (UnfinishedRequests || keep_alive));
-
+
if (requests.Count == 0) {
lock (connection_teardown_lock) {
CloseSocket();
@@ -330,7 +330,7 @@ void HandleBeginRequest (Request request, Record record)
public void SendRecord (RecordType type, ushort requestID,
byte [] bodyData)
{
- SendRecord (type, requestID, bodyData, 0, -1);
+ SendRecord (type, requestID, bodyData, 0, bodyData.Length);
}
public void SendRecord (RecordType type, ushort requestID,
@@ -364,14 +364,7 @@ void HandleBeginRequest (Request request, Record record)
} catch (System.Net.Sockets.SocketException) {
}
-
- int index = GetRequestIndex (requestID);
-
- if (index >= 0) {
- lock (request_lock) {
- requests.RemoveAt (index);
- }
- }
+ RemoveRequest(requestID);
lock (connection_teardown_lock) {
if (requests.Count == 0 && (!keep_alive || stop)) {
@@ -389,9 +382,9 @@ void HandleBeginRequest (Request request, Record record)
public void Stop ()
{
stop = true;
-
- foreach (Request req in new List<Request> (requests))
- EndRequest (req.RequestID, -1, ProtocolStatus.RequestComplete);
+ lock(request_lock)
+ foreach (Request req in requests)
+ EndRequest (req.RequestID, -1, ProtocolStatus.RequestComplete);
}
#endregion
@@ -402,9 +395,10 @@ public void Stop ()
bool UnfinishedRequests {
get {
- foreach (Request request in requests)
- if (request.DataNeeded)
- return true;
+ lock(request_lock)
+ foreach (Request request in requests)
+ if (request.DataNeeded)
+ return true;
return false;
}
@@ -418,22 +412,27 @@ public void Stop ()
Request GetRequest (ushort requestID)
{
- foreach (Request request in requests)
- if (request.RequestID == requestID)
- return request;
+ lock(request_lock)
+ foreach (Request request in requests)
+ if (request.RequestID == requestID)
+ return request;
return null;
}
- int GetRequestIndex (ushort requestID)
+ void RemoveRequest (ushort requestID)
{
int i = 0;
- int count = requests.Count;
- while (i < count &&
- requests [i].RequestID != requestID)
- i ++;
-
- return (i != count) ? i : -1;
+ int count;
+ lock(request_lock)
+ {
+ count = requests.Count;
+ while (i < count &&
+ requests [i].RequestID != requestID)
+ i ++;
+ if (i != count)
+ requests.RemoveAt(i);
+ }
}
void StopRun (string message, params object [] args)
Modified: src/Mono.WebServer.FastCgi/Server/GenericServer.cs
===================================================================
@@ -44,6 +44,8 @@ public class GenericServer<T> : IGenericServer<T> where T : IConnection
bool stopped;
Thread runner;
readonly List<T> connections = new List<T> ();
+ readonly object connections_lock = new object ();
+
int max_connections = Int32.MaxValue;
AutoResetEvent stop_signal = new AutoResetEvent (false);
AutoResetEvent stopped_signal = new AutoResetEvent (false);
@@ -51,7 +53,7 @@ public class GenericServer<T> : IGenericServer<T> where T : IConnection
public event EventHandler RequestReceived;
public IEnumerable<T> Connections {
- get { return connections; }
+ get { lock(connections_lock) return new List<T> (connections); }
}
public bool Started { get; private set; }
@@ -74,8 +76,7 @@ public class GenericServer<T> : IGenericServer<T> where T : IConnection
public int ConnectionCount {
get {
- lock (connections)
- return connections.Count;
+ return connections.Count;
}
}
@@ -114,7 +115,7 @@ public void Stop ()
throw new InvalidOperationException (Strings.Server_NotStarted);
listen_socket.Close ();
- lock (connections) {
+ lock (connections_lock) {
foreach (T c in new List<T> (connections)) {
EndConnection (c);
}
@@ -137,7 +138,7 @@ public void EndConnection (T connection)
connection.Stop ();
- lock (connections) {
+ lock (connections_lock) {
if (connections.Contains (connection))
connections.Remove (connection);
}
@@ -174,7 +175,7 @@ void OnAccept (IAsyncResult ares)
Socket accepted = listen_socket.EndAccept (ares);
connection = serverCallback.OnAccept (accepted);
created = true;
- lock (connections)
+ lock (connections_lock)
connections.Add (connection);
connection.RequestReceived += RequestReceived;
} catch (System.Net.Sockets.SocketException e) {
Modified: src/Mono.WebServer.FastCgi/main.cs
===================================================================
@@ -303,6 +303,8 @@ public static bool TryCreateSocket (ConfigurationManager configurationManager, o
static bool TryCreateSocketFromUri (Uri uri, out Socket socket)
{
+ socket = null;
+
switch (uri.Scheme) {
case "pipe":
return TryCreatePipe (out socket);
Modified: src/Mono.WebServer.XSP/XSPWorkerRequest.cs
===================================================================
@@ -644,7 +644,10 @@ public override void SendResponseFromMemory (byte [] data, int length)
SendHeaders ();
}
- Send (data, 0, length);
+ int sent = Send (data, 0, length);
+ if (sent != length)
+ throw new IOException ("Blocking send did not send entire buffer");
+
if (uncork)
Cork (false);
}
Modified: src/Mono.WebServer/ApplicationServer.cs
===================================================================
@@ -445,7 +445,9 @@ void SendException (Socket socket, Exception ex)
byte[] data = Encoding.UTF8.GetBytes (sb.ToString ());
try {
- socket.Send (data);
+ int sent = socket.Send (data);
+ if (sent != data.Length)
+ throw new IOException ("Blocking send did not send entire buffer");
} catch (Exception ex2) {
Logger.Write(LogLevel.Error, "Failed to send exception:");
Logger.Write(ex);
Modified: src/Mono.WebServer/VPathToHost.cs
===================================================================
@@ -96,6 +96,9 @@ public bool Match (string vhost, int vport, string vpath)
if (vport != -1 && this.vport != -1 && vport != this.vport)
return false;
+ if (vpath == null)
+ return false;
+
if (vhost != null && this.vhost != null && this.vhost != "*") {
int length = this.vhost.Length;
string lwrvhost = vhost.ToLower (CultureInfo.InvariantCulture);
Commit: 389c92f87ea71a04726fef9683fa3e91c20c3c64
Author: Leonardo Taglialegne <
cmt.mi...@gmail.com> (miniBill)
Date: 2013-08-16 17:47:00 GMT
URL:
https://github.com/mono/xsp/commit/389c92f87ea71a04726fef9683fa3e91c20c3c64
[FastCgi] Fix reaction on connection close
Changed paths:
M src/Mono.WebServer.FastCgi/Connection.cs
M src/Mono.WebServer.FastCgi/StandardSocket.cs
M src/Mono.WebServer.XSP/Mono.WebServer.XSP.sources
Modified: src/Mono.WebServer.FastCgi/Connection.cs
===================================================================
@@ -166,6 +166,9 @@ void CloseSocket ()
// error from UnmanagedSocket.Close
if (e.ErrorCode != 10038)
throw; // Rethrow other errors
+ } catch(ObjectDisposedException){
+ // Ignore: already closed
+ // TODO: figure out a better flow than try/catch
} finally {
socket = null;
}
@@ -383,7 +386,7 @@ public void Stop ()
{
stop = true;
lock(request_lock)
- foreach (Request req in requests)
+ foreach (Request req in new List<Request>(requests))
EndRequest (req.RequestID, -1, ProtocolStatus.RequestComplete);
}
Modified: src/Mono.WebServer.FastCgi/StandardSocket.cs
===================================================================
@@ -101,7 +101,7 @@ public override int Receive (byte [] buffer, int offset, int size,
System.Net.So {
// Note: a better error message would probably be deemed fit.
socket.Close();
- throw new Exception("Remote end hung up.");
+ throw new System.Net.Sockets.SocketException();
}
return received;
Modified: src/Mono.WebServer.XSP/Mono.WebServer.XSP.sources
===================================================================
@@ -1,9 +1,10 @@
-ConfigurationManager.cs
-SecurityConfiguration.cs
-SslInformation.cs
-XSPApplicationHost.cs
-XSPRequestBroker.cs
-XSPWebSource.cs
-XSPWorker.cs
-XSPWorkerRequest.cs
-main.cs
+./CompatTuple.cs
+./ConfigurationManager.cs
+./main.cs
+./SecurityConfiguration.cs
+./SslInformation.cs
+./XSPApplicationHost.cs
+./XSPRequestBroker.cs
+./XSPWebSource.cs
+./XSPWorker.cs
+./XSPWorkerRequest.cs
Commit: 2ddb9782907e43f1cb2e9b7499c0786464a8d366
Author: Marek Habersack <
gre...@twistedcode.net> (grendello)
Date: 2013-08-16 19:03:54 GMT
URL:
https://github.com/mono/xsp/commit/2ddb9782907e43f1cb2e9b7499c0786464a8d366
Merge pull request #48 from mono-soc-2013/master
Starting fixes on heavy load
Changed paths:
M src/Mono.WebServer.FastCgi/Connection.cs
M src/Mono.WebServer.FastCgi/StandardSocket.cs
M src/Mono.WebServer.FastCgi/main.cs
M src/Mono.WebServer.Test/HelloWorld.cs
M src/Mono.WebServer.Test/Mono.WebServer.Test.csproj
M src/Mono.WebServer.Test/Stress.cs
M src/Mono.WebServer.XSP/AssemblyInfo.cs.in
M src/Mono.WebServer.XSP/Mono.WebServer.XSP.csproj
M src/Mono.WebServer.XSP/Mono.WebServer.XSP.sources
M src/Mono.WebServer.XSP/main.cs
M test-fpm/index.aspx
Added paths:
A src/Mono.WebServer.Test/DebugServer.cs
A src/Mono.WebServer.XSP/CompatTuple.cs
Modified: src/Mono.WebServer.FastCgi/Connection.cs
===================================================================
@@ -166,6 +166,9 @@ void CloseSocket ()
// error from UnmanagedSocket.Close
if (e.ErrorCode != 10038)
throw; // Rethrow other errors
+ } catch(ObjectDisposedException){
+ // Ignore: already closed
+ // TODO: figure out a better flow than try/catch
} finally {
socket = null;
}
@@ -383,7 +386,7 @@ public void Stop ()
{
stop = true;
lock(request_lock)
- foreach (Request req in requests)
+ foreach (Request req in new List<Request>(requests))
EndRequest (req.RequestID, -1, ProtocolStatus.RequestComplete);
}
Modified: src/Mono.WebServer.FastCgi/StandardSocket.cs
===================================================================
@@ -101,7 +101,7 @@ public override int Receive (byte [] buffer, int offset, int size, System.Net.So
{
// Note: a better error message would probably be deemed fit.
socket.Close();
- throw new Exception("Remote end hung up.");
+ throw new System.Net.Sockets.SocketException();
}
return received;
Modified: src/Mono.WebServer.FastCgi/main.cs
===================================================================
@@ -291,8 +291,8 @@ public static bool TryCreateSocket (ConfigurationManager configurationManager, o
var socket_type = configurationManager.Socket;
Uri uri;
- if (Uri.TryCreate (socket_type, UriKind.Absolute, out uri))
- return TryCreateSocketFromUri (uri, out socket);
+ if (Uri.TryCreate (socket_type, UriKind.Absolute, out uri) && TryCreateSocketFromUri (uri, out socket))
+ return true;
string[] socket_parts = socket_type.Split (new[] {':'}, 3);
@@ -369,7 +369,7 @@ static bool TryCreateTcpSocket (string ip, int port, out Socket socket)
IPAddress address;
if (!IPAddress.TryParse (ip, out address)) {
- Logger.Write (LogLevel.Error, "Error in argument \"address\". \"{0}\" cannot be converted to an IP address.", ip);
+ Logger.Write (LogLevel.Debug, "\"{0}\" cannot be converted to an IP address.", ip);
return false;
}
Added: src/Mono.WebServer.Test/DebugServer.cs
===================================================================
@@ -0,0 +1,23 @@
+using System;
+using Mono.WebServer.XSP;
+
+namespace Mono.WebServer.Test
+{
+ public class DebugServer : IDisposable
+ {
+ ApplicationServer server;
+
+ public void Dispose ()
+ {
+ if (server != null)
+ server.Stop ();
+ }
+
+ public int Run ()
+ {
+ CompatTuple<int, string, ApplicationServer> res = Server.DebugMain (new [] { "--applications", "/:.", "--port", "9000", "--nonstop" });
+ server = res.Item3;
+ return res.Item1;
+ }
+ }
+}
Modified: src/Mono.WebServer.Test/HelloWorld.cs
===================================================================
@@ -1,6 +1,5 @@
using System;
using NUnit.Framework;
-using Mono.WebServer.XSP;
using System.Net;
namespace Mono.WebServer.Test
@@ -19,14 +18,15 @@ public void Init ()
[Test]
public void TestCase ()
{
- int result = Server.Main (new []{"--applications", "/:.","--port", "9000","--nonstop"});
- Assert.AreEqual (0, result);
- var wc = new WebClient ();
- try {
- string downloaded = wc.DownloadString ("http://localhost:9000/");
- Assert.AreEqual (Environment.CurrentDirectory, downloaded);
- } catch (WebException e) {
- Assert.Fail(e.Message);
+ using (var server = new DebugServer()) {
+ Assert.AreEqual (0, server.Run ());
+ var wc = new WebClient ();
+ try {
+ string downloaded = wc.DownloadString ("http://localhost:9000/");
+ Assert.AreEqual (Environment.CurrentDirectory, downloaded);
+ } catch (WebException e) {
+ Assert.Fail (e.Message);
+ }
}
}
}
Modified: src/Mono.WebServer.Test/Mono.WebServer.Test.csproj
===================================================================
@@ -47,6 +47,7 @@
<Compile Include="Stress.cs" />
<Compile Include="FailLogger.cs" />
<Compile Include="CompatArraySegmentTest.cs" />
+ <Compile Include="DebugServer.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
Modified: src/Mono.WebServer.Test/Stress.cs
===================================================================
@@ -21,49 +21,51 @@ public void Init ()
[Test]
public void ValidConnections ()
{
- int result = Server.Main (new []{"--applications", "/:.","--port", "9000","--nonstop"});
- Assert.AreEqual (0, result);
- const int count = 1000;
- var threads = new Thread [count];
- try {
- for(int i = 0; i < count; i++) {
- threads [i] = new Thread (() => {
- var wc = new WebClient ();
- string downloaded = wc.DownloadString ("http://localhost:9000/");
- Assert.AreEqual (Environment.CurrentDirectory, downloaded);
- });
- threads [i].Start ();
- }
+ using (var server = new DebugServer()) {
+ Assert.AreEqual (0, server.Run ());
+ const int count = 1000;
+ var threads = new Thread [count];
+ try {
+ for (int i = 0; i < count; i++) {
+ threads [i] = new Thread (() => {
+ var wc = new WebClient ();
+ string downloaded = wc.DownloadString ("http://localhost:9000/");
+ Assert.AreEqual (Environment.CurrentDirectory, downloaded);
+ });
+ threads [i].Start ();
+ }
- foreach (Thread thread in threads)
- thread.Join();
- } catch (WebException e) {
- Assert.Fail(e.Message);
+ foreach (Thread thread in threads)
+ thread.Join ();
+ } catch (WebException e) {
+ Assert.Fail (e.Message);
+ }
}
}
[Test]
public void InvalidConnections ()
{
- int result = Server.Main (new []{"--applications", "/:.","--port", "9000","--nonstop"});
- Assert.AreEqual (0, result);
- const int count = 1000;
- var threads = new Thread [count];
- try {
- for(int i = 0; i < count; i++) {
- threads [i] = new Thread (() => {
- var client = new TcpClient ("localhost", 9000);
- using(var sw = new StreamWriter(client.GetStream()))
- sw.Write("\0\0\0\0");
- client.Close ();
- });
- threads [i].Start ();
- }
+ using (var server = new DebugServer()) {
+ Assert.AreEqual (0, server.Run ());
+ const int count = 1000;
+ var threads = new Thread [count];
+ try {
+ for (int i = 0; i < count; i++) {
+ threads [i] = new Thread (() => {
+ var client = new TcpClient ("localhost", 9000);
+ using (var sw = new StreamWriter(client.GetStream()))
+ sw.Write ("\0\0\0\0");
+ client.Close ();
+ });
+ threads [i].Start ();
+ }
- foreach (Thread thread in threads)
- thread.Join();
- } catch (WebException e) {
- Assert.Fail(e.Message);
+ foreach (Thread thread in threads)
+ thread.Join ();
+ } catch (WebException e) {
+ Assert.Fail (e.Message);
+ }
}
}
}
Modified: src/Mono.WebServer.XSP/AssemblyInfo.cs.in
===================================================================
@@ -33,3 +33,9 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyDescription ("Minimalistic web server for testing System.Web")]
[assembly: AssemblyCopyright ("(C) 2002-2011 Novell, Inc.")]
[assembly: AssemblyCompany ("Novell, Inc.")]
+[assembly: InternalsVisibleTo ("Mono.WebServer.Test, PublicKey = 0024000004800000940000000602000" +
+ "00024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1a" +
+ "fcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fb" +
+ "e2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c508" +
+ "1dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284db" +
+ "dd35f46cdff12a1bd78e4ef0065d016df")]
Added: src/Mono.WebServer.XSP/CompatTuple.cs
===================================================================
@@ -0,0 +1,47 @@
+//
+// CompatTuple.cs
+//
+// Author:
+// Leonardo Taglialegne <leonardo.t...@gmail.com>
+//
+// Copyright (c) 2013 Leonardo Taglialegne.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace Mono.WebServer.XSP
+{
+ [Serializable]
+ struct CompatTuple<T1, T2, T3> {
+ public T1 Item1;
+ public T2 Item2;
+ public T3 Item3;
+
+ public CompatTuple (T1 item1, T2 item2, T3 item3)
+ {
+ Item1 = item1;
+ Item2 = item2;
+ Item3 = item3;
+ }
+ }
+
+}
Modified: src/Mono.WebServer.XSP/Mono.WebServer.XSP.csproj
===================================================================
@@ -74,6 +74,7 @@
<Compile Include="XSPWorker.cs" />
<Compile Include="XSPWorkerRequest.cs" />
<Compile Include="AssemblyInfo.cs" />
+ <Compile Include="CompatTuple.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mono.WebServer\Mono.WebServer.csproj">
Modified: src/Mono.WebServer.XSP/Mono.WebServer.XSP.sources
===================================================================
@@ -1,9 +1,10 @@
-ConfigurationManager.cs
-SecurityConfiguration.cs
-SslInformation.cs
-XSPApplicationHost.cs
-XSPRequestBroker.cs
-XSPWebSource.cs
-XSPWorker.cs
-XSPWorkerRequest.cs
-main.cs
+./CompatTuple.cs
+./ConfigurationManager.cs
+./main.cs
+./SecurityConfiguration.cs
+./SslInformation.cs
+./XSPApplicationHost.cs
+./XSPRequestBroker.cs
+./XSPWebSource.cs
+./XSPWorker.cs
+./XSPWorkerRequest.cs
Modified: src/Mono.WebServer.XSP/main.cs
===================================================================
@@ -43,6 +43,8 @@ public class Server : MarshalByRefObject
{
static RSA key;
+ static readonly CompatTuple<int, string, ApplicationServer> success = new CompatTuple<int,string,ApplicationServer> (0, null, null);
+
static AsymmetricAlgorithm GetPrivateKey (X509Certificate certificate, string targetHost)
{
return key;
@@ -61,11 +63,16 @@ public static void CurrentDomain_UnhandledException (object sender, UnhandledExc
public static int Main (string [] args)
{
+ return DebugMain (args).Item1;
+ }
+
+ internal static CompatTuple<int, string, ApplicationServer> DebugMain (string [] args)
+ {
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
bool quiet = false;
while (true) {
try {
- return new Server ().RealMain (args, true, null, quiet);
+ return new Server ().DebugMain (args, true, null, quiet);
} catch (ThreadAbortException ex) {
Logger.Write (ex);
// Single-app mode and ASP.NET appdomain unloaded
@@ -75,22 +82,28 @@ public static int Main (string [] args)
}
}
- //
- // Parameters:
- //
- // args - original args passed to the program
- // root - true means caller is in the root domain
- // ext_apphost - used when single app mode is used, in a recursive call to
- // RealMain from the single app domain
- // quiet - don't show messages. Used to avoid double printing of the banner
- //
+ /// <param name="args">Original args passed to the program.</param>
+ /// <param name="root">If set to <c>true</c> it means the caller is in the root domain.</param>
+ /// <param name="ext_apphost">Used when single app mode is used, in a recursive call to RealMain from the single app domain.</param>
+ /// <param name="quiet">If set to <c>true</c> don't show messages. Used to avoid double printing of the banner.</param>
public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bool quiet)
{
+ return DebugMain (args, root, ext_apphost, quiet).Item1;
+ }
+
+ /// <param name="args">Original args passed to the program.</param>
+ /// <param name="root">If set to <c>true</c> it means the caller is in the root domain.</param>
+ /// <param name="ext_apphost">Used when single app mode is used, in a recursive call to RealMain from the single app domain.</param>
+ /// <param name="quiet">If set to <c>true</c> don't show messages. Used to avoid double printing of the banner.</param>
+ internal CompatTuple<int, string, ApplicationServer> DebugMain (string [] args, bool root, IApplicationHost ext_apphost, bool quiet)
+ {
var configurationManager = new ConfigurationManager (quiet);
var security = new SecurityConfiguration ();
+
+ ApplicationServer server = null;
if (!ParseOptions (configurationManager, args, security))
- return 1;
+ return new CompatTuple<int,string,ApplicationServer> (1, "Error while parsing options", server);
// Show the help and exit.
if (configurationManager.Help) {
@@ -99,17 +112,17 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
Console.WriteLine ("Press any key...");
Console.ReadKey ();
#endif
- return 0;
+ return success;
}
// Show the version and exit.
if (configurationManager.Version) {
Version.Show ();
- return 0;
+ return success;
}
if (!configurationManager.LoadConfigFile ())
- return 1;
+ return new CompatTuple<int,string,ApplicationServer> (1, "Error while loading the configuration file", server);
configurationManager.SetupLogger ();
@@ -125,13 +138,13 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
}
catch (CryptographicException ce) {
Logger.Write (ce);
- return 1;
+ return new CompatTuple<int,string,ApplicationServer> (1, "Error while setting up https", server);
}
} else {
webSource = new XSPWebSource (configurationManager.Address, configurationManager.Port, !root);
}
- var server = new ApplicationServer (webSource, configurationManager.Root) {
+ server = new ApplicationServer (webSource, configurationManager.Root) {
Verbose = configurationManager.Verbose,
SingleApplication = !root
};
@@ -155,7 +168,7 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
vh.CreateHost (server, webSource);
var svr = (Server) vh.AppHost.Domain.CreateInstanceAndUnwrap (GetType ().Assembly.GetName ().ToString (), GetType ().FullName);
webSource.Dispose ();
- return svr.RealMain (args, false, vh.AppHost, configurationManager.Quiet);
+ return svr.DebugMain (args, false, vh.AppHost, configurationManager.Quiet);
}
server.AppHost = ext_apphost;
@@ -166,8 +179,8 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
}
try {
- if (server.Start (!configurationManager.NonStop, (int)configurationManager.Backlog) == false)
- return 2;
+ if (!server.Start (!configurationManager.NonStop, (int)configurationManager.Backlog))
+ return new CompatTuple<int,string,ApplicationServer> (2, "Error while starting server", server);
if (!configurationManager.Quiet) {
// MonoDevelop depends on this string. If you change it, let them know.
@@ -203,10 +216,10 @@ public int RealMain (string [] args, bool root, IApplicationHost ext_apphost, bo
Logger.Write (e);
else
server.ShutdownSockets ();
- return 1;
+ return new CompatTuple<int,string,ApplicationServer> (1, "Error running server", server);
}
- return 0;
+ return new CompatTuple<int,string,ApplicationServer> (0, null, server);
}
static bool ParseOptions (ConfigurationManager manager, string[] args, SecurityConfiguration security)
Modified: test-fpm/index.aspx
===================================================================
@@ -1 +1,3 @@
-<%= "Hallo" %>
+<%
+for (int i = 0; i < 100; i++)
+ Response.Write (String.Format ("<p>Hallo {0}</p>\n", i)); %>