Skip to content

Instantly share code, notes, and snippets.

@gsscoder
Last active September 22, 2024 14:45
Show Gist options
  • Select an option

  • Save gsscoder/4750069 to your computer and use it in GitHub Desktop.

Select an option

Save gsscoder/4750069 to your computer and use it in GitHub Desktop.
Super-Simple HTTP Server, demonstrates use of https://github.com/gsscoder/surfhttp (work in progress)
/*
* Toy HTTP Sample Server
* Giacomo Stelluti Scala ([email protected])
* Demonstrates use of https://github.com/gsscoder/surfhttp (work in progress).
* How to execute: Copy & paste, then add a reference to Surf.dll.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using Surf.Http;
using Surf.Http.Formatters;
using Surf.Http.Parser;
using Surf.Http.Serialization;
using HttpStatusCode = Surf.Http.HttpStatusCode;
namespace Surf.Sample1
{
class Program
{
static void Main(string[] args)
{
var server = new SampleServer();
server.GoUp();
Console.ReadKey();
server.GoDown();
}
}
class TraceableCallbacks : IHttpRequestParserCallbacks
{
public void OnMessageBegin(IHttpRequestParser parser)
{
}
public void OnRequestLine(IHttpRequestParser parser, string method, string uri, string version)
{
Trace.WriteLine("--REQUEST-LINE\n\t" + method + " " + uri + " " + version);
}
public void OnHeaderLine(IHttpRequestParser parser, string name, string value)
{
Trace.WriteLine("--HEADER\n\t" + name + "-> " + value + "\n]");
}
public void OnBody(IHttpRequestParser parser, ArraySegment<byte> data)
{
}
public void OnMessageEnd(IHttpRequestParser parser)
{
}
}
class SampleServer
{
public SampleServer()
{
_listener = new TcpListener(new IPAddress(new byte[] { 0, 0, 0, 0 }), 8899);
}
public void GoUp()
{
_listener.Start();
Trace.WriteLine("SampleServer UP :D");
_listener.BeginAcceptSocket(AcceptCallback, null);
}
public void GoDown()
{
_listener.Stop();
Trace.WriteLine("SampleServer DOWN :(");
}
private void AcceptCallback(IAsyncResult asr)
{
Socket socket;
try
{
socket = _listener.EndAcceptSocket(asr);
}
catch (ObjectDisposedException)
{
return;
}
_listener.BeginAcceptSocket(AcceptCallback, null);
Task.Factory.StartNew(() =>
{
var ns = new NetworkStream(socket, FileAccess.ReadWrite, false);
// -==READ, PARSE Request==-
var buffer = new List<byte>();
while (ns.DataAvailable)
{
buffer.Add((byte)ns.ReadByte());
}
//Trace.Write(Encoding.UTF8.GetString(buffer.ToArray()));
var cbacks = new TraceableCallbacks();
var parser = new HttpRequestParser(cbacks);
parser.Parse(new ArraySegment<byte>(buffer.ToArray()));
// -==COMPOSE, WRITE Response==-
var response = new HttpResponse { StatusCode = HttpStatusCode.OK };
response.Headers["Date"] = HttpHeaderFormatter.Default.FormatHttpDateString(DateTime.Now);
response.Body = new ArraySegment<byte>(Encoding.UTF8.GetBytes(
"<html><body><p>Hello, world!<br/>Ticks: " +
DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture) +
"</p></body></html>"
));
var serializer = new HttpResponseSerializer();
serializer.Serialize(ns, response);
ns.Close();
socket.Close();
});
}
private readonly TcpListener _listener;
}
}
#region App.config
/*
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<add name="configConsoleListener"
type="System.Diagnostics.ConsoleTraceListener" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
*/
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment