From c4c5dbefdb2ebda6be1ba085bddecf54fba47e5f Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Thu, 31 May 2012 13:24:11 -0700 Subject: [PATCH] Adding local/remote ip and port ServerVariables to env --- src/main/Firefly/Http/Connection.cs | 3 ++- src/main/Firefly/Http/Frame.cs | 18 ++++++++++++++++ src/main/Firefly/Utils/ISocket.cs | 3 +++ src/main/Firefly/Utils/SocketWrapper.cs | 17 +++++++++++++++ src/test/Firefly.Tests/Fakes/FakeSocket.cs | 4 ++++ src/test/Firefly.Tests/Http/FrameTests.cs | 21 ++++++++++++++++++- src/test/Firefly.Tests/Http/FrameTestsBase.cs | 3 +++ 7 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/main/Firefly/Http/Connection.cs b/src/main/Firefly/Http/Connection.cs index 177fd52..6558177 100644 --- a/src/main/Firefly/Http/Connection.cs +++ b/src/main/Firefly/Http/Connection.cs @@ -79,9 +79,10 @@ private void Go(bool newFrame, Frame frame) { Services = _services, App = _app, + Socket = _socket, Write = _socketSender.Write, Flush = _socketSender.Flush, - End = ProduceEnd + End = ProduceEnd, }); if (_baton.Buffer.Count != 0) diff --git a/src/main/Firefly/Http/Frame.cs b/src/main/Firefly/Http/Frame.cs index c1e9ca6..7928e65 100644 --- a/src/main/Firefly/Http/Frame.cs +++ b/src/main/Firefly/Http/Frame.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; +using System.Net; using System.Text; using System.Threading; using Firefly.Utils; @@ -21,6 +23,7 @@ public struct FrameContext { public IFireflyService Services; public AppDelegate App; + public ISocket Socket; public Func, bool> Write; public Func Flush; public Action End; @@ -434,6 +437,21 @@ private IDictionary CreateOwinEnvironment() env["owin.RequestBody"] = (BodyDelegate)_messageBody.Subscribe; env["owin.RequestScheme"] = "http"; // TODO: pass along information about scheme, cgi headers, etc env["owin.Version"] = "1.0"; + + var remoteEndPoint = _context.Socket.RemoteEndPoint as IPEndPoint; + if (remoteEndPoint != null) + { + env["server.REMOTE_ADDR"] = remoteEndPoint.Address.ToString(); + env["server.REMOTE_PORT"] = remoteEndPoint.Port.ToString(CultureInfo.InvariantCulture); + } + + var localEndPoint = _context.Socket.LocalEndPoint as IPEndPoint; + if (localEndPoint != null) + { + env["server.LOCAL_ADDR"] = localEndPoint.Address.ToString(); + env["server.SERVER_PORT"] = localEndPoint.Port.ToString(CultureInfo.InvariantCulture); + } + return env; } } diff --git a/src/main/Firefly/Utils/ISocket.cs b/src/main/Firefly/Utils/ISocket.cs index c6bbdec..3f1a0a2 100644 --- a/src/main/Firefly/Utils/ISocket.cs +++ b/src/main/Firefly/Utils/ISocket.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Net; using System.Net.Sockets; namespace Firefly.Utils @@ -9,6 +10,8 @@ public interface ISocket bool Blocking { get; set; } bool NoDelay { get; set; } bool Connected { get; } + EndPoint LocalEndPoint { get; } + EndPoint RemoteEndPoint { get; } int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode); bool ReceiveAsync(ISocketEvent socketEvent); diff --git a/src/main/Firefly/Utils/SocketWrapper.cs b/src/main/Firefly/Utils/SocketWrapper.cs index b857eb1..7ade037 100644 --- a/src/main/Firefly/Utils/SocketWrapper.cs +++ b/src/main/Firefly/Utils/SocketWrapper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Net; using System.Net.Sockets; namespace Firefly.Utils @@ -45,6 +46,22 @@ public bool Connected } } + public EndPoint LocalEndPoint + { + get + { + return _socket.LocalEndPoint; + } + } + + public EndPoint RemoteEndPoint + { + get + { + return _socket.RemoteEndPoint; + } + } + public int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode) { return _socket.Receive(buffer, offset, size, socketFlags, out errorCode); diff --git a/src/test/Firefly.Tests/Fakes/FakeSocket.cs b/src/test/Firefly.Tests/Fakes/FakeSocket.cs index 2d0bef3..286a55b 100644 --- a/src/test/Firefly.Tests/Fakes/FakeSocket.cs +++ b/src/test/Firefly.Tests/Fakes/FakeSocket.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Net; using System.Net.Sockets; using System.Text; using Firefly.Utils; @@ -119,6 +120,9 @@ Action TryReceiveAsync() public bool NoDelay { get; set; } public bool Connected { get; private set; } + public EndPoint LocalEndPoint { get; set; } + public EndPoint RemoteEndPoint { get; set; } + public int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode) { diff --git a/src/test/Firefly.Tests/Http/FrameTests.cs b/src/test/Firefly.Tests/Http/FrameTests.cs index 33b9a1b..5ed552b 100644 --- a/src/test/Firefly.Tests/Http/FrameTests.cs +++ b/src/test/Firefly.Tests/Http/FrameTests.cs @@ -1,4 +1,5 @@ -using Xunit; +using System.Net; +using Xunit; namespace Firefly.Tests.Http { @@ -116,5 +117,23 @@ public void InsufficientRequestBodyWillWaitForMoreData() Assert.False(App.RequestBody.Ended); Assert.Equal("12345", App.RequestBody.Text); } + + [Fact] + public void ValuesForCommonServerVariablesArePresent() + { + Socket.LocalEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 80); + Socket.RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.1"), 12345); + Input.Add("GET /hello/world?x=y HTTP/1.1\r\nHost: london\r\nfoo: bar\r\nfrap: quad\r\n\r\n"); + Input.End(); + AssertInputState(false, true, ""); + AssertOutputState(true); + Assert.Equal(1, App.CallCount); + + Assert.Equal("127.0.0.1", App.Env["server.LOCAL_ADDR"]); + Assert.Equal("80", App.Env["server.SERVER_PORT"]); + Assert.Equal("192.168.1.1", App.Env["server.REMOTE_ADDR"]); + Assert.Equal("12345", App.Env["server.REMOTE_PORT"]); + } + } } diff --git a/src/test/Firefly.Tests/Http/FrameTestsBase.cs b/src/test/Firefly.Tests/Http/FrameTestsBase.cs index 8ae209a..dca1626 100644 --- a/src/test/Firefly.Tests/Http/FrameTestsBase.cs +++ b/src/test/Firefly.Tests/Http/FrameTestsBase.cs @@ -10,6 +10,7 @@ public class FrameTestsBase protected readonly FakeApp App; protected readonly FakeOutput Output; protected readonly FakeInput Input; + protected readonly FakeSocket Socket; protected readonly Frame Frame; public FrameTestsBase() @@ -18,11 +19,13 @@ public FrameTestsBase() App = new FakeApp(); Output = new FakeOutput(); Input = new FakeInput(); + Socket = new FakeSocket(); Frame = new Frame( new FrameContext { Services = Services, App = App.Call, + Socket = Socket, Write = Output.Write, Flush = Output.Flush, End = Output.End,