У меня проблема, когда я запускаю 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
Я пробовал прежде, все еще остается тем же самым –