1: using System;
2: using System.IO;
3: using System.Net;
4: using System.Text;
5: using System.Threading.Tasks;
6: using System.Net.Http;
7: using System.Net.Http.Headers;
8: using System.Net.Http.Json;
9: using Newtonsoft.Json;
10:
11: namespace Ia.Cl.Model
12: {
13: ////////////////////////////////////////////////////////////////////////////
14:
15: /// <summary publish="true">
16: /// Contains functions that relate to posting and receiving data from remote Internet/Intranet pages
17: /// </summary>
18: /// <remarks>
19: /// Copyright � 2001-2020 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
20: ///
21: /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
22: /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
23: ///
24: /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25: /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
26: ///
27: /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
28: ///
29: /// Copyright notice: This notice may not be removed or altered from any source distribution.
30: /// </remarks>
31: public class Http
32: {
33: ////////////////////////////////////////////////////////////////////////////
34:
35: /// <summary>
36: ///
37: /// </summary>
38: private static bool range = false;
39:
40: ////////////////////////////////////////////////////////////////////////////
41:
42: /// <summary>
43: ///
44: /// </summary>
45: public Http() { }
46:
47: // Note that "https://" and "http://" are different. Wrong protocol could produce a "(403) Forbidden" response.
48:
49: // Include custom cookies, start and end points, and posting of data to remove server.
50:
51: // See https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client
52:
53: // Remember to "synch all the way"
54:
55: ////////////////////////////////////////////////////////////////////////////
56:
57: /// <summary>
58: ///
59: /// </summary>
60: public static async Task<string> PostAsync<T>(string baseAddress, string serviceUrl, T t)
61: {
62: HttpResponseMessage httpResponseMessage;
63: var s = string.Empty;
64:
65: serviceUrl = SuffixUrlWithSlashIfItContainsDot(serviceUrl);
66:
67: using (var httpClient = new HttpClient())
68: {
69: httpClient.BaseAddress = new Uri(baseAddress);
70: httpClient.DefaultRequestHeaders.Accept.Clear();
71: httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
72:
73: HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(t), Encoding.UTF8, "application/json");
74:
75: httpResponseMessage = await httpClient.PostAsJsonAsync(serviceUrl, httpContent);
76: // e.g. httpResponseMessage = await httpClient.PostAsJsonAsync("api/products", product);
77:
78: httpResponseMessage.EnsureSuccessStatusCode();
79:
80: s = await httpResponseMessage.Content.ReadAsStringAsync();
81: }
82:
83: return s;
84: }
85:
86: ////////////////////////////////////////////////////////////////////////////
87:
88: /// <summary>
89: ///
90: /// </summary>
91: public static async Task<string> PostAsync(string baseAddress, string serviceUrl)
92: {
93: HttpResponseMessage httpResponseMessage;
94: var s = string.Empty;
95:
96: serviceUrl = SuffixUrlWithSlashIfItContainsDot(serviceUrl);
97:
98: using (var httpClient = new HttpClient())
99: {
100: httpClient.BaseAddress = new Uri(baseAddress);
101: httpClient.DefaultRequestHeaders.Accept.Clear();
102: httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
103:
104: HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(string.Empty), Encoding.UTF8, "application/json"); // dummy
105:
106: httpResponseMessage = await httpClient.PostAsJsonAsync(serviceUrl, httpContent);
107: // e.g. httpResponseMessage = await httpClient.PostAsJsonAsync("api/products", product);
108:
109: httpResponseMessage.EnsureSuccessStatusCode();
110:
111: s = await httpResponseMessage.Content.ReadAsStringAsync();
112: }
113:
114: return s;
115: }
116:
117: /*
118: ////////////////////////////////////////////////////////////////////////////
119:
120: /// <summary>
121: ///
122: /// </summary>
123: public static async Task<T> GetAsync<T>(string baseAddress, string serviceUrl)
124: {
125: HttpResponseMessage httpResponseMessage;
126: T t;
127:
128: t = default;
129:
130: serviceUrl = SuffixUrlWithSlashIfItContainsDot(serviceUrl);
131:
132: using (var httpClient = new HttpClient())
133: {
134: httpClient.BaseAddress = new Uri(baseAddress);
135: httpClient.DefaultRequestHeaders.Accept.Clear();
136: httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
137:
138: httpResponseMessage = await httpClient.GetAsync(serviceUrl);
139:
140: if (httpResponseMessage.IsSuccessStatusCode)
141: {
142: t = await httpResponseMessage.Content.ReadAsAsync<T>();
143: }
144: else
145: {
146:
147: }
148: }
149:
150: return t;
151: }
152: */
153:
154: ////////////////////////////////////////////////////////////////////////////
155:
156: /// <summary>
157: ///
158: /// </summary>
159: public static async Task<string> GetAsync(string baseAddress, string serviceUrl)
160: {
161: HttpResponseMessage httpResponseMessage;
162: var s = string.Empty;
163:
164: serviceUrl = SuffixUrlWithSlashIfItContainsDot(serviceUrl);
165:
166: using (var httpClient = new HttpClient())
167: {
168: httpClient.BaseAddress = new Uri(baseAddress);
169: httpClient.DefaultRequestHeaders.Accept.Clear();
170: httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
171:
172: httpResponseMessage = await httpClient.GetAsync(serviceUrl);
173:
174: httpResponseMessage.EnsureSuccessStatusCode();
175:
176: s = await httpResponseMessage.Content.ReadAsStringAsync();
177: }
178:
179: return s;
180: }
181:
182: ////////////////////////////////////////////////////////////////////////////
183:
184: /// <summary>
185: ///
186: /// </summary>
187: public static async Task<string> PutAsync<T>(string baseAddress, string serviceUrl, T t)
188: {
189: HttpResponseMessage httpResponseMessage;
190: var s = string.Empty;
191:
192: serviceUrl = SuffixUrlWithSlashIfItContainsDot(serviceUrl);
193:
194: using (var httpClient = new HttpClient())
195: {
196: httpClient.BaseAddress = new Uri(baseAddress);
197: httpClient.DefaultRequestHeaders.Accept.Clear();
198: httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
199:
200: HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(t), Encoding.UTF8, "application/json");
201:
202: httpResponseMessage = await httpClient.PutAsJsonAsync(serviceUrl, httpContent);
203: // e.g. httpResponseMessage = await httpClient.PutAsJsonAsync($"api/products/{product.Id}", product);
204:
205: httpResponseMessage.EnsureSuccessStatusCode();
206:
207: s = await httpResponseMessage.Content.ReadAsStringAsync();
208: }
209:
210: return s;
211: }
212:
213: ////////////////////////////////////////////////////////////////////////////
214:
215: /// <summary>
216: ///
217: /// </summary>
218: public static async Task<string> PutAsync(string baseAddress, string serviceUrl)
219: {
220: HttpResponseMessage httpResponseMessage;
221: var s = string.Empty;
222:
223: serviceUrl = SuffixUrlWithSlashIfItContainsDot(serviceUrl);
224:
225: using (var httpClient = new HttpClient())
226: {
227: httpClient.BaseAddress = new Uri(baseAddress);
228: httpClient.DefaultRequestHeaders.Accept.Clear();
229: httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
230:
231: HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(string.Empty), Encoding.UTF8, "application/json"); // dummy
232:
233: httpResponseMessage = await httpClient.PutAsJsonAsync(serviceUrl, httpContent);
234: // e.g. httpResponseMessage = await httpClient.PutAsJsonAsync($"api/products/{product.Id}", product);
235:
236: httpResponseMessage.EnsureSuccessStatusCode();
237:
238: s = await httpResponseMessage.Content.ReadAsStringAsync();
239: }
240:
241: return s;
242: }
243:
244: ////////////////////////////////////////////////////////////////////////////
245:
246: /// <summary>
247: ///
248: /// </summary>
249: public static async Task<string> DeleteAsync(string baseAddress, string serviceUrl)
250: {
251: HttpResponseMessage httpResponseMessage;
252: var s = string.Empty;
253:
254: serviceUrl = SuffixUrlWithSlashIfItContainsDot(serviceUrl);
255:
256: using (var httpClient = new HttpClient())
257: {
258: httpClient.BaseAddress = new Uri(baseAddress);
259: httpClient.DefaultRequestHeaders.Accept.Clear();
260: httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
261:
262: httpResponseMessage = await httpClient.DeleteAsync(serviceUrl);
263: // e.g. httpResponseMessage = await client.DeleteAsync($"api/products/{id}");
264:
265: httpResponseMessage.EnsureSuccessStatusCode();
266:
267: s = await httpResponseMessage.Content.ReadAsStringAsync();
268: }
269:
270: return s;
271: }
272:
273: ////////////////////////////////////////////////////////////////////////////
274:
275: /// <summary>
276: ///
277: /// </summary>
278: private static string SuffixUrlWithSlashIfItContainsDot(string url)
279: {
280: // - Suffix the URL with a slash e.g. http://somedomain.com/api/people/staff.33311/ instead of http://somedomain.com/api/people/staff.33311 to pass a dot '.'
281:
282: if (!string.IsNullOrEmpty(url))
283: {
284: if (url.Contains(".")) url += "/";
285: }
286:
287: return url;
288: }
289:
290: ////////////////////////////////////////////////////////////////////////////
291: ////////////////////////////////////////////////////////////////////////////
292:
293:
294:
295: ////////////////////////////////////////////////////////////////////////////
296: ////////////////////////////////////////////////////////////////////////////
297:
298: /// <summary>
299: ///
300: /// </summary>
301: public static string Request(string url)
302: {
303: range = false;
304:
305: return ProcessRequest(url, 0, false, null, null);
306: }
307:
308: ////////////////////////////////////////////////////////////////////////////
309:
310: /// <summary>
311: ///
312: /// </summary>
313: public static string Request(string url, int start)
314: {
315: range = true;
316:
317: return ProcessRequest(url, start, false, null, null);
318: }
319:
320: ////////////////////////////////////////////////////////////////////////////
321:
322: /// <summary>
323: ///
324: /// </summary>
325: public static string Request2(string url)
326: {
327: range = true;
328:
329: return ProcessRequest2(url, false);
330: }
331:
332: ////////////////////////////////////////////////////////////////////////////
333:
334: /// <summary>
335: ///
336: /// </summary>
337: public static string Request_Utf8(string url, int start)
338: {
339: range = true;
340:
341: return ProcessRequest(url, start, true, null, null);
342: }
343:
344: ////////////////////////////////////////////////////////////////////////////
345:
346: /// <summary>
347: ///
348: /// </summary>
349: public static string Request(string url, int start, System.Net.Cookie c)
350: {
351: range = true;
352:
353: return ProcessRequest(url, start, false, c, null);
354: }
355:
356: ////////////////////////////////////////////////////////////////////////////
357:
358: /// <summary>
359: ///
360: /// </summary>
361: public static string Request(string url, int start, System.Net.Cookie c1, System.Net.Cookie c2)
362: {
363: range = true;
364:
365: return ProcessRequest(url, start, false, c1, c2);
366: }
367:
368: ////////////////////////////////////////////////////////////////////////////
369:
370: /// <summary>
371: ///
372: /// </summary>
373: public static string Post(string URI, string Parameters)
374: {
375: // for a "Request format is unrecognized" problem see: http://support.microsoft.com/default.aspx?scid=kb;en-us;819267
376:
377: System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
378: //req.Proxy = new System.Net.WebProxy(ProxyString, true);
379:
380: req.ContentType = "application/x-www-form-urlencoded";
381: req.Method = "POST";
382: //req.Timeout = 3000;
383:
384: byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
385: req.ContentLength = bytes.Length;
386:
387: using (System.IO.Stream os = req.GetRequestStream())
388: {
389: os.Write(bytes, 0, bytes.Length);
390: //os.Close();
391: }
392:
393: System.Net.WebResponse resp = null;
394:
395: try
396: {
397: resp = req.GetResponse();
398:
399: if (resp == null) return null;
400:
401: System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream(), Encoding.GetEncoding(1256));
402: return sr.ReadToEnd().Trim();
403: }
404: catch (WebException ex)
405: {
406: string str = ex.Message;
407: }
408:
409: return null;
410: }
411:
412: ////////////////////////////////////////////////////////////////////////////
413:
414: /// <summary>
415: ///
416: /// </summary>
417: public static string Post(string URI, string Parameters, int code_page)
418: {
419: // for a "Request format is unrecognized" problem see: http://support.microsoft.com/default.aspx?scid=kb;en-us;819267
420:
421: // Sometimes you need to POST in Windows 1256 code page for the process to run
422:
423: System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
424: //req.Proxy = new System.Net.WebProxy(ProxyString, true);
425:
426: req.ContentType = "application/x-www-form-urlencoded";
427: req.Method = "POST";
428: //req.Timeout = 3000;
429:
430: byte[] bytes = System.Text.Encoding.GetEncoding(code_page).GetBytes(Parameters);
431: req.ContentLength = bytes.Length;
432:
433: using (System.IO.Stream os = req.GetRequestStream())
434: {
435: os.Write(bytes, 0, bytes.Length);
436: //os.Close();
437: }
438:
439: System.Net.WebResponse resp = null;
440:
441: try
442: {
443: resp = req.GetResponse();
444:
445: if (resp == null) return null;
446:
447: System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream(), Encoding.GetEncoding(code_page));
448: return sr.ReadToEnd().Trim();
449: }
450: catch (WebException ex)
451: {
452: string str = ex.Message;
453: }
454:
455: return null;
456: }
457:
458: ////////////////////////////////////////////////////////////////////////////
459:
460: /// <summary>
461: ///
462: /// </summary>
463: private static string ProcessRequest(string url, int start, bool utf8, System.Net.Cookie c1, System.Net.Cookie c2)
464: {
465: string text = "";
466:
467: try
468: {
469: Uri ourUri = new Uri(url);
470: // Creates an HttpWebRequest for the specified URL.
471: HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(ourUri);
472:
473: // this code below is very important. It sends a request with a specific cookie in the collection
474: // to demonstrate to the remote server that we have his cookie and we should skip his advertisement.
475: if (c1 != null || c2 != null)
476: {
477: myHttpWebRequest.CookieContainer = new CookieContainer();
478: if (c1 != null) myHttpWebRequest.CookieContainer.Add(c1);
479: if (c2 != null) myHttpWebRequest.CookieContainer.Add(c2);
480: }
481:
482: myHttpWebRequest.Method = "POST";
483: //myHttpWebRequest.Timeout = 5000; // 5 sec
484: //myHttpWebRequest.MaximumResponseHeadersLength = 100; // *1024 (Kilobytes)
485:
486: // set the range of data to be returned if the start and end positions are given
487: if (range) myHttpWebRequest.AddRange(start);
488:
489: myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
490: myHttpWebRequest.ContentLength = 0;
491:
492: HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
493:
494: if (myHttpWebRequest.HaveResponse)
495: {
496: Stream receiveStream = myHttpWebResponse.GetResponseStream();
497: Encoding encode;
498:
499: if (utf8) encode = System.Text.Encoding.GetEncoding("utf-8");
500: else encode = System.Text.Encoding.GetEncoding(1252); // 1252 best for western char
501:
502: // Pipes the stream to a higher level stream reader with the required encoding format.
503: using (StreamReader readStream = new StreamReader(receiveStream, encode))
504: {
505: text = readStream.ReadToEnd().Trim(); // ONE
506:
507: /*
508: // TWO
509: Char[] read = new Char[256];
510: // Reads 256 characters at a time.
511: int count = readStream.Read( read, 0, 256 );
512:
513: while (count > 0)
514: {
515: // Dumps the 256 characters on a string and displays the string to the console.
516: String str = new String(read, 0, count);
517: text += str;
518: count = readStream.Read(read, 0, 256);
519: }
520: */
521:
522: // Releases the resources of the response.
523: //myHttpWebResponse.Close();
524: }
525: }
526: else
527: {
528: text = "\nResponse not received from server";
529: }
530: }
531: catch (WebException e)
532: {
533: HttpWebResponse response = (HttpWebResponse)e.Response;
534: if (response != null)
535: {
536: if (response.StatusCode == HttpStatusCode.Unauthorized)
537: {
538: string challenge = null;
539: challenge = response.GetResponseHeader("WWW-Authenticate");
540: if (challenge != null) text = "\nThe following challenge was raised by the server: " + challenge;
541: }
542: else text = "\nThe following WebException was raised : " + e.Message;
543: }
544: else text = "\nResponse Received from server was null";
545: }
546: catch (Exception e)
547: {
548: text = "\nThe following Exception was raised : " + e.Message;
549: }
550:
551: return text;
552: }
553:
554: ////////////////////////////////////////////////////////////////////////////
555:
556: /// <summary>
557: ///
558: /// </summary>
559: private static string ProcessRequest2(string url, bool utf8)
560: {
561: string text = "";
562:
563: try
564: {
565: Uri ourUri = new Uri(url);
566: // Creates an HttpWebRequest for the specified URL.
567: HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(ourUri);
568:
569: //myHttpWebRequest.Method = "POST";
570: //myHttpWebRequest.Timeout = 5000; // 5 sec
571: //myHttpWebRequest.MaximumResponseHeadersLength = 100; // *1024 (Kilobytes)
572:
573: // set the range of data to be returned if the start and end positions are given
574: //if (range) myHttpWebRequest.AddRange(start);
575:
576: myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
577: myHttpWebRequest.ContentLength = 0;
578:
579: HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
580:
581: if (myHttpWebRequest.HaveResponse)
582: {
583: Stream receiveStream = myHttpWebResponse.GetResponseStream();
584: Encoding encode;
585:
586: if (utf8) encode = System.Text.Encoding.GetEncoding("utf-8");
587: else encode = System.Text.Encoding.GetEncoding(1252); // 1252 best for western char
588:
589: // Pipes the stream to a higher level stream reader with the required encoding format.
590: using (StreamReader readStream = new StreamReader(receiveStream, encode))
591: {
592: text = readStream.ReadToEnd().Trim(); // ONE
593:
594: /*
595: // TWO
596: Char[] read = new Char[256];
597: // Reads 256 characters at a time.
598: int count = readStream.Read( read, 0, 256 );
599:
600: while (count > 0)
601: {
602: // Dumps the 256 characters on a string and displays the string to the console.
603: String str = new String(read, 0, count);
604: text += str;
605: count = readStream.Read(read, 0, 256);
606: }
607: */
608:
609: // Releases the resources of the response.
610: //myHttpWebResponse.Close();
611: }
612: }
613: else
614: {
615: text = "\nResponse not received from server";
616: }
617: }
618: catch (WebException e)
619: {
620: HttpWebResponse response = (HttpWebResponse)e.Response;
621: if (response != null)
622: {
623: if (response.StatusCode == HttpStatusCode.Unauthorized)
624: {
625: string challenge = null;
626: challenge = response.GetResponseHeader("WWW-Authenticate");
627: if (challenge != null) text = "\nThe following challenge was raised by the server: " + challenge;
628: }
629: else text = "\nThe following WebException was raised : " + e.Message;
630: }
631: else text = "\nResponse Received from server was null";
632: }
633: catch (Exception e)
634: {
635: text = "\nThe following Exception was raised : " + e.Message;
636: }
637:
638: return text;
639: }
640:
641: ////////////////////////////////////////////////////////////////////////////
642:
643: /// <summary>
644: ///
645: /// </summary>
646: private static int Get(string url, out string text, out string result)
647: {
648: int op;
649:
650: op = 0;
651: result = "";
652: text = "";
653:
654: try
655: {
656: Uri ourUri = new Uri(url);
657: // Creates an HttpWebRequest for the specified URL.
658: HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(ourUri);
659: HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
660:
661: Stream receiveStream = myHttpWebResponse.GetResponseStream();
662: Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
663:
664: // Pipes the stream to a higher level stream reader with the required encoding format.
665: using (StreamReader readStream = new StreamReader(receiveStream, encode))
666: {
667: Char[] read = new Char[256];
668: // Reads 256 characters at a time.
669: int count = readStream.Read(read, 0, 256);
670:
671: while (count > 0)
672: {
673: // Dumps the 256 characters on a string and displays the string to the console.
674: String str = new String(read, 0, count);
675: text += str;
676: count = readStream.Read(read, 0, 256);
677: }
678:
679: // Releases the resources of the response.
680: //myHttpWebResponse.Close();
681: }
682:
683: op = 1;
684: }
685: catch (WebException e)
686: {
687: HttpWebResponse response = (HttpWebResponse)e.Response;
688: if (response != null)
689: {
690: if (response.StatusCode == HttpStatusCode.Unauthorized)
691: {
692: string challenge = null;
693: challenge = response.GetResponseHeader("WWW-Authenticate");
694: if (challenge != null) result = "The following challenge was raised by the server: " + challenge;
695: }
696: else result = "The following WebException was raised : " + e.Message;
697: }
698: else result = "Response Received from server was null";
699:
700: op = -1;
701: }
702: catch (Exception e)
703: {
704: result = "The following Exception was raised : " + e.Message;
705: op = -1;
706: }
707:
708: return op;
709: }
710:
711: ////////////////////////////////////////////////////////////////////////////
712: ////////////////////////////////////////////////////////////////////////////
713: }
714: }