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

Commit 2840cd3

Browse files
committed
Nancy / Kayak in and linked together!
1 parent f4e5184 commit 2840cd3

File tree

12 files changed

+296
-1
lines changed

12 files changed

+296
-1
lines changed

CloudLogCAT/CloudlogCAT.csproj

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,13 @@
3434
<WarningLevel>4</WarningLevel>
3535
</PropertyGroup>
3636
<ItemGroup>
37-
<Reference Include="Kayak">
37+
<Reference Include="Kayak, Version=0.7.2.0, Culture=neutral, processorArchitecture=MSIL">
38+
<SpecificVersion>False</SpecificVersion>
3839
<HintPath>..\Referenced Dlls\Kayak\Kayak.dll</HintPath>
3940
</Reference>
41+
<Reference Include="Nancy">
42+
<HintPath>..\packages\Nancy.0.14.0\lib\net40\Nancy.dll</HintPath>
43+
</Reference>
4044
<Reference Include="System" />
4145
<Reference Include="System.Core" />
4246
<Reference Include="System.Web.Extensions">
@@ -60,12 +64,17 @@
6064
<Compile Include="ConnectionForm.Designer.cs">
6165
<DependentUpon>ConnectionForm.cs</DependentUpon>
6266
</Compile>
67+
<Compile Include="HttpServer\BufferedConsumer.cs" />
68+
<Compile Include="HttpServer\BufferedProducer.cs" />
69+
<Compile Include="HttpServer\HttpHost.cs" />
70+
<Compile Include="HttpServer\NancyRequestDelegate.cs" />
6371
<Compile Include="MainForm.cs">
6472
<SubType>Form</SubType>
6573
</Compile>
6674
<Compile Include="MainForm.Designer.cs">
6775
<DependentUpon>MainForm.cs</DependentUpon>
6876
</Compile>
77+
<Compile Include="NancyTest.cs" />
6978
<Compile Include="Program.cs" />
7079
<Compile Include="Properties\AssemblyInfo.cs" />
7180
<Compile Include="Settings.cs" />
@@ -86,6 +95,7 @@
8695
<DesignTime>True</DesignTime>
8796
</Compile>
8897
<None Include="app.config" />
98+
<None Include="packages.config" />
8999
<None Include="Properties\Settings.settings">
90100
<Generator>SettingsSingleFileGenerator</Generator>
91101
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
@@ -102,6 +112,7 @@
102112
<Name>RigCAT.NET</Name>
103113
</ProjectReference>
104114
</ItemGroup>
115+
<ItemGroup />
105116
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
106117
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
107118
Other similar extension points exist, see Microsoft.Common.targets.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using Kayak;
6+
using System.IO;
7+
8+
namespace CloudlogCAT.HttpServer
9+
{
10+
internal class BufferedConsumer : IDataConsumer
11+
{
12+
MemoryStream m_DataBuffer = new MemoryStream();
13+
Action<Stream> resultCallback;
14+
Action<Exception> errorCallback;
15+
16+
public BufferedConsumer(Action<Stream> resultCallback, Action<Exception> errorCallback)
17+
{
18+
this.resultCallback = resultCallback;
19+
this.errorCallback = errorCallback;
20+
}
21+
public bool OnData(ArraySegment<byte> data, Action continuation)
22+
{
23+
// since we're just buffering, ignore the continuation.
24+
// TODO: place an upper limit on the size of the buffer.
25+
// don't want a client to take up all the RAM on our server!
26+
m_DataBuffer.Write(data.Array, data.Offset, data.Count);
27+
return false;
28+
}
29+
public void OnError(Exception error)
30+
{
31+
errorCallback(error);
32+
}
33+
34+
public void OnEnd()
35+
{
36+
resultCallback(m_DataBuffer);
37+
}
38+
}
39+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using Kayak;
6+
7+
namespace CloudlogCAT.HttpServer
8+
{
9+
internal class BufferedProducer : IDataProducer
10+
{
11+
ArraySegment<byte> data;
12+
13+
public BufferedProducer(string data) : this(data, Encoding.UTF8) { }
14+
public BufferedProducer(string data, Encoding encoding) : this(encoding.GetBytes(data)) { }
15+
public BufferedProducer(byte[] data) : this(new ArraySegment<byte>(data)) { }
16+
public BufferedProducer(ArraySegment<byte> data)
17+
{
18+
this.data = data;
19+
}
20+
21+
public IDisposable Connect(IDataConsumer channel)
22+
{
23+
// null continuation, consumer must swallow the data immediately.
24+
channel.OnData(data, null);
25+
channel.OnEnd();
26+
return null;
27+
}
28+
}
29+
}

CloudLogCAT/HttpServer/HttpHost.cs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using Kayak;
6+
using Kayak.Http;
7+
using Nancy;
8+
using Nancy.Bootstrapper;
9+
using System.Diagnostics;
10+
using System.Net;
11+
using System.Threading;
12+
13+
namespace CloudlogCAT.HttpServer
14+
{
15+
internal sealed class HttpHost
16+
{
17+
INancyEngine m_Engine;
18+
private IScheduler m_Scheduler;
19+
private IServer m_Server;
20+
private IPEndPoint m_EndPoint;
21+
22+
public HttpHost(IPEndPoint endpoint)
23+
{
24+
var bootStrapper = NancyBootstrapperLocator.Bootstrapper;
25+
bootStrapper.Initialise();
26+
m_Engine = bootStrapper.GetEngine();
27+
m_EndPoint = endpoint;
28+
}
29+
30+
public void Start()
31+
{
32+
m_Scheduler = KayakScheduler.Factory.Create(new SchedulerDelegate());
33+
m_Server = KayakServer.Factory.CreateHttp(new NancyRequestDelegate(m_Engine), m_Scheduler);
34+
35+
IDisposable disposable = m_Server.Listen(m_EndPoint);
36+
Thread schedulerWorkerThread = new Thread(SchedulerWorker);
37+
schedulerWorkerThread.IsBackground = true;
38+
schedulerWorkerThread.Start(disposable);
39+
m_Scheduler.Post(GetLocalPort);
40+
}
41+
42+
private void GetLocalPort()
43+
{
44+
Debug.WriteLine(m_EndPoint.Port);
45+
}
46+
47+
private void SchedulerWorker(object disposable)
48+
{
49+
using ((IDisposable)disposable)
50+
{
51+
m_Scheduler.Start();
52+
}
53+
}
54+
55+
public void Stop()
56+
{
57+
m_Scheduler.Stop();
58+
}
59+
60+
private class SchedulerDelegate : ISchedulerDelegate
61+
{
62+
public void OnException(IScheduler scheduler, Exception e)
63+
{
64+
Debug.WriteLine("Error on scheduler.");
65+
e.DebugStackTrace();
66+
}
67+
68+
public void OnStop(IScheduler scheduler)
69+
{
70+
71+
}
72+
}
73+
74+
}
75+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using Nancy;
6+
using Kayak.Http;
7+
using Nancy.Helpers;
8+
using System.IO;
9+
10+
namespace CloudlogCAT.HttpServer
11+
{
12+
internal sealed class NancyRequestDelegate : IHttpRequestDelegate
13+
{
14+
private INancyEngine m_Engine;
15+
16+
public NancyRequestDelegate(INancyEngine engine)
17+
{
18+
m_Engine = engine;
19+
}
20+
21+
public void OnRequest(HttpRequestHead head, Kayak.IDataProducer body, IHttpResponseDelegate response)
22+
{
23+
BufferedConsumer requestConsumer = new BufferedConsumer(bodyStream => RequestReadCompleted(head, bodyStream, response), RequestReadError);
24+
body.Connect(requestConsumer);
25+
}
26+
27+
private void RequestReadCompleted(HttpRequestHead head, Stream requestStream, IHttpResponseDelegate response)
28+
{
29+
#warning wrong hard-coded base URI
30+
Uri baseUri = new Uri("http://localhost:8083/");
31+
Uri requestUrl = new Uri(baseUri, head.Uri);
32+
Url nancyUrl = new Url
33+
{
34+
Scheme = requestUrl.Scheme,
35+
HostName = requestUrl.Host,
36+
Port = requestUrl.IsDefaultPort ? null : (int?)requestUrl.Port,
37+
BasePath = baseUri.AbsolutePath.TrimEnd('/'),
38+
Path = HttpUtility.UrlDecode(head.Uri),
39+
Query = requestUrl.Query,
40+
Fragment = requestUrl.Fragment,
41+
};
42+
Dictionary<string, IEnumerable<string>> headers = new Dictionary<string, IEnumerable<string>>();
43+
foreach (var kvp in head.Headers)
44+
headers[kvp.Key] = new List<string> { kvp.Value };
45+
46+
Request req = new Request(
47+
head.Method,
48+
nancyUrl,
49+
Nancy.IO.RequestStream.FromStream(requestStream, requestStream.Length),
50+
headers,
51+
null);
52+
53+
m_Engine.HandleRequest(req, context => RequestProcessingCompleted(context, response), ex => RequestProcessingError(ex, response));
54+
}
55+
56+
private void RequestReadError(Exception ex)
57+
{
58+
throw new NotImplementedException();
59+
}
60+
61+
private void RequestProcessingCompleted(NancyContext context, IHttpResponseDelegate response)
62+
{
63+
HttpResponseHead responseHead = new HttpResponseHead {
64+
Headers = context.Response.Headers,
65+
Status = context.Response.StatusCode.ToString()
66+
};
67+
68+
byte[] responseBodyData;
69+
using (MemoryStream ms = new MemoryStream())
70+
{
71+
context.Response.Contents(ms);
72+
//ms.Seek(0, SeekOrigin.Begin);
73+
responseBodyData = ms.ToArray();
74+
}
75+
76+
responseHead.Headers["Content-Type"] = context.Response.ContentType;
77+
responseHead.Headers["Content-Length"] = responseBodyData.LongLength.ToString();
78+
79+
BufferedProducer bodyDataProducer = new BufferedProducer (responseBodyData);
80+
response.OnResponse(responseHead, bodyDataProducer);
81+
}
82+
83+
private void RequestProcessingError(Exception ex, IHttpResponseDelegate response)
84+
{
85+
throw new NotImplementedException();
86+
}
87+
}
88+
}

CloudLogCAT/NancyTest.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using Nancy;
6+
7+
namespace CloudlogCAT
8+
{
9+
public sealed class NancyTest : NancyModule
10+
{
11+
public NancyTest()
12+
{
13+
Get["/"] = _ => "CloudLog CAT is running.";
14+
Get["/foo/{bar}"] = Bar;
15+
}
16+
17+
private string Bar(dynamic parameters)
18+
{
19+
return Request.Url.ToString();
20+
}
21+
}
22+
}

CloudLogCAT/Program.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Windows.Forms;
5+
using System.Net;
56

67
namespace CloudlogCAT
78
{
@@ -13,9 +14,13 @@ static class Program
1314
[STAThread]
1415
static void Main()
1516
{
17+
18+
var nancyHost = new HttpServer.HttpHost(new IPEndPoint(IPAddress.Any, 8083));
19+
nancyHost.Start();
1620
Application.EnableVisualStyles();
1721
Application.SetCompatibleTextRenderingDefault(false);
1822
Application.Run(new MainForm());
23+
nancyHost.Stop();
1924
}
2025
}
2126
}

CloudLogCAT/packages.config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<packages>
3+
<package id="Nancy" version="0.14.0" targetFramework="net40" />
4+
</packages>
316 KB
Binary file not shown.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0"?>
2+
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
3+
<metadata>
4+
<id>Nancy</id>
5+
<version>0.14.0</version>
6+
<authors>Andreas Håkansson, Steven Robbins and contributors</authors>
7+
<owners>Andreas Håkansson, Steven Robbins and contributors</owners>
8+
<licenseUrl>https://github.com/NancyFx/Nancy/blob/master/license.txt</licenseUrl>
9+
<projectUrl>http://nancyfx.org/</projectUrl>
10+
<iconUrl>http://nancyfx.org/nancy-nuget.png</iconUrl>
11+
<requireLicenseAcceptance>false</requireLicenseAcceptance>
12+
<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>
13+
<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>
14+
<copyright>Andreas Håkansson, Steven Robbins and contributors</copyright>
15+
<language>en-US</language>
16+
<tags>Nancy</tags>
17+
</metadata>
18+
</package>

0 commit comments

Comments
 (0)