diff --git a/examples/c#/example.cs b/examples/c#/example.cs new file mode 100644 index 0000000000000000000000000000000000000000..07f5048c01d30f5a6e8ce94da6351f909d5e6dd2 --- /dev/null +++ b/examples/c#/example.cs @@ -0,0 +1,27 @@ +// This file is part of mongoose web server project, +// https://github.com/cesanta/mongoose + +using System; +using System.Runtime.InteropServices; + +public class Program { + static private int RequestHandler(MongooseConnection conn) { + return 0; + /* + conn.write("HTTP/1.1 200 OK\r\n\r\n"); + conn.write("Hello from C#!\n"); + conn.write("Your user-agent is: " + conn.get_header("User-Agent") + "\n"); + */ + } + + static void Main() { + Mongoose web_server = new Mongoose("c:\\", "8080", + new MongooseBeginRequest(RequestHandler)); + + Console.WriteLine("Mongoose v." + web_server.version_ + " started."); + Console.WriteLine("Press enter to exit program."); + + // Serve requests until user presses "enter" on a keyboard + Console.ReadLine(); + } +} diff --git a/examples/c#/mongoose.cs b/examples/c#/mongoose.cs new file mode 100644 index 0000000000000000000000000000000000000000..68afed1f84d7f4ec4ed4fe6f143339d9f5a01e27 --- /dev/null +++ b/examples/c#/mongoose.cs @@ -0,0 +1,118 @@ +// This file is part of mongoose web server project, +// https://github.com/cesanta/mongoose + +using System; +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] public struct MongooseHeader { + public IntPtr name; // Using IntPtr here because if we use strings here, + public IntPtr value; // it won't be properly marshalled. +}; + +// mongoose.h :: struct mg_request_info +[StructLayout(LayoutKind.Sequential)] public struct MongooseRequestInfo { + public string request_method; + public string uri; + public string http_version; + public string query_string; + public string remote_user; + public int remote_ip; + public int remote_port; + public int is_ssl; + public IntPtr user_data; + public IntPtr conn_data; + [MarshalAs(UnmanagedType.ByValArray,SizeConst=64)] + public MongooseHeader[] http_headers; +}; + +[UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate + int MongooseBeginRequest_native(IntPtr conn); +public delegate int MongooseBeginRequest(MongooseConnection conn); + +// mongoose.h :: struct mg_callbacks +[StructLayout(LayoutKind.Sequential)] public struct MongooseCallbacks { + public MongooseBeginRequest_native begin_request; + [MarshalAs(UnmanagedType.ByValArray,SizeConst=20)] + public IntPtr[] other_callbacks; +}; + +public class Mongoose { + public const string dll_name_ = "mongoose"; + public string version_ = "??"; + + // These are here to store a ref to the callbacks + // while they are over in unmanaged code, to prevent garbage collection. + private event MongooseBeginRequest_native delegates; + + private IntPtr ctx_; + + [DllImport(dll_name_)] private static extern + IntPtr mg_start([MarshalAs(UnmanagedType.LPArray, + ArraySubType=UnmanagedType.LPTStr)] string[] options, + ref MongooseCallbacks callbacks, + IntPtr user_data); + [DllImport(dll_name_)] public static extern + IntPtr mg_get_request_info(IntPtr conn); + [DllImport(dll_name_)] private static extern void mg_stop(IntPtr ctx); + [DllImport(dll_name_)] private static extern string mg_version(); + + public Mongoose(string document_root, string listening_ports, + MongooseBeginRequest request_handler) { + version_ = mg_version(); + + string[] options = { + "document_root", document_root, + "listening_ports", listening_ports, + null + }; + + MongooseBeginRequest_native begin_request_cb = delegate(IntPtr conn) { + return request_handler(new MongooseConnection(conn, this)); + }; + MongooseCallbacks callbacks = new MongooseCallbacks(); + callbacks.begin_request = begin_request_cb; + + // Prevent garbage collection + delegates += begin_request_cb; + + ctx_ = mg_start(options, ref callbacks, IntPtr.Zero); + } + + ~Mongoose() { + if (this.ctx_ != IntPtr.Zero) { + mg_stop(this.ctx_); + } + this.ctx_ = IntPtr.Zero; + } +} + +public class MongooseConnection { + public Mongoose mongoose; + private IntPtr conn; + + [DllImport(Mongoose.dll_name_)] private static extern + string mg_get_header(IntPtr conn, string name); + [DllImport(Mongoose.dll_name_)] private static extern + string mg_get_var(IntPtr conn, string name); + [DllImport(Mongoose.dll_name_)] public static extern + int mg_write(IntPtr conn, string data, int length); + + public MongooseConnection(IntPtr conn_, Mongoose mongoose_) { + mongoose = mongoose_; + conn = conn_; + } + + public string get_header(string header_name) { + return mg_get_header(this.conn, header_name); + } + + public string get_var(string header_name) { + string s = mg_get_var(this.conn, header_name); + string copy = "" + s; + return copy; + } + + public int write(string data) { + return mg_write(this.conn, data, data.Length); + } +}