【问题标题】:Android post request has been truncatedAndroid 发布请求已被截断
【发布时间】:2016-12-18 15:26:27
【问题描述】:

我需要从手机上传文件到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;
        }
    }
}

【问题讨论】:

    标签: android proxy request httpurlconnection


    【解决方案1】:

    How do I make HttpURLConnection use a proxy?这个答案可能对你有所帮助; 在android中有很多http工具,比如volley,aysnchttp,okhttp...你可以选择其中一种来代替原来的HttpUrlConnection; 如果您可以在代码中添加日志打印并将日志提供给我们,我们可能会对此问题了解更多;

    【讨论】:

      【解决方案2】:

      感谢克里斯和高。 我通过删除解决了这个问题

      conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
      

      哪个效果服务器在发送到android之前将文本消息转换为gzip。

      当我从 conn.getContentLength() 得到 -1 时,另一个问题来了, 我以为内容是空的,但这只是意味着请求的内容长度未知。仍然可以从 conn.getInputStream() 读取内容。

      【讨论】:

        猜你喜欢
        • 2019-08-06
        • 2017-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-07
        • 1970-01-01
        • 2016-01-29
        • 1970-01-01
        相关资源
        最近更新 更多