Android帖子请求已被截断

时间:2016-12-18 15:26:27

标签: android proxy request httpurlconnection

我需要从移动设备上传文件到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;
        }
    }
}

2 个答案:

答案 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()中读取内容。