我试图像浏览器(chrome)那样模拟HTTP帖子文件:
HTML :
<form name="fnup" method="post" action="action.shtml" enctype="multipart/form-data">
<input name="firmfile" id="firmfile" type="file">
<input type="submit" id="firmbutton" value="Upgrade" class="othsave">
</form>
C#:
public async Task<string> UploadFile(string actionUrl, string filePath)
{
var httpClient = new HttpClient();
//Should I need to add all those headers??? it will help me? what is necessary?
httpClient.DefaultRequestHeaders.Add("Upgrade-Insecure-Requests", "1");
httpClient.DefaultRequestHeaders.Add("Origin", "http://" + ip);
httpClient.DefaultRequestHeaders.Add("Upgrade-Insecure-Requests", "1");
httpClient.DefaultRequestHeaders.Add("Pragma", "no-cache");
httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");
httpClient.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
httpClient.DefaultRequestHeaders.Add("Referer", "http://" + ip + "/");
httpClient.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
httpClient.DefaultRequestHeaders.Add("Accept-Language", "he,en-US;q=0.9,en;q=0.8");
httpClient.DefaultRequestHeaders.Add("Cookie", "page=DevSet");
FileStream paramFileStream = File.OpenRead(filePath);
HttpContent fileStreamContent = new StreamContent(paramFileStream);
using (var content = new MultipartFormDataContent())
{
content.Add(fileStreamContent, "firmfile", Path.GetFileName(filePath));
HttpResponseMessage response = await httpClient.PostAsync(actionUrl, content);
string res = await response.Content.ReadAsStringAsync();
return await Task.Run(() => res);
}
}
C#示例在我的服务器中无效,我无法理解为什么......
在查看Wireshark之后,我发现了一些不同之处:
Chrome :
C#
问题:
1)如何从"filename*=utf-8''VP445_all_V116.bin"
中删除Content-Disposition
2)为什么我在Chrome中看不到第二行Content-Type: application/octet-stream
?
3)内容长度也不相同(即使它是同一个文件)
4)底线是C#不工作且chrome正在工作,服务器端对我来说是黑盒子,所以我需要猜测我在C#post请求中做错了什么。
答案 0 :(得分:1)
找到解决方案。
问题确实是'Content-Type: application/octet-stream'
为什么HttpClient
StreamContent
未添加自动?我真的不知道。
将解决方法添加到手动
主要想法是从这里: https://github.com/paulcbetts/ModernHttpClient/issues/92
这是固定的C#代码:
public async Task<string> UploadFile(string actionUrl, string filePath)
{
var httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromMilliseconds(FileReqTimeout);
FileStream fileStream = File.OpenRead(filePath);
var streamContent = new StreamContent(fileStream);
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
streamContent.Headers.ContentDisposition.Name = "\"firmfile\"";
streamContent.Headers.ContentDisposition.FileName = "\"" + Path.GetFileName(filePath) + "\"";
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
string boundary = Guid.NewGuid().ToString();
var content = new MultipartFormDataContent(boundary);
content.Headers.Remove("Content-Type");
content.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + boundary);
content.Add(streamContent);
HttpResponseMessage response = null;
try
{
response = await httpClient.PostAsync(actionUrl, content, cts.Token);
}
catch (WebException ex)
{
// handle web exception
return null;
}
catch (TaskCanceledException ex)
{
if (ex.CancellationToken == cts.Token)
{
// a real cancellation, triggered by the caller
return null;
}
else
{
// a web request timeout (possibly other things!?)
return null;
}
}
try
{
response.EnsureSuccessStatusCode();
}
catch (Exception)
{
return null;
};
string res = await response.Content.ReadAsStringAsync();
return await Task.Run(() => res);
}
}