2017-02-08 23 views
1

У меня проблема, когда я запускаю HTTP POST через HttpClient. Я использовал его загрузку микропрограммы интерфейса обновления прошивки OTA ESP8266 Arduino (см образца: https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266HTTPUpdateServer/examples), но он бросает исключение, говоряC# - Неопознанный ответ при запуске HTTP POST через HttpClient?

«WinHttpException: Сервер возвратил недопустимый или нераспознанный ответ»

Когда я загрузить изображение прошивки на локон, он работает совершенно нормально с командой ниже:

curl -F "[email protected]" 192.168.1.104/update 

Я попытался отладки с Скрипач, он сказал мне, У меня есть 504 Тайм-аут шлюза. Но это не произойдет, если я использую cURL.

Возможно, это может быть вызвано некоторыми ошибками в API-интерфейсе API-интерфейса прошивки OSP ESP8266, и моя программа не создала заголовок, который может «удовлетворить» API, поэтому его каким-то образом отклонили. Если возможно, я хотел бы спросить, есть ли какие-либо способы решения этой проблемы? Заранее спасибо!

Вот сырой результат локонов захвачен Скрипач:

POST http://192.168.1.104/update HTTP/1.1 
Host: 192.168.1.104 
User-Agent: curl/7.51.0 
Accept: */* 
Connection: Keep-Alive 
Content-Length: 335869 
Expect: 100-continue 
Content-Type: multipart/form-data; boundary=------------------------32e3208a349a700d 

--------------------------32e3208a349a700d 
Content-Disposition: form-data; name="image"; filename="firmware.bin" 
Content-Type: application/octet-stream 

.......(Firmware File Content)....... 

Вот сырой результат моей программы:

POST http://192.168.1.104/update HTTP/1.1 
Connection: Keep-Alive 
Content-Type: multipart/form-data; boundary="----TwilightFirmware" 
Accept-Encoding: gzip, deflate 
Content-Length: 335857 
Host: 192.168.1.104 

------TwilightFirmware 
Content-Type: application/octet-stream 
Content-Disposition: form-data; name=update; filename=firmware.bin; filename*=utf-8''firmware.bin 

.............(Firmware file Content)........... 

Вот мой (часть) C# код,

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.IO; 
using System.Net.Http; 
using System.Diagnostics; 


namespace JasmineApp.Core 
{ 
    class LocalFirmwareUpdater 
    { 
     public async Task<bool> UploadLocalFirmware(string baseUrl, string filePath) 
     { 
      Debug.WriteLine("[Core.FirmwareUpdater] Base URL is: " + baseUrl); 
      HttpCommandHandler httpHandler = new HttpCommandHandler(); 
      httpHandler.SetHttpBaseUrl(baseUrl); 

      byte[] firmwareContent = File.ReadAllBytes(filePath); 

      // HttpContent postContent = new StreamContent(firmwareStream); 
      HttpContent postContent = new ByteArrayContent(firmwareContent); 
      postContent.Headers.Add("Content-Type", "application/octet-stream"); 

      var formData = new MultipartFormDataContent("----TwilightFirmware"); 
      formData.Add(postContent, "update", "firmware.bin"); 
      string result = await httpHandler.ExecutePostAsync("/update", formData); 
      // string result = await httpHandler.ExecutePostAsync("/update", postContent); 

      return (
       result.Equals(string.Empty) 
       || result == null 
       || result.Contains("Fail")) ? false : true; 
     } 
    } 
} 

... и код обработчика HTTP:

public async Task<string> ExecutePostAsync(string pathAndQuery, MultipartFormDataContent content) 
    { 
     Debug.WriteLine("[Core.HttpHandler] Request POST URL: " + BaseUrl + pathAndQuery); 

     using(var client = this.getHttpClient()) 
     { 
      client.Timeout = TimeSpan.FromSeconds(2000000); 
      var httpResponseMessage = client.PostAsync(pathAndQuery, content).Result; 


      if(httpResponseMessage != null) 
      { 
       string responseResult = await httpResponseMessage.Content.ReadAsStringAsync(); 
       Debug.WriteLine("[Core.HttpCommandHandler] POST return message: " + httpResponseMessage.Content.ReadAsStringAsync().Result); 
       return responseResult; 
      } 
      else 
      { 
       // Return an empty string to avoid exceptions 
       // Don't need to worrry if it's empty. 
       return string.Empty; 
      } 
     } 

Кстати, вы можете посмотреть мой полный код на GitHub, если необходимо. Вот ссылка: https://github.com/huming2207/JasmineApp.Windows

ответ

1

Здравствуйте, Джексон, вы должны изменить программное обеспечение esp. вы не используете https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266HTTPUpdateServer/examples, потому что мы загрузили серверную сторону. Вы можете использовать https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WebServer/examples/WebUpdate/WebUpdate.ino этот пример, и вы измените эту часть

server.on("/update", HTTP_POST, [](){ 
    server.sendHeader("Connection", "close"); 
    server.sendHeader("Access-Control-Allow-Methods", "GET, POST, PUT"); 
    server.sendHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept, Authorization"); 
    server.send(200, "text/plain", (Update.hasError())?"FAIL":"OK"); 
    ESP.restart(); 
} 

Я надеюсь решить вашу проблему :) наслаждаться кодирования

0

Попробуйте использовать «образ» имя

formData.Add(postContent, "image", "firmware.bin"); 
+0

Я пробовал прежде, все еще остается тем же самым –