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