mongoose.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Copyright (c) 2004-2009 Sergey Lyubka
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. //
  21. // $Id: mongoose.cs 472 2009-08-30 22:40:29Z spsone1 $
  22. using System;
  23. using System.Runtime.InteropServices;
  24. [StructLayout(LayoutKind.Sequential)] public struct MongooseHeader {
  25. public IntPtr name; // Using IntPtr here because if we use strings here,
  26. public IntPtr value; // it won't be properly marshalled.
  27. };
  28. // This is "struct mg_request_info" from mongoose.h header file
  29. [StructLayout(LayoutKind.Sequential)] public struct MongooseRequestInfo {
  30. public string request_method;
  31. public string uri;
  32. public string http_version;
  33. public string query_string;
  34. public IntPtr post_data;
  35. public string remote_user;
  36. public int remote_ip; //int to match the 32bit declaration in c
  37. public int remote_port;
  38. public int post_data_len;
  39. public int status_code;
  40. public int num_headers;
  41. [MarshalAs(UnmanagedType.ByValArray,SizeConst=64)] public MongooseHeader[] http_headers;
  42. };
  43. // This is a delegate for mg_callback_t from mongoose.h header file
  44. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  45. public delegate void MongooseCallback2(IntPtr conn, ref MongooseRequestInfo ri, IntPtr user_data);
  46. // This is a delegate to be used by the application
  47. public delegate void MongooseCallback(MongooseConnection conn, MongooseRequestInfo ri);
  48. public class Mongoose {
  49. public string version;
  50. private IntPtr ctx;
  51. //These two events are here to store a ref to the callbacks while they are over in unmanaged code.
  52. private event MongooseCallback2 delegates2;
  53. private event MongooseCallback delegates1;
  54. [DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern IntPtr mg_start();
  55. [DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern void mg_stop(IntPtr ctx);
  56. [DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern string mg_version();
  57. [DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern int mg_set_option(IntPtr ctx, string name, string value);
  58. [DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern string mg_get_option(IntPtr ctx, string name);
  59. [DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern void mg_set_uri_callback(IntPtr ctx, string uri_regex, MulticastDelegate func, IntPtr data);
  60. [DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern void mg_set_log_callback(IntPtr ctx, MulticastDelegate func);
  61. public Mongoose() {
  62. ctx = mg_start();
  63. version = mg_version();
  64. }
  65. ~Mongoose() {
  66. mg_stop(this.ctx);
  67. this.ctx = IntPtr.Zero;
  68. }
  69. public int set_option(string option_name, string option_value) {
  70. return mg_set_option(this.ctx, option_name, option_value);
  71. }
  72. public string get_option(string option_name) {
  73. return mg_get_option(this.ctx, option_name);
  74. }
  75. public void set_uri_callback(string uri_regex, MongooseCallback func) {
  76. // Build a closure around user function. Initialize connection object there which wraps
  77. // mg_write() and other useful methods, and then call user specified handler.
  78. MongooseCallback2 callback = delegate(IntPtr conn, ref MongooseRequestInfo ri, IntPtr user_data) {
  79. MongooseConnection connection = new MongooseConnection(conn, this);
  80. func(connection, ri);
  81. };
  82. // store a reference to the callback so it won't be GC'ed while its over in unmanged code
  83. delegates2 += callback;
  84. mg_set_uri_callback(this.ctx, uri_regex, callback, IntPtr.Zero);
  85. }
  86. public void set_log_callback(MongooseCallback func) {
  87. delegates1 += func;
  88. mg_set_log_callback(this.ctx, func);
  89. }
  90. }
  91. public class MongooseConnection {
  92. public Mongoose mongoose;
  93. private IntPtr conn;
  94. [DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern string mg_get_header(IntPtr ctx, string name);
  95. [DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern string mg_get_var(IntPtr ctx, string name);
  96. [DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern void mg_free(IntPtr ptr);
  97. [DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] public static extern int mg_write(IntPtr conn, string data, int length);
  98. public MongooseConnection(IntPtr conn_, Mongoose mongoose_) {
  99. mongoose = mongoose_;
  100. conn = conn_;
  101. }
  102. public string get_header(string header_name) {
  103. return mg_get_header(this.conn, header_name);
  104. }
  105. public string get_var(string header_name) {
  106. string s = mg_get_var(this.conn, header_name);
  107. string copy = "" + s;
  108. mg_free(Marshal.StringToHGlobalAnsi(s));
  109. return copy;
  110. }
  111. public int write(string data) {
  112. return mg_write(this.conn, data, data.Length);
  113. }
  114. }