RequestHeader.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. using System;
  2. using System.IO;
  3. using System.Net;
  4. using System.Net.Sockets;
  5. using System.Text;
  6. using System.Threading;
  7. using System.Collections;
  8. using System.Collections.Generic;
  9. using System.Collections.Specialized;
  10. using System.Reflection;
  11. using System.Linq;
  12. using System.Text.RegularExpressions;
  13. namespace System.Net.ApiService {
  14. public class RequestHeader {
  15. public enum eMethod : byte {
  16. Get,
  17. Post,
  18. Delete,
  19. Put,
  20. Patch,
  21. Trace,
  22. Options,
  23. Connect
  24. }
  25. public enum eConnection : byte {
  26. Close,
  27. KeepAlive
  28. }
  29. public enum eEncoder : byte {
  30. none = 0,
  31. deflate = 1,
  32. gzip = 2,
  33. compress = 4,
  34. identity = 8,
  35. br = 16
  36. }
  37. protected string _Path;
  38. protected NameValueCollection _Query;
  39. protected NameValueCollection _Post;
  40. protected HttpMethod _Method;
  41. protected string _UserAgent;
  42. protected int _UpgradeInsecureRequests;
  43. protected string _Pragma;
  44. protected string _Host;
  45. protected bool _DNT;
  46. protected eConnection _Connection;
  47. protected string _CacheControl;
  48. protected string _AcceptLanguage;
  49. protected eEncoder _AcceptEncoding;
  50. protected string _Accept;
  51. protected string _blankRequest;
  52. protected string _referer;
  53. protected int _contentLength = 0;
  54. protected string _contentType;
  55. protected string _boundary = "";
  56. protected List<RequestBoundary> Boundaries = new List<RequestBoundary>();
  57. public string Request(string variable) {
  58. if (this._Query.AllKeys.Contains(variable))
  59. return this._Query[variable];
  60. if (this._Post != null && this._Post.AllKeys.Contains(variable))
  61. return this._Post[variable];
  62. return "";
  63. }
  64. public string Request(string variable, string defaultValue) {
  65. if (this._Query.AllKeys.Contains(variable))
  66. return this._Query[variable];
  67. if (this._Post !=null && this._Post.AllKeys.Contains(variable))
  68. return this._Post[variable];
  69. return default;
  70. }
  71. public string Path {
  72. get {
  73. return this._Path;
  74. }
  75. }
  76. public string Blank {
  77. get {
  78. return this._blankRequest;
  79. }
  80. }
  81. public NameValueCollection Query {
  82. get {
  83. return this._Query;
  84. }
  85. }
  86. public string QueryString {
  87. get {
  88. string s = "";
  89. foreach (KeyValuePair<string, string> k in this._Query)
  90. s += (s!=""?"&":"") + k.Key + "=" + k.Value;
  91. return s;
  92. }
  93. }
  94. public NameValueCollection Post {
  95. get {
  96. return this._Post;
  97. }
  98. }
  99. public int ContentLength {
  100. get => this._contentLength;
  101. }
  102. public string ContentType {
  103. get => this._contentType;
  104. }
  105. public string Boundary {
  106. get => this._boundary;
  107. }
  108. public string PostString {
  109. get {
  110. string s = "";
  111. foreach (KeyValuePair<string, string> k in this._Post)
  112. s += (s != "" ? "&" : "") + k.Key + "=" + k.Value;
  113. return s;
  114. }
  115. }
  116. public HttpMethod Method {
  117. get {
  118. return this._Method;
  119. }
  120. }
  121. public string UserAgent {
  122. get {
  123. return this._UserAgent;
  124. }
  125. }
  126. public int UpgradeInsecureRequests {
  127. get {
  128. return this._UpgradeInsecureRequests;
  129. }
  130. }
  131. public string Pragma {
  132. get {
  133. return this._Pragma;
  134. }
  135. }
  136. public string Host {
  137. get {
  138. return this._Host;
  139. }
  140. }
  141. public string CacheControl {
  142. get {
  143. return this._CacheControl;
  144. }
  145. }
  146. public string Referer {
  147. get {
  148. return this._referer;
  149. }
  150. }
  151. public bool DNT {
  152. get {
  153. return this._DNT;
  154. }
  155. }
  156. public eConnection Connection {
  157. get {
  158. return this._Connection;
  159. }
  160. }
  161. public string AcceptLanguage {
  162. get {
  163. return this._AcceptLanguage;
  164. }
  165. }
  166. public eEncoder AcceptEncoding {
  167. get {
  168. return this._AcceptEncoding;
  169. }
  170. }
  171. public string Accept {
  172. get {
  173. return this._Accept;
  174. }
  175. }
  176. public void SetPostData(string content) {
  177. string[] qis = content.Split('&');
  178. foreach (string qi in qis) {
  179. if (qi.Contains("=")) {
  180. string variable = System.Web.HttpUtility.UrlDecode(qi.Substring(0, qi.IndexOf("=")));
  181. string value = System.Web.HttpUtility.UrlDecode(qi.Substring(qi.IndexOf("=") + 1));
  182. if (variable != "") {
  183. this.Post.Add(variable, value);
  184. }
  185. }
  186. }
  187. }
  188. public void SetPostData(NameValueCollection content) {
  189. foreach (string qi in content.AllKeys) {
  190. this._Post[qi] = content[qi];
  191. }
  192. }
  193. public RequestHeader() {
  194. }
  195. public override string ToString() {
  196. string res = "";
  197. switch (this._Method) {
  198. case HttpMethod.GET:
  199. res = "GET " + this._Path + (this._Query.Count > 0 ? "?" + this.QueryString : "") + " HTTP/1.1\r\n";
  200. break;
  201. case HttpMethod.POST:
  202. res = "POST " + this._Path + (this._Query.Count > 0 ? "?" + this.QueryString : "") + " HTTP/1.1\r\n";
  203. break;
  204. case HttpMethod.PUT:
  205. res = "PUT " + this._Path + (this._Query.Count > 0 ? "?" + this.QueryString : "") + " HTTP/1.1\r\n";
  206. break;
  207. case HttpMethod.DELETE:
  208. res = "GET " + this._Path + (this._Query.Count > 0 ? "?" + this.QueryString : "") + " HTTP/1.1\r\n";
  209. break;
  210. }
  211. res += "Host: " + this._Host + "\r\n";
  212. if(this._UserAgent.Length > 0)
  213. res += "UserAgent: " + this._UserAgent + "\r\n";
  214. if (this._Pragma.Length > 0)
  215. res += "Pragma: " + this._Pragma + "\r\n";
  216. if (this._DNT)
  217. res += "DNT: 1\r\n";
  218. if (this._referer.Length>0)
  219. res += "Referer: "+this._referer+"\r\n";
  220. if (this._Accept.Length > 0)
  221. res += "Accept: " + this._Accept + "\r\n";
  222. if (this._AcceptEncoding != eEncoder.none) {
  223. string enc = "";
  224. if ((this._AcceptEncoding | eEncoder.br) == this._AcceptEncoding)
  225. enc += (enc == "" ? "" : "; ") + "br";
  226. res += "Accept: " + enc + "\r\n";
  227. }
  228. return res;
  229. }
  230. public RequestHeader(string buffer) {
  231. //TODO: Request Header - requested path must cut down ../ at the beginning!
  232. System.Diagnostics.Debug.WriteLine("RequestHeader()");
  233. this._blankRequest = buffer;
  234. string[] lines = buffer.Split('\n');
  235. if (lines.Length > 1) {
  236. string[] firstLine = lines[0].Trim().Split(' ');
  237. if (firstLine.Length == 3) {
  238. switch (firstLine[0].ToLower()) {
  239. case "get":
  240. this._Method = HttpMethod.GET;
  241. break;
  242. case "post":
  243. this._Method = HttpMethod.POST;
  244. break;
  245. case "put":
  246. this._Method = HttpMethod.PUT;
  247. break;
  248. case "delete":
  249. this._Method = HttpMethod.DELETE;
  250. break;
  251. case "patch":
  252. this._Method = HttpMethod.PATCH;
  253. break;
  254. case "trace":
  255. this._Method = HttpMethod.TRACE;
  256. break;
  257. case "options":
  258. this._Method = HttpMethod.OPTIONS;
  259. break;
  260. case "connect":
  261. this._Method = HttpMethod.CONNECT;
  262. break;
  263. default:
  264. // invalid header
  265. System.Diagnostics.Debug.WriteLine("Invalid header - Method '" + firstLine[0] + "' not allowed");
  266. break;
  267. }
  268. this._Path = firstLine[1].Split('?')[0];
  269. this._Query = new NameValueCollection();
  270. if (firstLine[1].Contains('?')) {
  271. string q = firstLine[1].Split('?')[1];
  272. string[] qis = q.Split('&');
  273. foreach (string qi in qis) {
  274. if (qi.Contains("=")) {
  275. string variable = System.Web.HttpUtility.UrlDecode(qi.Substring(0, qi.IndexOf("=")));
  276. string value = System.Web.HttpUtility.UrlDecode(qi.Substring(qi.IndexOf("=") + 1));
  277. if (variable != "") {
  278. //System.Diagnostics.Debug.WriteLine("Query String: '" + variable + "' = '" + value + "'");
  279. this.Query.Add(variable, value);
  280. }
  281. }
  282. }
  283. }
  284. for (int i = 1, c = lines.Length; i < c; i++) {
  285. if (lines[i].Trim() != "" && lines[i].Contains(":")) {
  286. string variable = lines[i].Substring(0, lines[i].IndexOf(":")).Trim().ToLower();
  287. string value = lines[i].Substring(lines[i].IndexOf(":") + 1).Trim();
  288. System.Diagnostics.Debug.WriteLine("- '" + variable + "': '" + value + "'");
  289. if (variable != "") {
  290. switch (variable) {
  291. case "user-agent":
  292. this._UserAgent = value;
  293. break;
  294. case "upgrade-insecure-requests":
  295. int.TryParse(value, out this._UpgradeInsecureRequests);
  296. break;
  297. case "pragma":
  298. this._Pragma = value;
  299. break;
  300. case "host":
  301. this._Host = value;
  302. break;
  303. case "dnt":
  304. int xDoNotTrack = 0;
  305. int.TryParse(value, out xDoNotTrack);
  306. this._DNT = (xDoNotTrack == 1);
  307. break;
  308. case "connection":
  309. if (value.ToLower() == "keep-alive") {
  310. this._Connection = eConnection.KeepAlive;
  311. } else {
  312. this._Connection = eConnection.Close;
  313. }
  314. break;
  315. case "cache-control":
  316. this._CacheControl = value;
  317. break;
  318. case "accept-language":
  319. this._AcceptLanguage = value;
  320. break;
  321. case "content-length":
  322. int.TryParse(value, out this._contentLength);
  323. break;
  324. case "content-type":
  325. string[] ct = value.Split(';');
  326. this._contentType = ct[0];
  327. if(ct.Length>1) {
  328. ct[1] = ct[1].Trim();
  329. if(ct[1].StartsWith("boundary=")) {
  330. string boundary = ct[1].Substring(9);
  331. if (boundary.StartsWith("\"") && boundary.EndsWith("\""))
  332. boundary = boundary.Substring(1, boundary.Length - 2);
  333. this._boundary = boundary;
  334. }
  335. }
  336. break;
  337. case "accept-encoding":
  338. string[] encodings = value.Split(',');
  339. foreach (string enc in encodings) {
  340. if (enc.Trim() == "gzip")
  341. this._AcceptEncoding |= eEncoder.gzip;
  342. if (enc.Trim() == "deflate")
  343. this._AcceptEncoding |= eEncoder.deflate;
  344. if (enc.Trim() == "br")
  345. this._AcceptEncoding |= eEncoder.br;
  346. if (enc.Trim() == "compress")
  347. this._AcceptEncoding |= eEncoder.compress;
  348. if (enc.Trim() == "identity")
  349. this._AcceptEncoding |= eEncoder.identity;
  350. }
  351. break;
  352. case "accept":
  353. this._Accept = value;
  354. break;
  355. case "referer":
  356. this._referer = value;
  357. break;
  358. default:
  359. System.Diagnostics.Debug.WriteLine("Header field unknown: " + variable + ": " + value);
  360. break;
  361. }
  362. }
  363. }
  364. }
  365. } else {
  366. // Invalid header
  367. System.Diagnostics.Debug.WriteLine("Invalid header - First line has " + firstLine.Length + " parts");
  368. }
  369. } else {
  370. // invalid header
  371. System.Diagnostics.Debug.WriteLine("Invalid header - There are only " + lines.Length + " lines");
  372. }
  373. }
  374. }
  375. }