我需要从移动设备上传文件到asp
服务器。该功能正常工作,直到客户端需要为上传服务器添加代理。
在iOS
上我使用NSMutableURLRequest
并将文件附加到HttpBody
作为数据,
let request = NSMutableURLRequest(URL:NSURL(string:urlString)!)
request.HTTPBody = uploader.createBodyWithParameters()
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {...}
哪个是工作,
在android
我使用了HttpUrlConnection
,我发现请求已被截断,OutputStream
发送的所有数据都将消失。
URL connectURL = new URL(serverURL);
HttpURLConnection conn = (HttpURLConnection) connectURL.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Accept", "*/*");
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
conn.setRequestProperty("Accept-Language", "en-usa");
conn.addRequestProperty("Authorization", "Bearer " + uploader.accesstoken);
conn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundary);
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\""
+ fileName +"\"" + lineEnd);
dos.writeBytes("Content-Type: "+"application/zip, application/octet-stream"+"\r\n\r\n");
FileInputStream fileInputStream = new FileInputStream(new File(filePath+"/"+fileName));
int bytesAvailable = fileInputStream.available();
int maxBufferSize = 1024 * 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[]buffer = new byte[bufferSize];
// read file and write it into form...
int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
这是ios请求数据
POST /Upload.ashx HTTP/1.1
Connection: keep-alive
Content-Length: 6998
Content-Type: multipart/form-data; boundary=Boundary-417BEF5E-9840-4369-B397-C5BA87C25D9E
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-usa
Authorization: ...
Host: 192.168.1.5
User-Agent: Apploader/11 CFNetwork/758.2.8 Darwin/15.6.0
--Boundary-417BEF5E-9840-4369-B397-C5BA87C25D9E
Content-Disposition: form-data; name="file"; filename="..."
Content-Type: application/zip, application/octet-stream
.......
--Boundary-417BEF5E-9840-4369-B397-C5BA87C25D9E--
Android结束"用户代理:Dalvik / 2.1.0(Linux; U; Android 6.0.1; SM-G925V Build / MMB29K)"
POST /AppLoader/Upload.ashx HTTP/1.1
Connection: Keep-Alive
Content-Length: 7464126
Content-Type: multipart/form-data; boundary=Boundary-fc13ac98-53bf-4f3f-9a56-ddc4393d8719
Accept-Encoding: gzip
Authorization: Bearer ..
Host: ...
User-Agent: Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-G925V Build/MMB29K)
我很确定在添加代理时发生问题,没有代理,上传功能正常。我的问题是iOS和Android有什么不同使得android上传失败,如何解决这个问题?
这是代理代码:
using Client.Proxy.Controllers;
using Client.Utilites;
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
namespace Proxy.Controllers
{
[RoutePrefix("Loader")]
public class AppLoaderController : BaseApiController
{
public AppLoaderController()
{
base.defaultServiceProxyName = "Loader";
}
[HttpPost]
[ActionName("Upload.ashx")]
public HttpResponseMessage Upload()
{
HttpResponseMessage result = new HttpResponseMessage();
try
{
LoggingUtilities.WriteLog("Upload Started", TraceEventType.Verbose);
var connector = GetConnectorProxyURI("AppLoaderReceiver").ToString();
LoggingUtilities.WriteLog(string.Format( "Connector: {0}", connector), TraceEventType.Verbose);
string requestUri = string.Format("{0}/Upload.ashx", connector.Replace("/AppLoader", "/"));
LoggingUtilities.WriteLog(string.Format("requestUri: {0}", requestUri), TraceEventType.Verbose);
MultipartFormDataContent content = new MultipartFormDataContent();
byte[] buffer = null;
try
{
HttpPostedFile file;
string requestFileName = string.Format("request-{0:yyyy-MM-dd_hh-mm-ss-tt}.txt", DateTime.Now);
LoggingUtilities.WriteLog(string.Format("log request to file."), TraceEventType.Verbose);
HttpContext.Current.Request.SaveAs(string.Format(@"c:\temp\{0}", requestFileName), true);
LoggingUtilities.WriteLog(string.Format("About to check Current.Request.Files.Count"), TraceEventType.Verbose);
if (HttpContext.Current.Request.Files.Count > 0)
{
file = HttpContext.Current.Request.Files[0];
LoggingUtilities.WriteLog(string.Format("file.ContentLength ={0}", file.ContentLength), TraceEventType.Verbose);
using (BinaryReader reader = new BinaryReader(file.InputStream))
{
buffer = reader.ReadBytes(file.ContentLength);
}
LoggingUtilities.WriteLog("Got FileData", TraceEventType.Verbose);
content.Add(new ByteArrayContent(buffer, 0, buffer.Length), "application/zip", file.FileName);
LoggingUtilities.WriteLog("Got ByteArrayContent", TraceEventType.Verbose);
string fileName = "";
fileName = HttpContext.Current.Request.Files[0].FileName;
LoggingUtilities.WriteLog(string.Format("Filename= {0}", fileName), TraceEventType.Verbose);
if (string.IsNullOrEmpty(fileName))
{
TimeSpan span = (TimeSpan)(DateTime.UtcNow - new DateTime(0x7b1, 1, 1));
string str3 = span.TotalMilliseconds.ToString().Substring(0, 13);
fileName = string.Format("*.zip", str3);
}
content.Add(new StringContent(fileName), "FILE_NAME");
Task<HttpResponseMessage> task1 = new HttpClient().PostAsync(requestUri, content);
task1.Wait();
result = task1.Result;
}
else
{
result = new HttpResponseMessage(HttpStatusCode.BadRequest);
}
}
catch (Exception exception)
{
result = new HttpResponseMessage(HttpStatusCode.BadRequest);
}
}
catch (Exception exception2)
{
result = new HttpResponseMessage(HttpStatusCode.BadRequest);
}
return result;
}
}
}
答案 0 :(得分:0)
How do I make HttpURLConnection use a proxy?这个答案可以帮到你; 在android中有很多http工具,比如volley,aysnchttp,okhttp ......你可以选择其中一个代替原来的HttpUrlConnection; 如果您可以在代码中添加日志打印并向我们提供日志,我们可能会对此问题有更多了解。
答案 1 :(得分:0)
谢谢Chris和Gao。 我通过删除
解决了这个问题conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
哪个效果服务器在发送到android之前将文本消息转换为gzip。
另一个问题来自于我从conn.getContentLength()得到-1, 我认为内容是空的,但它只是意味着请求具有未知的内容长度。仍然可以从conn.getInputStream()中读取内容。