Skip to content
This repository has been archived by the owner on Apr 15, 2023. It is now read-only.

Commit

Permalink
Nancy / Kayak in and linked together!
Browse files Browse the repository at this point in the history
  • Loading branch information
rmc47 committed Dec 8, 2012
1 parent f4e5184 commit 2840cd3
Show file tree
Hide file tree
Showing 12 changed files with 296 additions and 1 deletion.
13 changes: 12 additions & 1 deletion CloudLogCAT/CloudlogCAT.csproj
Expand Up @@ -34,9 +34,13 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Kayak">
<Reference Include="Kayak, Version=0.7.2.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Referenced Dlls\Kayak\Kayak.dll</HintPath>
</Reference>
<Reference Include="Nancy">
<HintPath>..\packages\Nancy.0.14.0\lib\net40\Nancy.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Web.Extensions">
Expand All @@ -60,12 +64,17 @@
<Compile Include="ConnectionForm.Designer.cs">
<DependentUpon>ConnectionForm.cs</DependentUpon>
</Compile>
<Compile Include="HttpServer\BufferedConsumer.cs" />
<Compile Include="HttpServer\BufferedProducer.cs" />
<Compile Include="HttpServer\HttpHost.cs" />
<Compile Include="HttpServer\NancyRequestDelegate.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="NancyTest.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Settings.cs" />
Expand All @@ -86,6 +95,7 @@
<DesignTime>True</DesignTime>
</Compile>
<None Include="app.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
Expand All @@ -102,6 +112,7 @@
<Name>RigCAT.NET</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Expand Down
39 changes: 39 additions & 0 deletions CloudLogCAT/HttpServer/BufferedConsumer.cs
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kayak;
using System.IO;

namespace CloudlogCAT.HttpServer
{
internal class BufferedConsumer : IDataConsumer
{
MemoryStream m_DataBuffer = new MemoryStream();
Action<Stream> resultCallback;
Action<Exception> errorCallback;

public BufferedConsumer(Action<Stream> resultCallback, Action<Exception> errorCallback)
{
this.resultCallback = resultCallback;
this.errorCallback = errorCallback;
}
public bool OnData(ArraySegment<byte> data, Action continuation)
{
// since we're just buffering, ignore the continuation.
// TODO: place an upper limit on the size of the buffer.
// don't want a client to take up all the RAM on our server!
m_DataBuffer.Write(data.Array, data.Offset, data.Count);
return false;
}
public void OnError(Exception error)
{
errorCallback(error);
}

public void OnEnd()
{
resultCallback(m_DataBuffer);
}
}
}
29 changes: 29 additions & 0 deletions CloudLogCAT/HttpServer/BufferedProducer.cs
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kayak;

namespace CloudlogCAT.HttpServer
{
internal class BufferedProducer : IDataProducer
{
ArraySegment<byte> data;

public BufferedProducer(string data) : this(data, Encoding.UTF8) { }
public BufferedProducer(string data, Encoding encoding) : this(encoding.GetBytes(data)) { }
public BufferedProducer(byte[] data) : this(new ArraySegment<byte>(data)) { }
public BufferedProducer(ArraySegment<byte> data)
{
this.data = data;
}

public IDisposable Connect(IDataConsumer channel)
{
// null continuation, consumer must swallow the data immediately.
channel.OnData(data, null);
channel.OnEnd();
return null;
}
}
}
75 changes: 75 additions & 0 deletions CloudLogCAT/HttpServer/HttpHost.cs
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kayak;
using Kayak.Http;
using Nancy;
using Nancy.Bootstrapper;
using System.Diagnostics;
using System.Net;
using System.Threading;

namespace CloudlogCAT.HttpServer
{
internal sealed class HttpHost
{
INancyEngine m_Engine;
private IScheduler m_Scheduler;
private IServer m_Server;
private IPEndPoint m_EndPoint;

public HttpHost(IPEndPoint endpoint)
{
var bootStrapper = NancyBootstrapperLocator.Bootstrapper;
bootStrapper.Initialise();
m_Engine = bootStrapper.GetEngine();
m_EndPoint = endpoint;
}

public void Start()
{
m_Scheduler = KayakScheduler.Factory.Create(new SchedulerDelegate());
m_Server = KayakServer.Factory.CreateHttp(new NancyRequestDelegate(m_Engine), m_Scheduler);

IDisposable disposable = m_Server.Listen(m_EndPoint);
Thread schedulerWorkerThread = new Thread(SchedulerWorker);
schedulerWorkerThread.IsBackground = true;
schedulerWorkerThread.Start(disposable);
m_Scheduler.Post(GetLocalPort);
}

private void GetLocalPort()
{
Debug.WriteLine(m_EndPoint.Port);
}

private void SchedulerWorker(object disposable)
{
using ((IDisposable)disposable)
{
m_Scheduler.Start();
}
}

public void Stop()
{
m_Scheduler.Stop();
}

private class SchedulerDelegate : ISchedulerDelegate
{
public void OnException(IScheduler scheduler, Exception e)
{
Debug.WriteLine("Error on scheduler.");
e.DebugStackTrace();
}

public void OnStop(IScheduler scheduler)
{

}
}

}
}
88 changes: 88 additions & 0 deletions CloudLogCAT/HttpServer/NancyRequestDelegate.cs
@@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nancy;
using Kayak.Http;
using Nancy.Helpers;
using System.IO;

namespace CloudlogCAT.HttpServer
{
internal sealed class NancyRequestDelegate : IHttpRequestDelegate
{
private INancyEngine m_Engine;

public NancyRequestDelegate(INancyEngine engine)
{
m_Engine = engine;
}

public void OnRequest(HttpRequestHead head, Kayak.IDataProducer body, IHttpResponseDelegate response)
{
BufferedConsumer requestConsumer = new BufferedConsumer(bodyStream => RequestReadCompleted(head, bodyStream, response), RequestReadError);
body.Connect(requestConsumer);
}

private void RequestReadCompleted(HttpRequestHead head, Stream requestStream, IHttpResponseDelegate response)
{
#warning wrong hard-coded base URI
Uri baseUri = new Uri("http://localhost:8083/");
Uri requestUrl = new Uri(baseUri, head.Uri);
Url nancyUrl = new Url
{
Scheme = requestUrl.Scheme,
HostName = requestUrl.Host,
Port = requestUrl.IsDefaultPort ? null : (int?)requestUrl.Port,
BasePath = baseUri.AbsolutePath.TrimEnd('/'),
Path = HttpUtility.UrlDecode(head.Uri),
Query = requestUrl.Query,
Fragment = requestUrl.Fragment,
};
Dictionary<string, IEnumerable<string>> headers = new Dictionary<string, IEnumerable<string>>();
foreach (var kvp in head.Headers)
headers[kvp.Key] = new List<string> { kvp.Value };

Request req = new Request(
head.Method,
nancyUrl,
Nancy.IO.RequestStream.FromStream(requestStream, requestStream.Length),
headers,
null);

m_Engine.HandleRequest(req, context => RequestProcessingCompleted(context, response), ex => RequestProcessingError(ex, response));
}

private void RequestReadError(Exception ex)
{
throw new NotImplementedException();
}

private void RequestProcessingCompleted(NancyContext context, IHttpResponseDelegate response)
{
HttpResponseHead responseHead = new HttpResponseHead {
Headers = context.Response.Headers,
Status = context.Response.StatusCode.ToString()
};

byte[] responseBodyData;
using (MemoryStream ms = new MemoryStream())
{
context.Response.Contents(ms);
//ms.Seek(0, SeekOrigin.Begin);
responseBodyData = ms.ToArray();
}

responseHead.Headers["Content-Type"] = context.Response.ContentType;
responseHead.Headers["Content-Length"] = responseBodyData.LongLength.ToString();

BufferedProducer bodyDataProducer = new BufferedProducer (responseBodyData);
response.OnResponse(responseHead, bodyDataProducer);
}

private void RequestProcessingError(Exception ex, IHttpResponseDelegate response)
{
throw new NotImplementedException();
}
}
}
22 changes: 22 additions & 0 deletions CloudLogCAT/NancyTest.cs
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nancy;

namespace CloudlogCAT
{
public sealed class NancyTest : NancyModule
{
public NancyTest()
{
Get["/"] = _ => "CloudLog CAT is running.";
Get["/foo/{bar}"] = Bar;
}

private string Bar(dynamic parameters)
{
return Request.Url.ToString();
}
}
}
5 changes: 5 additions & 0 deletions CloudLogCAT/Program.cs
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Net;

namespace CloudlogCAT
{
Expand All @@ -13,9 +14,13 @@ static class Program
[STAThread]
static void Main()
{

var nancyHost = new HttpServer.HttpHost(new IPEndPoint(IPAddress.Any, 8083));
nancyHost.Start();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
nancyHost.Stop();
}
}
}
4 changes: 4 additions & 0 deletions CloudLogCAT/packages.config
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Nancy" version="0.14.0" targetFramework="net40" />
</packages>
Binary file added packages/Nancy.0.14.0/Nancy.0.14.0.nupkg
Binary file not shown.
18 changes: 18 additions & 0 deletions packages/Nancy.0.14.0/Nancy.0.14.0.nuspec
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Nancy</id>
<version>0.14.0</version>
<authors>Andreas Håkansson, Steven Robbins and contributors</authors>
<owners>Andreas Håkansson, Steven Robbins and contributors</owners>
<licenseUrl>https://github.com/NancyFx/Nancy/blob/master/license.txt</licenseUrl>
<projectUrl>http://nancyfx.org/</projectUrl>
<iconUrl>http://nancyfx.org/nancy-nuget.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Nancy is a lightweight web framework for the .Net platform, inspired by Sinatra. Nancy aim at delivering a low ceremony approach to building light, fast web applications.</description>
<summary>Nancy is a lightweight web framework for the .Net platform, inspired by Sinatra. Nancy aim at delivering a low ceremony approach to building light, fast web applications.</summary>
<copyright>Andreas Håkansson, Steven Robbins and contributors</copyright>
<language>en-US</language>
<tags>Nancy</tags>
</metadata>
</package>
Binary file added packages/Nancy.0.14.0/lib/net40/Nancy.dll
Binary file not shown.
4 changes: 4 additions & 0 deletions packages/repositories.config
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<repositories>
<repository path="..\CloudLogCAT\packages.config" />
</repositories>

0 comments on commit 2840cd3

Please sign in to comment.