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