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