Skip to content

Commit

Permalink
- NullReferenceException bug when binding to Unix Sockets fixed, test…
Browse files Browse the repository at this point in the history
…s added and issue documented.

- Some old code removed.
  • Loading branch information
mzabani committed Mar 4, 2014
1 parent 5b4a2be commit 436e13b
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 65 deletions.
35 changes: 34 additions & 1 deletion Fos.Tests/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public void CloseAndFlush()
}

[Test]
public void StartAndDispose()
public void StartAndDisposeTcpSocket()
{
int port = 9007; // Let's hope this is not being used..

Expand All @@ -30,7 +30,40 @@ public void StartAndDispose()
Assert.AreEqual(true, server.IsRunning);
}

using (server = new FosSelfHost(app => {}))
{
server.Bind(System.Net.IPAddress.Loopback, port);

server.Start(true);
Assert.AreEqual(true, server.IsRunning);
}

Assert.AreEqual(false, server.IsRunning);
}

#if __MonoCS__
[Test]
public void StartAndDisposeUnixSocket()
{
FosSelfHost server;
using (server = new FosSelfHost(app => {}))
{
server.Bind("./.FosTestSocket");

server.Start(true);
Assert.AreEqual(true, server.IsRunning);
}

using (server = new FosSelfHost(app => {}))
{
server.Bind("./.FosTestSocket");

server.Start(true);
Assert.AreEqual(true, server.IsRunning);
}

Assert.AreEqual(false, server.IsRunning);
}
#endif
}
}
62 changes: 1 addition & 61 deletions Fos/FosSelfHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,6 @@ public override void Start(bool background)
if (logger != null)
base.SetLogger(logger);

// // Signs up for important events, then starts the listener
// FastCgiListener.OnReceiveBeginRequestRecord += OnReceiveBeginRequest;
// FastCgiListener.OnReceiveParamsRecord += OnReceiveParams;
// FastCgiListener.OnReceiveStdinRecord += OnReceiveStdin;

base.Start(background);
}

Expand All @@ -100,61 +95,7 @@ public override void SetLogger(IServerLogger logger)
throw new ArgumentNullException("logger");

this.UserSetLogger = logger;
}

// protected override void OnRecordBuild(RecordBase rec, FosRequest req)
// {
// if (rec.RecordType == RecordType.FCGIBeginRequest)
// OnReceiveStdin(req, rec);
// }

//
// private void OnReceiveBeginRequest(FosRequest req, BeginRequestRecord rec)
// {
// req.ApplicationPipelineEntry = OwinPipelineEntry;
// req.FlushPeriodically = FlushPeriodically;
// }
//
// private void OnReceiveParams(FosRequest req, ParamsRecord rec)
// {
// req.ReceiveParams(rec);
// }

// private void OnReceiveStdin(FosRequest req, StdinRecord rec)
// {
// var onCloseConnection = req.ReceiveStdin(rec);
// if (onCloseConnection == null)
// return;
//
// onCloseConnection.ContinueWith(t =>
// {
// //TODO: The task may have failed or something else happened, verify
// // Remember that connections closed by the other side abruptly have already
// // been closed by the listener loop, so we shouldn't call Request.CloseSocket() here again
// if (req.ApplicationMustCloseConnection)
// {
// req.Dispose();
// }
// });
// }

// /// <summary>
// /// Binds the TCP listen socket to an address an a port.
// /// </summary>
// public void Bind(System.Net.IPAddress addr, int port)
// {
// FastCgiListener.Bind(addr, port);
// }
//
//#if __MonoCS__
// /// <summary>
// /// Defines the unix socket path to listen on.
// /// </summary>
// public void Bind(string socketPath)
// {
// FastCgiListener.Bind(socketPath);
// }
//#endif
}

public override void Dispose()
{
Expand All @@ -168,7 +109,6 @@ public override void Dispose()
public FosSelfHost(Action<IAppBuilder> configureMethod)
{
ApplicationConfigure = configureMethod;
//FastCgiListener = new SocketListener();
OnAppDisposal = new CancellationTokenSource();
}
}
Expand Down
9 changes: 7 additions & 2 deletions Fos/Listener/SocketListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public abstract class SocketListener : IDisposable
private const int listenBacklog = 500;
private Socket tcpListenSocket;
private Socket unixListenSocket;
private string unixSocketFilePath;
private bool SomeListenSocketHasBeenBound
{
get
Expand Down Expand Up @@ -269,6 +270,7 @@ public void Bind(IPAddress addr, int port)
/// </summary>
public void Bind(string socketPath)
{
unixSocketFilePath = socketPath;
var endpoint = new Mono.Unix.UnixEndPoint(socketPath);
unixListenSocket.Bind (endpoint);
}
Expand Down Expand Up @@ -311,7 +313,10 @@ public virtual void Stop()
if (tcpListenSocket != null && tcpListenSocket.IsBound)
tcpListenSocket.Close();
if (unixListenSocket != null && unixListenSocket.IsBound)
unixListenSocket.Close();
{
unixListenSocket.Close();
System.IO.File.Delete(unixSocketFilePath);
}

//TODO: Stop task that waits for connection data..
if (Logger != null)
Expand Down Expand Up @@ -346,7 +351,7 @@ public virtual void Dispose()
public SocketListener()
{
tcpListenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
#if __MonoCs__
#if __MonoCS__
unixListenSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); // man unix (7) says most unix implementations are safe on deliveryand order
#endif

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ static void applicationRegistration(IAppBuilder builder)
}
```

*Note about Unix Sockets*: NuGet's Fos has a bug that will make it throw a ```NullReferenceException``` when binding to an Unix Socket with Mono. This is fixed in **master**. Also, Fos does not sets permissions for you in the socket file, but does remove the socket file when stopped, so make sure permissions are all set.

Architecture
------------
Fos is comprised of a main loop, where it handles new connections and incoming data from established ones. This loop runs synchronous socket operations only when these wouldn't block. In essence, it is an asynchronous loop.
Expand All @@ -58,7 +60,7 @@ Always remember to use ````async```` and ````await```` if you are writing C# 5 o

Installation
---------
You can install Fos via NuGet.
You can install Fos via NuGet or build it manually for the latest bug fixes and features.

Build instructions:
Clone this repository and open this solution in Monodevelop (this is the development IDE I use, in fact) or Visual Studio, then Build. You will find the binary Fos.dll in your *bin* folder. Yes, it is that simple.
Expand Down

0 comments on commit 436e13b

Please sign in to comment.