的Java / Android的HttpURLConnection的setChunkedStreamingMode不能处理所有的PHP服务器 [英] Java/Android HttpURLConnection setChunkedStreamingMode not working with all PHP servers

查看:969
本文介绍了的Java / Android的HttpURLConnection的setChunkedStreamingMode不能处理所有的PHP服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经花了近一天左右要调试这个问题,我的想法。基本上我有一个Android应用程序,被张贴一些数据到PHP / Apache Web服务器。这code似乎做工精细,当我在我的本地测试服务器指向它。它也似乎当我在我的生产服务器指向它做工精细,但只有当我注释掉行 conn.setChunkedStreamingMode(maxBufferSize); 。一旦该行被激活,后期只能我的本地测试服务器上,而是发布到生产服务器时,在PHP $ _FILES数组是空的。我试过路过无数值 setChunkedStreamingMode (包括0和1024),但这些似乎解决问题。

I've spent the last day or so trying to debug this issue and I'm out of ideas. Basically I have an Android app that is POSTing some data to a PHP/Apache web server. This code seems to work fine when I point it at my local test server. It also seems to work fine when I point it at my production server, but ONLY when I comment out the line conn.setChunkedStreamingMode(maxBufferSize);. Once that line is enabled, the post only works on my local test server, but when posting to the production server, the PHP $_FILES array is empty. I've tried passing numerous values to setChunkedStreamingMode (including 0 and 1024) but none of these seem to fix the problem.

在这一点上我假设这个问题必须与生产服务器的PHP的配置方式,但据我所知,在服务器上所有重要的参数是一样的在我的测试实例。此外,它们都运行Apache和PHP的版本相同。我的生产服务器是由BlueHost的运行。

At this point I'm assuming the issue has to do with the way the production server's PHP is configured, but as far as I can tell, all the important parameters on the server are the same as on my test instance. Additionally, they're both running the same version of Apache and PHP. My production server is run by Bluehost.

下面是在Java code我用上传:

Here's the Java code I'm using to upload:

HttpURLConnection conn = null;
DataOutputStream dos = null;
DataInputStream inStream = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "***************************************************";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 212144; // 1024*1024 = 1MB.  212144 is a quarter MB.
FileInputStream fileInputStream = null;
try
{
  // ------------------ CLIENT REQUEST
  fileInputStream = new FileInputStream(new File(existingFileWithFullPath));
  // open a URL connection to the Servlet
  URL url = new URL(BACKUP_POST_URL);
  // Open a HTTP connection to the URL
  conn = (HttpURLConnection) url.openConnection();
  // Allow Inputs
  conn.setDoInput(true);
  // Allow Outputs
  conn.setDoOutput(true);
  // Send in chunks (to avoid out of memory error)
  conn.setChunkedStreamingMode(maxBufferSize);
  // Don't use a cached copy.
  conn.setUseCaches(false);
  // Use a post method.
  conn.setRequestMethod("POST"); 
  conn.setRequestProperty("Connection", "Keep-Alive");
  conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="
      + boundary);
  conn.setReadTimeout(200000); // 200 seconds...
  dos = new DataOutputStream(conn.getOutputStream());
  dos.writeBytes(twoHyphens + boundary + lineEnd);
  dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\""
      + fileName + "\"" + lineEnd);
  dos.writeBytes(lineEnd);
  // create a buffer of maximum size
  bytesAvailable = fileInputStream.available();
  bufferSize = Math.min(bytesAvailable, maxBufferSize);
  buffer = new byte[bufferSize];
  // read file and write it into form...
  bytesRead = fileInputStream.read(buffer, 0, bufferSize);
  while (bytesRead > 0)
  {
    try {
      dos.write(buffer, 0, bufferSize);          
    } catch (OutOfMemoryError oome) {
      Log.e(CommonStatic.LOG_NAME, "Out of memory error caught...");
      oome.printStackTrace();
      fileInputStream.close();
      throw new Exception("Out Of Memory!");
    }
    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);
  fileInputStream.close();
  dos.flush();
  dos.close();

  // close streams
  Log.d(CommonStatic.LOG_NAME, "Backup file written to server successfully...");
}
catch (Exception ex)
{
  Log.e(CommonStatic.LOG_NAME, "Backup File Upload Error: " + ex.getMessage(), ex);
  throw new Exception (c.getString(R.string.SAVE_TO_CLOUD_ERROR));
}

和这里是我使用的另一端接受她的PHP code:

And here's the PHP code I'm using on the other end to recieve:

$target = "userfiles/"; 
$target = $target . basename( $_FILES['uploadedfile']['name']);

if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target)) 
{ 
  echo "SUCCESS";
} 
else 
{ 
  echo "FAIL";
}

我坚持一个的print_r($ _ FILES); 在脚本的一开始就确定$ _FILES是空的生产实例,而不是在测试实例。任何想法将大大AP preciated。

I stuck a print_r($_FILES); at the very beginning of the script to determine that $_FILES is empty on the production instance, but not on the test instance. Any ideas would be greatly appreciated.

推荐答案

不幸的是我没能找到一个直接的解决这个问题,但我能找到一个解决办法。而不是使用 conn.setChunkedStreamingMode 我用 conn.setFixedLengthStreamingMode ,这我以前没有成功尝试。敲门砖 conn.setFixedLengthStreamingMode 来的工作就是把它全长你试图发送(在这种情况下,该文件)中的数据,再加上的长度头。幸运的是报头长度通常是固定在code像这样的,所以一旦你计算出你的头有多大(记住的东西,如文件名,这将会在内容配置发送的报头也是可变的),你可以只是把它作为一个固定的数字。为了弄清楚我的头长度,我第一次跑了code不指定任何长度的头。我收到此错误信息回给了我的预期和字节数的实际值发送,这让我计算头部长度。

Unfortunately I wasn't able to find a direct solution to this problem, but I was able to find a workaround. Instead of using conn.setChunkedStreamingMode I used conn.setFixedLengthStreamingMode, which I had tried before with no success. The key to getting conn.setFixedLengthStreamingMode to work is to pass it the full length of the data you are attempting to send (in this case the file), plus the length of the headers. Fortunately header length is usually fixed in code such as this, so once you figure out how big your header is (keeping in mind things like the filename, which gets sent in the header under Content-Disposition is also variable) you can just put it in as a fixed number. To figure out my header length, I ran the code first without specifying any length for the header. The error message I received back gave me an expected and an actual value for the number of bytes sent, which allowed me to calculate the header length.

这篇关于的Java / Android的HttpURLConnection的setChunkedStreamingMode不能处理所有的PHP服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆