Skip to content

Commit 7536348

Browse files
committed
Added working Example project code
1 parent 25ab594 commit 7536348

22 files changed

+1988
-2
lines changed

HttpWebServer.sln

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ Global
2121
{F2AB258C-3FD8-4D46-B8C0-F4BBCF220216}.Release|Any CPU.Build.0 = Release|Any CPU
2222
EndGlobalSection
2323
GlobalSection(MonoDevelopProperties) = preSolution
24-
StartupItem = HttpWebServer\HttpWebServer.csproj
24+
StartupItem = HttpWebServerExample\HttpWebServerExample.csproj
2525
EndGlobalSection
2626
EndGlobal

HttpWebServerExample/HttpWebServerExample.csproj

+56
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<ItemGroup>
3434
<Compile Include="Program.cs" />
3535
<Compile Include="Properties\AssemblyInfo.cs" />
36+
<Compile Include="StaticWebServer.cs" />
3637
</ItemGroup>
3738
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
3839
<ItemGroup>
@@ -41,4 +42,59 @@
4142
<Name>HttpWebServer</Name>
4243
</ProjectReference>
4344
</ItemGroup>
45+
<ItemGroup>
46+
<None Include="www\apple-touch-icon-precomposed.png">
47+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
48+
</None>
49+
<None Include="www\favicon.ico">
50+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
51+
</None>
52+
<None Include="www\index.html">
53+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
54+
</None>
55+
<None Include="www\LICENSE" />
56+
<None Include="www\README.md" />
57+
<None Include="www\css\main.css">
58+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
59+
</None>
60+
<None Include="www\js\main.js">
61+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
62+
</None>
63+
<None Include="www\partials\404.html">
64+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
65+
</None>
66+
<None Include="www\partials\about.html">
67+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
68+
</None>
69+
<None Include="www\partials\blog.html">
70+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
71+
</None>
72+
<None Include="www\partials\blog_item.html">
73+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
74+
</None>
75+
<None Include="www\partials\contact.html">
76+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
77+
</None>
78+
<None Include="www\partials\faq.html">
79+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
80+
</None>
81+
<None Include="www\partials\home.html">
82+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
83+
</None>
84+
<None Include="www\partials\pricing.html">
85+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
86+
</None>
87+
<None Include="www\partials\services.html">
88+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
89+
</None>
90+
<None Include="www\templates\footer.html">
91+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
92+
</None>
93+
<None Include="www\templates\header.html">
94+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
95+
</None>
96+
</ItemGroup>
97+
<ItemGroup>
98+
<Folder Include="www\" />
99+
</ItemGroup>
44100
</Project>

HttpWebServerExample/Program.cs

+32-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,43 @@
11
using System;
22

3+
using RipcordSoftware.HttpWebServer;
4+
35
namespace HttpWebServerExample
46
{
57
class MainClass
68
{
9+
private const int port = 3010;
10+
11+
private static bool RequestCallback(HttpWebRequest request, HttpWebResponse response)
12+
{
13+
var status = StaticWebServer.HandleRequest(request, response);
14+
15+
if (status)
16+
{
17+
Console.WriteLine("{0}: {1}, {2}", request.HttpMethod, request.Uri, response.StatusCode);
18+
}
19+
20+
return status;
21+
}
22+
23+
private static bool RequestContinueCallback(HttpWebRequest request)
24+
{
25+
return true;
26+
}
27+
728
public static void Main(string[] args)
829
{
9-
Console.WriteLine("Hello World!");
30+
var bindings = new HttpWebServer.Binding[] { new HttpWebServer.Binding("127.0.0.1", port, false) };
31+
var config = new HttpWebServer.Config();
32+
33+
using (var server = new HttpWebServer(bindings, config))
34+
{
35+
server.Start(RequestCallback, RequestContinueCallback);
36+
37+
Console.WriteLine("Listening on port {0}", port);
38+
39+
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
40+
}
1041
}
1142
}
1243
}
+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
using System;
2+
using System.IO;
3+
using System.Collections.Generic;
4+
5+
using RipcordSoftware.HttpWebServer;
6+
7+
namespace HttpWebServerExample
8+
{
9+
public class StaticWebServer
10+
{
11+
private class ContentTypeInfo
12+
{
13+
public ContentTypeInfo(string extension, string contentType, bool compressible)
14+
{
15+
Extension = extension;
16+
ContentType = contentType;
17+
Compressible = compressible;
18+
}
19+
20+
public string Extension { get; protected set; }
21+
22+
public string ContentType { get; protected set; }
23+
24+
public bool Compressible { get; protected set; }
25+
}
26+
27+
private static readonly Dictionary<string, ContentTypeInfo> contentTypeLookup = new Dictionary<string, ContentTypeInfo>()
28+
{
29+
{ "jpg", new ContentTypeInfo("jpg", @"image/jpg", false) },
30+
{ "png", new ContentTypeInfo("png", @"image/png", false) },
31+
{ "gif", new ContentTypeInfo("gif", @"image/gif", false) },
32+
{ "ico", new ContentTypeInfo("ico", @"image/ico", true) },
33+
{ "bmp", new ContentTypeInfo("bmp", @"image/x-ms-bmp", true) },
34+
{ "html", new ContentTypeInfo("html", @"text/html", true) },
35+
{ "htm", new ContentTypeInfo("htm", @"text/html", true) },
36+
{ "css", new ContentTypeInfo("css", @"text/css", true) },
37+
{ "js", new ContentTypeInfo("js", @"text/javascript", true) },
38+
{ "txt", new ContentTypeInfo("txt", @"text/plain", true) },
39+
{ "xml", new ContentTypeInfo("xml", @"text/xml", true) },
40+
{ "woff", new ContentTypeInfo("woff", @"application/font-woff", false) },
41+
{ "svg", new ContentTypeInfo("svg", @"image/svg+xml", true) }
42+
};
43+
44+
private static ContentTypeInfo GetContentTypeInfo(string extn)
45+
{
46+
ContentTypeInfo info = null;
47+
48+
if (extn.Contains("/"))
49+
{
50+
extn = System.IO.Path.GetExtension(extn);
51+
}
52+
53+
if (extn.StartsWith("."))
54+
{
55+
extn = extn.Substring(1);
56+
}
57+
58+
contentTypeLookup.TryGetValue(extn, out info);
59+
return info;
60+
}
61+
62+
private static string UrlAppendPath(string url, string path)
63+
{
64+
var appendedUrl = url;
65+
66+
if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(path))
67+
{
68+
var terminated = url.EndsWith("/");
69+
var prefixed = path.StartsWith("/");
70+
71+
if (terminated && prefixed)
72+
{
73+
appendedUrl = url + path.Substring(1);
74+
}
75+
else if (!terminated && !prefixed)
76+
{
77+
appendedUrl = url + "/" + path;
78+
}
79+
else
80+
{
81+
appendedUrl = url + path;
82+
}
83+
}
84+
85+
return appendedUrl;
86+
}
87+
88+
public static bool HandleRequest(HttpWebRequest request, HttpWebResponse response)
89+
{
90+
bool handled = false;
91+
92+
if (request.HttpMethod == "GET")
93+
{
94+
try
95+
{
96+
var filePath = "www" + request.Uri;
97+
var fileInfo = new FileInfo(filePath);
98+
99+
if (fileInfo.Attributes == FileAttributes.Directory)
100+
{
101+
var redirect = UrlAppendPath(request.Uri, "index.html");
102+
response.Redirect(redirect);
103+
handled = true;
104+
}
105+
else
106+
{
107+
var contentTypeInfo = GetContentTypeInfo(filePath);
108+
if (contentTypeInfo != null)
109+
{
110+
if (fileInfo != null)
111+
{
112+
// we are going to return something, so let the caller know it happened
113+
handled = true;
114+
115+
// the client may already have the file, so check the timestamps
116+
bool clientHasFile = false;
117+
var ifModifiedSince = request.Headers["If-Modified-Since"];
118+
if (!string.IsNullOrEmpty(ifModifiedSince))
119+
{
120+
try
121+
{
122+
var lastModifiedTimestamp = DateTime.Parse(ifModifiedSince);
123+
clientHasFile = fileInfo.LastWriteTime <= lastModifiedTimestamp;
124+
}
125+
catch
126+
{
127+
}
128+
}
129+
130+
if (!clientHasFile)
131+
{
132+
// read the file from disk and return the contents to the client
133+
using (var inFile = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
134+
{
135+
// send the last modified file time so we can cache any further requests from this client
136+
response.Headers["Last-Modified"] = fileInfo.LastWriteTimeUtc.ToString("r");
137+
138+
// set the content type
139+
response.ContentType = contentTypeInfo.ContentType;
140+
141+
using (var stream = response.GetResponseStream(request.AcceptEncoding))
142+
{
143+
inFile.CopyTo(stream);
144+
}
145+
}
146+
}
147+
else
148+
{
149+
// the client has the file, so send a 304
150+
response.StatusCode = 304;
151+
response.ContentType = contentTypeInfo.ContentType;
152+
}
153+
}
154+
}
155+
}
156+
}
157+
catch (System.Exception ex)
158+
{
159+
// TODO: do something more useful here
160+
Console.WriteLine("ERROR: " + ex.Message);
161+
}
162+
}
163+
164+
return handled;
165+
}
166+
}
167+
}
168+

HttpWebServerExample/www/LICENSE

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
This is free and unencumbered software released into the public domain.
2+
3+
Anyone is free to copy, modify, publish, use, compile, sell, or
4+
distribute this software, either in source code form or as a compiled
5+
binary, for any purpose, commercial or non-commercial, and by any
6+
means.
7+
8+
In jurisdictions that recognize copyright laws, the author or authors
9+
of this software dedicate any and all copyright interest in the
10+
software to the public domain. We make this dedication for the benefit
11+
of the public at large and to the detriment of our heirs and
12+
successors. We intend this dedication to be an overt act of
13+
relinquishment in perpetuity of all present and future rights to this
14+
software under copyright law.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
OTHER DEALINGS IN THE SOFTWARE.
23+
24+
For more information, please refer to <http://unlicense.org>

HttpWebServerExample/www/README.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
AngularJS Tutorial 1
2+
====================
3+
4+
author: [Nick Kaye](http://www.nickkaye.com)
5+
6+
**NOTE: We’re referencing all of our vendor dependencies (e.g. Bootstrap, jQuery, Angular) at outside URLs. Therefore, it is necessary to host our site while we’re working on it. Be sure we are viewing it in a browser with http:// -- not file://**
7+
8+
View the [live demo](http://airpair.github.io/demos/2014/09/T0021-airpair-angularjs-tutorial).
Loading

0 commit comments

Comments
 (0)