3535f049f50225d98f808e41f9dd2c498f05f675
[GitHub/Stricted/SpeedportHybridControl.git] / SpeedportHybridControl / Data / SpeedportHybridAPI.cs
1 using Newtonsoft.Json.Linq;
2 using System;
3 using System.Linq;
4 using System.IO;
5 using System.Net;
6 using System.Text;
7 using System.Text.RegularExpressions;
8 using System.Windows;
9 using System.Threading;
10 using System.Collections.Generic;
11 using SpeedportHybridControl.Implementations;
12 using SpeedportHybridControl.Model;
13 using Newtonsoft.Json;
14 using SpeedportHybridControl.PageModel;
15
16 namespace SpeedportHybridControl.Data {
17 public class SpeedportHybridAPI : SingletonFactory<SpeedportHybridAPI> {
18 public string _ip = "speedport.ip";
19 private DateTime _lastReboot = DateTime.MinValue;
20 private bool _checkIsActive = false;
21 public string _password;
22 public string _challenge;
23 public string _hash;
24 public string _derivedk;
25 public CookieContainer _cookie = new CookieContainer();
26
27 public string ip {
28 get { return _ip; }
29 set { _ip = value; }
30 }
31
32 /**
33 * Requests the password-challenge from the router.
34 *
35 * @return string
36 */
37 public string getChallenge () {
38 string response = sendRequest("data/Login.json", "csrf_token=nulltoken&showpw=0&challengev=null");
39 if (response.IsNullOrEmpty())
40 return string.Empty;
41
42 string challenge = string.Empty;
43 try {
44 JToken jArray = JToken.Parse(response);
45
46 challenge = jArray.getVar("challengev");
47 jArray = null;
48 }
49 catch (Exception ex) {
50 LogManager.WriteToLog(ex.Message);
51 }
52
53 response = null;
54
55 return challenge;
56 }
57
58 /**
59 * calculate the derivedk
60 *
61 * @param string $password
62 * @return string
63 */
64 public string getDerviedk () {
65 return _password.sha256().pbkdf2(_challenge.Substring(0, 16));
66 }
67
68 /**
69 * login into the router with the given password
70 *
71 * @param string $password
72 * @return bool
73 */
74 public bool login (string password) {
75 if (password.IsNullOrEmpty()) {
76 return false;
77 }
78
79 _cookie = new CookieContainer();
80
81 _password = password;
82 _challenge = getChallenge();
83 _hash = string.Concat(_challenge, ":", password).sha256();
84
85 string response = sendRequest("data/Login.json", string.Concat("csrf_token=nulltoken&showpw=0&password=", _hash));
86 if (response.IsNullOrEmpty())
87 return false;
88
89 _cookie.Add(new Cookie("challengev", _challenge) { Domain = "speedport.ip" });
90
91 bool login = false;
92 try {
93 JToken jArray = JToken.Parse(response);
94 if (jArray.getVar("login").Equals("success")) {
95 if (isLoggedin().Equals(false)) {
96 login = false;
97 }
98 else {
99 login = true;
100 _derivedk = getDerviedk();
101 _lastReboot = getLastReboot();
102 }
103 }
104 jArray = null;
105 }
106 catch (Exception ex) {
107 LogManager.WriteToLog(ex.Message);
108 }
109
110 response = null;
111
112 return login;
113 }
114
115 /**
116 * logout
117 *
118 * @return bool
119 */
120 public bool logout () {
121 string response = sendRequest("data/Login.json", string.Concat("csrf_token=", getToken(), "&logout=byby"));
122 if (response.IsNullOrEmpty())
123 return false;
124
125 bool logout = false;
126 try {
127 JToken jArray = JToken.Parse(response);
128 if (jArray.getVar("status").Equals("ok")) {
129 if (isLoggedin().Equals(true)) {
130 logout = false;
131 }
132 else {
133 logout = true;
134 _password = "";
135 _challenge = "";
136 _cookie = new CookieContainer();
137 _lastReboot = DateTime.MinValue;
138 _hash = "";
139 _derivedk = "";
140 }
141 }
142
143 jArray = null;
144 }
145 catch (Exception ex) {
146 LogManager.WriteToLog(ex.Message);
147 }
148
149 response = null;
150
151 return logout;
152 }
153
154 /**
155 * check if we are logged in
156 *
157 * @return bool
158 */
159 public bool checkLogin () {
160 if (_checkIsActive.Equals(false)) {
161 _checkIsActive = true;
162 if (isLoggedin().Equals(false)) {
163 Console.WriteLine("Session expired, try to relogin");
164
165 Thread.Sleep(400);
166
167 if (login(_password).Equals(false)) {
168 // should we try to relogin? login(_password);...
169 new Thread(() => { LogManager.WriteToLog("Session expired."); }).Start();
170 _password = "";
171 _challenge = "";
172 _cookie = new CookieContainer();
173 _lastReboot = DateTime.MinValue;
174 _hash = "";
175 _derivedk = "";
176
177 LoginPageModel lpm = Application.Current.FindResource("LoginPageModel") as LoginPageModel;
178 lpm.LoginCommand.Execute();
179 MainWindowModel mwm = Application.Current.FindResource("MainWindowModel") as MainWindowModel;
180 mwm.SwitchToLoginPage.Execute();
181
182 new Thread(() => { MessageBox.Show("Session expired.", "Confirmation", MessageBoxButton.OK, MessageBoxImage.Error); }).Start();
183 _checkIsActive = false;
184 return false;
185 }
186 }
187
188 _checkIsActive = false;
189 }
190 else {
191 Console.WriteLine("check allready in progress");
192 }
193
194 return true;
195 }
196
197 /**
198 * check if we are logged in
199 *
200 * @param bool ischeck
201 * @return bool
202 */
203 public bool isLoggedin () {
204 string response = sendRequest("data/SecureStatus.json");
205 if (response.IsNullOrEmpty())
206 return false;
207
208 bool login = false;
209 try {
210 JToken jArray = JToken.Parse(response);
211
212 if (jArray.getVar("loginstate").Equals("1")/* && jArray.getVar("login").Equals("true")*/) {
213 login = true;
214 }
215
216 jArray = null;
217 }
218
219 catch (Exception ex) {
220 LogManager.WriteToLog(ex.Message);
221 }
222
223 response = null;
224
225 return login;
226 }
227
228 /**
229 * reboot the router
230 */
231 public void reboot () {
232 if (checkLogin().Equals(false))
233 return;
234
235 string response = sendRequest("data/Reboot.json", string.Concat("csrf_token=", Uri.EscapeUriString(getToken()), "&reboot_device=true"));
236 if (response.IsNullOrEmpty())
237 return;
238 try {
239 JToken jArray = JToken.Parse(response);
240 if (jArray.getVar("status").Equals("ok")) {
241 new Thread(() => { MessageBox.Show("Router Reboot.", "Confirmation", MessageBoxButton.OK, MessageBoxImage.Information); }).Start();
242 LogManager.WriteToLog("Router Reboot.");
243 _password = "";
244 _challenge = "";
245 _cookie = new CookieContainer();
246 _hash = "";
247 _derivedk = "";
248
249 LoginPageModel lpm = Application.Current.FindResource("LoginPageModel") as LoginPageModel;
250 lpm.LoginCommand.Execute();
251 MainWindowModel mwm = Application.Current.FindResource("MainWindowModel") as MainWindowModel;
252 mwm.SwitchToLoginPage.Execute();
253 }
254
255 jArray = null;
256 }
257 catch (Exception ex) {
258 LogManager.WriteToLog(ex.Message);
259 }
260
261 response = null;
262 }
263
264 /**
265 * reconnect LTE
266 *
267 * @return bool
268 */
269 public bool reconnectLte () {
270 if (checkLogin().Equals(false))
271 return false;
272
273 Thread.Sleep(400);
274
275 string response = sendEnryptedRequest("data/modules.json", string.Concat("lte_reconn=1&csrf_token=", Uri.EscapeUriString(getToken())));
276 if (response.IsNullOrEmpty())
277 return false;
278
279 try {
280 JToken jArray = JToken.Parse(response);
281
282 response = null;
283
284 if (jArray.getVar("status").Equals("ok")) {
285 jArray = null;
286 return true;
287 }
288
289 jArray = null;
290 }
291 catch (Exception ex) {
292 LogManager.WriteToLog(ex.Message);
293 }
294
295 response = null;
296
297 return false;
298 }
299
300 /**
301 * reconnect DSL
302 *
303 * @return bool
304 */
305 public bool reconnectDSL () {
306 if (checkLogin().Equals(false))
307 return false;
308
309 Thread.Sleep(400);
310
311 string response = sendEnryptedRequest("data/Connect.json", string.Concat("csrf_token=", Uri.EscapeUriString(getToken()), "&showpw=0&password=", _hash, "&req_connect=offline"));
312 if (response.IsNullOrEmpty())
313 return false;
314
315 bool offline = false;
316 try {
317 JToken jArray = JToken.Parse(response);
318
319 response = null;
320
321 if (jArray.getVar("status").Equals("ok")) {
322 offline = true;
323 }
324
325 jArray = null;
326
327 if (offline.Equals(true)) {
328 response = sendEnryptedRequest("data/Connect.json", string.Concat("csrf_token=", Uri.EscapeUriString(getToken()), "&showpw=0&password=", _hash, "&req_connect=online"));
329 jArray = JToken.Parse(response);
330 if (jArray.getVar("status").Equals("ok")) {
331 jArray = null;
332 return true;
333 }
334 }
335 }
336 catch (Exception ex) {
337 LogManager.WriteToLog(ex.Message);
338 }
339
340 response = null;
341
342 return false;
343 }
344
345 /**
346 * change dsl connection status
347 *
348 * @param string status
349 * @return bool
350 */
351 public bool changeDSLStatus (string status) {
352 if (checkLogin().Equals(false))
353 return false;
354
355 if (status.Equals("online") || status.Equals("offline")) {
356
357 string response = sendEnryptedRequest("data/Connect.json", string.Concat("req_connect=", status, "&csrf_token=", Uri.EscapeUriString(getToken())));
358 if (response.IsNullOrEmpty())
359 return false;
360 try {
361 JToken jArray = JToken.Parse(response);
362
363 response = null;
364
365 if (jArray.getVar("status").Equals("ok")) {
366 jArray = null;
367 return true;
368 }
369 }
370 catch (Exception ex) {
371 LogManager.WriteToLog(ex.Message);
372 }
373
374 response = null;
375 }
376
377 return false;
378 }
379
380 /**
381 * change lte connection status
382 *
383 * @param string status
384 * @return bool
385 */
386 public bool changeLTEStatus (string status) {
387 if (checkLogin().Equals(false))
388 return false;
389
390 if (status.Equals("online") || status.Equals("offline")) {
391 if (status.Equals("online"))
392 status = "1";
393
394 if (status.Equals("offline"))
395 status = "0";
396
397 string response = sendEnryptedRequest("data/Modules.json", string.Concat("use_lte=", status, "&csrf_token=", Uri.EscapeUriString(getToken())));
398 if (response.IsNullOrEmpty())
399 return false;
400 try {
401 JToken jArray = JToken.Parse(response);
402
403 response = null;
404
405 if (jArray.getVar("status").Equals("ok")) {
406 jArray = null;
407 return true;
408 }
409 }
410 catch (Exception ex) {
411 LogManager.WriteToLog(ex.Message);
412 }
413
414 response = null;
415 }
416
417 return false;
418 }
419
420 /**
421 * reset the router to Factory Default
422 * not tested
423 *
424 * @return bool
425 */
426 public bool resetToFactoryDefault () {
427 if (checkLogin().Equals(false))
428 return false;
429
430 Thread.Sleep(400);
431
432 string response = sendEnryptedRequest("data/resetAllSetting.json", string.Concat("csrf_token=nulltoken&showpw=0&password=", _hash, "&reset_all=true"));
433 if (response.IsNullOrEmpty())
434 return false;
435
436 try {
437 JToken jArray = JToken.Parse(response);
438 if (jArray.getVar("status").Equals("ok")) {
439 return true;
440 }
441
442 jArray = null;
443 }
444 catch (Exception ex) {
445 LogManager.WriteToLog(ex.Message);
446 }
447
448 response = null;
449
450 return false;
451 }
452
453 /**
454 * check for firmware update
455 */
456 public void checkFirmware () {
457 if (checkLogin().Equals(false))
458 return;
459
460 Thread.Sleep(400);
461
462 string response = sendRequest("data/checkfirm.json");
463 if (response.IsNullOrEmpty())
464 return;
465
466 try {
467 bool fw_isActual = false;
468 JToken jArray = JToken.Parse(response);
469
470 if (jArray.getVar("fw_isActual").Equals("1")) {
471 fw_isActual = true;
472 }
473
474 if (fw_isActual.Equals(true)) {
475 // Die Firmware ist aktuell.
476 MessageBox.Show("Die Firmware ist aktuell.", "Confirmation", MessageBoxButton.OK, MessageBoxImage.Information);
477 }
478 else {
479 // Es liegt eine neuere Firmware-Version vor. Möchten Sie diese Version jetzt installieren?
480 MessageBox.Show("Es liegt eine neuere Firmware-Version vor.\nMöchten Sie diese Version jetzt installieren?", "Confirmation", MessageBoxButton.OK, MessageBoxImage.Warning);
481 }
482
483 jArray = null;
484 }
485 catch (Exception ex) {
486 LogManager.WriteToLog(ex.Message);
487 }
488
489 response = null;
490 }
491
492 /**
493 * flush dns cache
494 */
495 public void flushDNS () {
496 if (checkLogin().Equals(false))
497 return;
498
499 Thread.Sleep(400);
500
501 string response = sendEnryptedRequest("data/dns.json", "op_type=flush_dns_cache");
502 if (response.IsNullOrEmpty())
503 return;
504
505 try {
506 JToken jArray = JToken.Parse(response);
507
508 if (jArray["DCI"].Count().Equals(0)) {
509 new Thread(() => { MessageBox.Show("DNS cache geleert", "Confirmation", MessageBoxButton.OK, MessageBoxImage.Information); }).Start();
510 }
511 else {
512 new Thread(() => { MessageBox.Show("unable to flush dns cache", "Confirmation", MessageBoxButton.OK, MessageBoxImage.Error); }).Start();
513 }
514
515
516 jArray = null;
517 }
518 catch (Exception ex) {
519 LogManager.WriteToLog(ex.Message);
520 }
521
522 response = null;
523 }
524
525 /**
526 * clear the Syslog
527 */
528 public void clearSyslog () {
529 if (checkLogin().Equals(false))
530 return;
531
532 Thread.Sleep(400);
533
534 string response = sendEnryptedRequest("data/SystemMessages.json", string.Concat("action_clearlist=true&clear_type=0&", "csrf_token=", getToken()));
535 if (response.IsNullOrEmpty())
536 return;
537
538 try {
539 JToken jArray = JToken.Parse(response);
540
541 if (jArray.getVar("status").Equals("ok")) {
542 // ok
543 new Thread(() => { MessageBox.Show("Syslog geleert", "Confirmation", MessageBoxButton.OK, MessageBoxImage.Information); }).Start();
544 }
545 else {
546 // fail
547 new Thread(() => { MessageBox.Show("Konnte Syslog nicht leeren.", "Confirmation", MessageBoxButton.OK, MessageBoxImage.Error); }).Start();
548 }
549
550 jArray = null;
551 }
552 catch (Exception ex) {
553 LogManager.WriteToLog(ex.Message);
554 }
555
556 response = null;
557 }
558
559 /**
560 * set QueueSkbTimeOut
561 *
562 * @param string value
563 */
564 public void setQueueSkbTimeOut (string value) {
565 if (checkLogin().Equals(false))
566 return;
567
568 string response = sendEnryptedRequest("data/bonding_tr181.json", string.Concat("bonding_QueueSkbTimeOut=", value));
569 if (response.IsNullOrEmpty())
570 return;
571 try {
572 TR181PageModel obj = JsonConvert.DeserializeObject<TR181PageModel>(response);
573
574 if (obj.QueueSkbTimeOut.Equals(value)) {
575 new Thread(() => { MessageBox.Show("QueueSkbTimeOut geändert", "Confirmation", MessageBoxButton.OK, MessageBoxImage.Information); }).Start();
576 }
577 else {
578 new Thread(() => { MessageBox.Show("unable to change QueueSkbTimeOut", "Confirmation", MessageBoxButton.OK, MessageBoxImage.Error); }).Start();
579 }
580
581 obj = null;
582 }
583 catch (Exception ex) {
584 LogManager.WriteToLog(ex.Message);
585 }
586
587 response = null;
588 }
589
590 /**
591 * set Antenna Mode
592 *
593 * @param string value
594 */
595 public void setAntennaMode (string value) {
596 if (checkLogin().Equals(false))
597 return;
598
599 string response = sendEnryptedRequest("data/lteinfo.json", string.Concat("mode_select=", value));
600 if (response.IsNullOrEmpty())
601 return;
602 try {
603 LteInfoModel obj = JsonConvert.DeserializeObject<LteInfoModel>(response);
604
605 string antenna_mode;
606 if (obj.antenna_mode.Equals("Antennal set to internal")) {
607 antenna_mode = "Inner";
608 }
609 else if (obj.antenna_mode.Equals("Antennal set to external")) {
610 antenna_mode = "Outer";
611 }
612 else {
613 antenna_mode = "Auto";
614 }
615
616 if (antenna_mode.Equals(value)) {
617 new Thread(() => { MessageBox.Show("Antennen Modus geändert", "Confirmation", MessageBoxButton.OK, MessageBoxImage.Information); }).Start();
618 }
619 else {
620 new Thread(() => { MessageBox.Show("Antennen Modus ändern Fehlgeschlagen", "Confirmation", MessageBoxButton.OK, MessageBoxImage.Error); }).Start();
621 }
622
623 antenna_mode = null;
624
625 obj = null;
626 }
627 catch (Exception ex) {
628 LogManager.WriteToLog(ex.Message);
629 }
630
631 response = null;
632 }
633
634 /**
635 * get Last Reboot time
636 *
637 * @return DateTime
638 */
639 public DateTime getLastReboot () {
640 if (_lastReboot.Equals(DateTime.MinValue).Equals(false)) {
641 return _lastReboot;
642 }
643
644 string response = sendRequest("data/Reboot.json");
645
646 if (response.IsNullOrEmpty())
647 return DateTime.Now;
648
649 JToken jArray = JToken.Parse(response);
650
651 DateTime lastReboot = DateTime.Parse(string.Concat(jArray.getVar("reboot_date"), " ", jArray.getVar("reboot_time")));
652
653 jArray = null;
654
655 return lastReboot;
656 }
657
658 /**
659 * get the csrf token from router
660 *
661 * @return string
662 */
663 public string getToken () {
664 string response = sendRequest("html/content/overview/index.html");
665 if (response.IsNullOrEmpty())
666 return string.Empty;
667
668 string a = "csrf_token = \"";
669 string b = "\";";
670 string token = response.Substring((response.IndexOf(a) + a.Length), (response.IndexOf(b) - response.IndexOf(a) - a.Length));
671
672 response = null;
673 a = null;
674 b = null;
675
676 Console.WriteLine("csrf_token: " + token);
677 return token;
678 }
679
680 /**
681 * send encrypted request to the router
682 *
683 * @param string path
684 * @param string post
685 * @param bool cookie
686 * @return string
687 */
688 public string sendEnryptedRequest (string path, string post = "", bool cookie = true) {
689 string response = string.Empty;
690
691 try {
692 sjcl sjcl = new sjcl();
693
694 string iv = _challenge.Substring(16, 16);
695 string adata = _challenge.Substring(32, 16);
696 string dKey = _derivedk;
697
698
699 // TODO: check if we need this really?
700 if (post.IsNullOrEmpty().Equals(false)) {
701 post = sjcl.encrypt(dKey, post, iv, adata);
702 }
703
704
705 response = sendRequest(path, post, cookie);
706 // check if the return value is hex (hex = enrypted)
707 if (Regex.IsMatch(response, @"\A\b[0-9a-fA-F]+\b\Z").Equals(true)) {
708 response = sjcl.decrypt(dKey, response, iv, adata);
709 }
710
711 post = null;
712 iv = null;
713 adata = null;
714 dKey = null;
715 sjcl = null;
716
717 }
718 catch (ArgumentOutOfRangeException ex) {
719 LogManager.WriteToLog(ex.Message);
720 }
721 catch (Exception ex) {
722 LogManager.WriteToLog(ex.Message);
723 }
724
725 return response;
726 }
727
728 /**
729 * send request to the router
730 *
731 * @param string path
732 * @param string post
733 * @param bool cookie
734 * @return string
735 */
736 public string sendRequest (string path, string post = "", bool cookie = true) {
737 string response = string.Empty;
738 try {
739 string url = string.Concat("http://", ip, "/", path, "?lang=de");
740
741 HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;
742 /* set timeout to 10 seconds */
743 webRequest.Timeout = 10000;
744
745 if (cookie.Equals(true)) {
746 webRequest.CookieContainer = _cookie;
747 }
748
749 if (post.IsNullOrEmpty().Equals(false)) {
750 webRequest.Method = "POST";
751 byte[] dataStream = Encoding.UTF8.GetBytes(post);
752 webRequest.ContentLength = dataStream.Length;
753 Stream newStream = webRequest.GetRequestStream();
754 newStream.Write(dataStream, 0, dataStream.Length);
755 newStream.Close();
756 newStream.Dispose();
757 newStream = null;
758 dataStream = null;
759 }
760
761 WebResponse webResponse = webRequest.GetResponse();
762 StreamReader reader = new StreamReader(webResponse.GetResponseStream());
763 response = reader.ReadToEnd().ToString();
764
765 webResponse.Dispose();
766 reader.Dispose();
767 reader = null;
768 webRequest = null;
769 webResponse = null;
770 post = null;
771 }
772 catch (Exception ex) {
773 LogManager.WriteToLog(ex.Message);
774 }
775
776 return response;
777 }
778
779 public string sendRequest2 (string path, Dictionary<string, object> files, string post = "", bool cookie = true) {
780 string response = string.Empty;
781
782 try {
783 string url = string.Concat("http://", ip, "/", path, "?lang=de");
784
785 string boundary = string.Concat("---------------------------", DateTime.Now.Ticks.ToString("x"));
786 byte[] boundaryBytes = Encoding.ASCII.GetBytes(string.Concat("\r\n--", boundary, "\r\n"));
787
788 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
789 request.ContentType = string.Concat("multipart/form-data; boundary=", boundary);
790 request.Method = "POST";
791 request.KeepAlive = true;
792
793 if (cookie.Equals(true)) {
794 request.CookieContainer = _cookie;
795 }
796
797 Stream requestStream = request.GetRequestStream();
798
799 if (string.IsNullOrEmpty(post).Equals(false)) {
800 byte[] dataStream = Encoding.UTF8.GetBytes(post);
801 requestStream.Write(dataStream, 0, dataStream.Length);
802 dataStream = null;
803 }
804
805 if (files != null && files.Count > 0) {
806 foreach (KeyValuePair<string, object> pair in files) {
807 requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
808 if (pair.Value is FormFile) {
809 FormFile file = pair.Value as FormFile;
810 string header = string.Concat("Content-Disposition: form-data; name=\"", pair.Key, "\"; filename=\"", file.Name, "\"\r\nContent-Type: ", file.ContentType, "\r\n\r\n");
811 byte[] bytes = Encoding.UTF8.GetBytes(header);
812 requestStream.Write(bytes, 0, bytes.Length);
813 byte[] buffer = new byte[32768];
814 int bytesRead;
815 if (file.Stream == null) {
816 // upload from file
817 FileStream fileStream = File.OpenRead(file.FilePath);
818 while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) {
819 requestStream.Write(buffer, 0, bytesRead);
820 }
821 fileStream.Close();
822 }
823 else {
824 // upload from given stream
825 while ((bytesRead = file.Stream.Read(buffer, 0, buffer.Length)) != 0)
826 requestStream.Write(buffer, 0, bytesRead);
827 }
828 }
829 else {
830 string data = string.Concat("Content-Disposition: form-data; name=\"", pair.Key, "\"\r\n\r\n", pair.Value);
831 byte[] bytes = Encoding.UTF8.GetBytes(data);
832 requestStream.Write(bytes, 0, bytes.Length);
833 }
834 }
835
836 byte[] trailer = Encoding.ASCII.GetBytes(string.Concat("\r\n--", boundary, "--\r\n"));
837 requestStream.Write(trailer, 0, trailer.Length);
838 requestStream.Close();
839
840 }
841
842 WebResponse webResponse = request.GetResponse();
843 Stream responseStream = webResponse.GetResponseStream();
844 StreamReader reader = new StreamReader(responseStream);
845 response = reader.ReadToEnd();
846
847 webResponse.Dispose();
848 reader.Dispose();
849 reader = null;
850 request = null;
851 webResponse = null;
852 }
853 catch (Exception ex) {
854 LogManager.WriteToLog(ex.Message);
855 }
856
857 return response;
858 }
859 }
860
861 public class FormFile {
862 public string Name { get; set; }
863
864 public string ContentType { get; set; }
865
866 public string FilePath { get; set; }
867
868 public Stream Stream { get; set; }
869 }
870 }