Сначала я попытался написать методы для этого в тестовом проекте. Это прекрасно работает:
Код: Выделить всё
private static async Task POST_internal(string url, HttpContent payLoad)
{
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(url);
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Add("Accept", "*/*");
try
{
var result = await httpClient.PostAsync(url, payLoad);
httpClient.Dispose();
return result;
}
catch (Exception)
{
httpClient.Dispose();
return null;
}
}
public static void POST_upload_token(IPAddress deviceIpAddress, string filename)
{
var requestURL = $"http://{deviceIpAddress}/api/upload_token";
using var payload = new MultipartFormDataContent();
payload.Add(new StreamContent(System.IO.File.OpenRead(filename)), "\"file\"", $"\"{Path.GetFileName(filename)}\"");
var response = POST_internal(requestURL, payload).Result;
if(response != null && response.IsSuccessStatusCode)
return;
throw new Exception($"Failed to post upload token to device.\nResponse code: {(response != null ? response.StatusCode : "Response was null")}\nResponse text {(response != null ? response.Content.ReadAsStringAsync().Result : "Response was null")}");
}
Код: Выделить всё
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.Единственное различие между тестовым проектом и основным проектом — это версии .NET. Тестовым проектом был .NET8, а основным проектом — .NET Framework 4.8.
При проверке трафика в Wireshark я считаю, что обнаружил проблему:
Запрос от программы .NET8 отправляет данные файла напрямую вместе с первым запросом
Код: Выделить всё
$X.$EJ@P8_8LPlPOST /api/upload_token HTTP/1.1
Host: 192.168.0.142
Accept: */*
Content-Type: multipart/form-data; boundary="afbc983b-2675-4133-b333-11fb5b878ca8"
Content-Length: 493
--afbc983b-2675-4133-b333-11fb5b878ca8
Content-Disposition: form-data; name="file"; filename="token_8961.bin"; filename*=utf-8''%22token_8961.bin%22
[FILE DATA]
--afbc983b-2675-4133-b333-11fb5b878ca8--
Код: Выделить всё
$X.$EZ@ XPPVpCs\PPOST /api/upload_token HTTP/1.1
Accept: */*
Content-Type: multipart/form-data; boundary="4855026b-b3a3-42df-8abe-d56028e7c47f"
Host: 192.168.0.142
Content-Length: 493
Expect: 100-continue
Connection: Keep-Alive
Код: Выделить всё
$X.$EW@Psft=,Pw--2fc0624c-9294-44ef-949d-0988aca1b042
Content-Disposition: form-data; name="file"; filename="token_8961.bin"; filename*=utf-8''%22token_8961.bin%22
[FILE DATA]
--2fc0624c-9294-44ef-949d-0988aca1b042--
Код: Выделить всё
$$X.E5WP=sftP
WHTTP/1.1 400 Bad Request
Connection: close
Content-Type: application/json
{"error":"Invalid filename. Expected TOKEN_8961.BIN"}
Установите для флага Expect100Continue значение false:
Код: Выделить всё
System.Net.ServicePointManager.Expect100Continue = false;- Удаляет заголовок Expect: 100-continue, но по-прежнему разделяет запрос
Код: Выделить всё
var request = new HttpRequestMessage(HttpMethod.Post, requestURL)
{
Content = payload
};
request.Headers.ConnectionClose = true;
request.Headers.ExpectContinue = false;
HttpClient.SendAsync(request);
- Удаляет оба заголовка, но по-прежнему разделяет запрос.
Код: Выделить всё
curl -X POST http://192.168.0.142/api/upload_token -F "file=@token_8961.bin;type=application/octet-stream"Подробнее здесь: https://stackoverflow.com/questions/798 ... ata-in-ini
Мобильная версия