2017-02-08 3 views
1

Ich habe ein Problem, wenn ich einen HTTP-POST über HttpClient ausführen. Ich benutzte es, Firmware ESP8266 Arduino OTA Firmware-Upgrade-Schnittstelle laden (siehe Beispiel: https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266HTTPUpdateServer/examples), aber es löst eine Ausnahme zu sagenC# - Unbekannte Antwort beim Ausführen von HTTP POST über HttpClient?

"WinHttpException: Der Server eine ungültige oder unbekannte Antwort zurückgegeben"

Wenn ich das Firmware-image von cURL hochladen, es mit dem Befehl total gut funktioniert unter:

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

ich das Debuggen mit Fiddler versucht habe, sagte er mir, dass ich habe 504 Gateway Timeout. Aber es wird nicht passieren, wenn ich cURL verwende.

Ich denke, es könnte durch einige Fehler innerhalb der Firmware OTA Update API ESP8266 verursacht werden, und mein Programm hat keine Kopfzeile generiert, die die API "erfüllen" kann, so wurde es irgendwie abgelehnt. Wenn möglich, möchte ich fragen, ob es eine Problemumgehung für dieses Problem gibt? Danke im Voraus!

Hier ist die von Fiddler erfasst Rohresultat der Curl:

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)....... 

Hier mein Programm des Rohresultat ist:

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)........... 

Hier ist mein (Teil) C# -Code,

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; 
     } 
    } 
} 

... und HTTP-Handler-Code ist hier:

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; 
      } 
     } 

Übrigens können Sie bei Bedarf nach meinem vollständigen Code auf GitHub suchen. Hier ist der Link: https://github.com/huming2207/JasmineApp.Windows

Antwort

1

Hallo Jackson sollten Sie esp Software ändern. Sie verwenden nicht https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266HTTPUpdateServer/examples, weil wir Server-Seite hochgeladen haben. Sie https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WebServer/examples/WebUpdate/WebUpdate.ino dieses Beispiel verwenden können, und Sie werden diesen Teil

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(); 
} 

Ich hoffe, Ihr Problem lösen ändern :) genießen

0

Versuchen Codierung der „Bild“ Namen

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

Ich habe versucht, es zu benutzen vorher, bleibt eigentlich immer noch gleich –