首页 \ 问答 \ 如何使用Java HttpClient库使用PHP上传文件(How to upload a file using Java HttpClient library working with PHP)

如何使用Java HttpClient库使用PHP上传文件(How to upload a file using Java HttpClient library working with PHP)

我想编写将使用PHP将文件上传到Apache服务器的Java应用程序。 Java代码使用Jakarta HttpClient库4.0版beta2:

import java.io.File;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils;


public class PostFile {
  public static void main(String[] args) throws Exception {
    HttpClient httpclient = new DefaultHttpClient();
    httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

    HttpPost httppost = new HttpPost("http://localhost:9002/upload.php");
    File file = new File("c:/TRASH/zaba_1.jpg");

    FileEntity reqEntity = new FileEntity(file, "binary/octet-stream");

    httppost.setEntity(reqEntity);
    reqEntity.setContentType("binary/octet-stream");
    System.out.println("executing request " + httppost.getRequestLine());
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity resEntity = response.getEntity();

    System.out.println(response.getStatusLine());
    if (resEntity != null) {
      System.out.println(EntityUtils.toString(resEntity));
    }
    if (resEntity != null) {
      resEntity.consumeContent();
    }

    httpclient.getConnectionManager().shutdown();
  }
}

PHP文件upload.php很简单:

<?php
if (is_uploaded_file($_FILES['userfile']['tmp_name'])) {
  echo "File ". $_FILES['userfile']['name'] ." uploaded successfully.\n";
  move_uploaded_file ($_FILES['userfile'] ['tmp_name'], $_FILES['userfile'] ['name']);
} else {
  echo "Possible file upload attack: ";
  echo "filename '". $_FILES['userfile']['tmp_name'] . "'.";
  print_r($_FILES);
}
?>

阅读回复我得到以下结果:

executing request POST http://localhost:9002/upload.php HTTP/1.1
HTTP/1.1 200 OK
Possible file upload attack: filename ''.
Array
(
)

所以请求是成功的,我能够与服务器通信,但是PHP没有注意到该文件 - 方法is_uploaded_file返回false$_FILES变量为空。 我不知道为什么这可能会发生。 我跟踪了HTTP响应和请求,他们看起来很好:
要求是:

POST /upload.php HTTP/1.1
Content-Length: 13091
Content-Type: binary/octet-stream
Host: localhost:9002
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.0-beta2 (java 1.5)
Expect: 100-Continue

˙Ř˙ŕ..... the rest of the binary file...

和回应:

HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Date: Wed, 01 Jul 2009 06:51:57 GMT
Server: Apache/2.2.8 (Win32) DAV/2 mod_ssl/2.2.8 OpenSSL/0.9.8g mod_autoindex_color PHP/5.2.5 mod_jk/1.2.26
X-Powered-By: PHP/5.2.5
Content-Length: 51
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

Possible file upload attack: filename ''.Array
(
)

我正在使用xampp和远程Linux服务器在本地Windows XP上测试这一点。 我也尝试使用以前版本的HttpClient - 3.1版,结果更加不清楚, is_uploaded_file返回false ,但$_FILES数组已填充正确的数据。


I want to write Java application that will upload a file to the Apache server with PHP. The Java code uses Jakarta HttpClient library version 4.0 beta2:

import java.io.File;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils;


public class PostFile {
  public static void main(String[] args) throws Exception {
    HttpClient httpclient = new DefaultHttpClient();
    httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

    HttpPost httppost = new HttpPost("http://localhost:9002/upload.php");
    File file = new File("c:/TRASH/zaba_1.jpg");

    FileEntity reqEntity = new FileEntity(file, "binary/octet-stream");

    httppost.setEntity(reqEntity);
    reqEntity.setContentType("binary/octet-stream");
    System.out.println("executing request " + httppost.getRequestLine());
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity resEntity = response.getEntity();

    System.out.println(response.getStatusLine());
    if (resEntity != null) {
      System.out.println(EntityUtils.toString(resEntity));
    }
    if (resEntity != null) {
      resEntity.consumeContent();
    }

    httpclient.getConnectionManager().shutdown();
  }
}

The PHP file upload.php is very simple:

<?php
if (is_uploaded_file($_FILES['userfile']['tmp_name'])) {
  echo "File ". $_FILES['userfile']['name'] ." uploaded successfully.\n";
  move_uploaded_file ($_FILES['userfile'] ['tmp_name'], $_FILES['userfile'] ['name']);
} else {
  echo "Possible file upload attack: ";
  echo "filename '". $_FILES['userfile']['tmp_name'] . "'.";
  print_r($_FILES);
}
?>

Reading the response I get the following result:

executing request POST http://localhost:9002/upload.php HTTP/1.1
HTTP/1.1 200 OK
Possible file upload attack: filename ''.
Array
(
)

So the request was successful, I was able to communicate with server, however PHP didn't notice the file - the method is_uploaded_file returned false and $_FILES variable is empty. I have no idea why this might happend. I have tracked HTTP response and request and they look ok:
request is:

POST /upload.php HTTP/1.1
Content-Length: 13091
Content-Type: binary/octet-stream
Host: localhost:9002
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.0-beta2 (java 1.5)
Expect: 100-Continue

˙Ř˙ŕ..... the rest of the binary file...

and response:

HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Date: Wed, 01 Jul 2009 06:51:57 GMT
Server: Apache/2.2.8 (Win32) DAV/2 mod_ssl/2.2.8 OpenSSL/0.9.8g mod_autoindex_color PHP/5.2.5 mod_jk/1.2.26
X-Powered-By: PHP/5.2.5
Content-Length: 51
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

Possible file upload attack: filename ''.Array
(
)

I was testing this both on the local windows xp with xampp and remote Linux server. I have also tried to use previous version of HttpClient - version 3.1 - and the result was even more unclear, is_uploaded_file returned false, however $_FILES array was filled with proper data.


原文:https://stackoverflow.com/questions/1067655
更新时间:2023-09-21 12:09

最满意答案

不熟悉Facebook API和iOS,所以我完全用理论来讲。

你能不能:

  1. 要求用户在iOS应用程序上使用Facebook登录
  2. 通过安全通道将登录数据发送到Web应用程序,以处理数据的实际处理
  3. 向iOS应用程序发送安全哈希以进行身份​​验证
  4. 根据需要使用您的Web应用程序; 使用哈希进行身份验证,像对待Web应用程序一样发出HTTPS请求,并使用来自Web服务器的响应来填充iOS应用程序

如果您将user_hash列设置为SHA-256(或更高版本)哈希之类的复杂盐渍哈希,则user_hash将在任何人能够猜测哈希值之前变为无效。 您可以在iOS设备上本地保存用户的Facebook凭据,然后每隔一段时间更新一次哈希,以使旧哈希失效并锁定犯罪者(如cookie过期)。 如果用户哈希在使用iOS应用程序时以某种方式变为无效,则应用程序将发送本地存储的凭据并检索新凭据。

如果Apple为应用程序提供cookie,您可以从您的网页发送cookie并给它一个合理的到期时间(例如1天)。 您每天都会重新发送本地存储的Facebook凭据,并有效地锁定任何试图破坏您的哈希值的人。 使用它而不是尝试从头开始实现cookie(如果iOS API提供),但正如我所说,我不熟悉iOS。

从SQL的角度来看,您的网页将验证用户的Facebook凭据,创建一个带有随机生成的user_hash的新行, expires timestamp, user_idfriends_id等。每个使用该网页的用户都必须从他们的网站发送user_hash客户端或iOS应用程序将根据数据库进行检查。 如果当前时间戳超过expires时间戳,则会话被裁定为无效,并且用户无法操作您的应用程序。

当然,您需要加密通信。 每次用户在Web应用程序上加载页面时,您是否都会传递凭据? 或者你把它们存放在会话中?

希望这至少有点帮助!

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSHTTPCookieStorage_Class/Reference/Reference.html


Not familiar with the Facebook API nor iOS so I am speaking completely in theoretical terms.

Could you not:

  1. Ask the user to login with Facebook on the iOS app
  2. Send the login data over a secure channel to your web application to handle the actual processing of the data
  3. Send the iOS app a secure hash for authentication
  4. Use your web application as needed; using the hash for authentication, make HTTPS requests as you would your web application and use the responses from the webserver to populate the iOS app

If you make a user_hash column a complex salted hash like a SHA-256 (or greater) hash, the user_hash will become invalid before anybody is able to guess the hash. You could save the user's Facebook credentials locally on the iOS device and then renew the hash every so often, as to invalidate old hashes and lock out perpetrators (like how a cookie expires). If the user hash somehow becomes invalidated while using the iOS app, the app will send the locally stored credentials and retrieve a new one.

If Apple offers cookies for apps, you could send the hash in a cookie from your webpage and give it a reasonable expiry time (e.g. 1 day). You'd be resending the locally stored Facebook credentials every day and be effectively locking out anybody trying to bruteforce your hashes. Use that instead of trying to implement cookies from scratch (if the iOS API offers that), but as I said, I'm unfamiliar with iOS.

From an SQL standpoint, your webpage would validate a user's Facebook credentials, create a new row with a randomly generated user_hash, expires timestamp, user_id, friends_id, etc. Every user that uses the webpage will have to send the user_hash either from their web-client or the iOS app and will be checked against the database. If the present timestamp exceeds the expires timestamp, the session is ruled invalid and the user cannot operate your application.

Of course, you'd need to encrypt the communication. Do you pass credentials everytime the user loads a page on your web app? Or do you store them in a session?

Hope this helps at least somewhat!

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSHTTPCookieStorage_Class/Reference/Reference.html

相关问答

更多

相关文章

更多

最新问答

更多
  • 如何在Laravel 5.2中使用paginate与关系?(How to use paginate with relationships in Laravel 5.2?)
  • linux的常用命令干什么用的
  • 由于有四个新控制器,Auth刀片是否有任何变化?(Are there any changes in Auth blades due to four new controllers?)
  • 如何交换返回集中的行?(How to swap rows in a return set?)
  • 在ios 7中的UITableView部分周围绘制边界线(draw borderline around UITableView section in ios 7)
  • 使用Boost.Spirit Qi和Lex时的空白队长(Whitespace skipper when using Boost.Spirit Qi and Lex)
  • Java中的不可变类(Immutable class in Java)
  • WordPress发布查询(WordPress post query)
  • 如何在关系数据库中存储与IPv6兼容的地址(How to store IPv6-compatible address in a relational database)
  • 是否可以检查对象值的条件并返回密钥?(Is it possible to check the condition of a value of an object and JUST return the key?)
  • GEP分段错误LLVM C ++ API(GEP segmentation fault LLVM C++ API)
  • 绑定属性设置器未被调用(Bound Property Setter not getting Called)
  • linux ubuntu14.04版没有那个文件或目录
  • 如何使用JSF EL表达式在param中迭代变量(How to iterate over variable in param using JSF EL expression)
  • 是否有可能在WPF中的一个单独的进程中隔离一些控件?(Is it possible to isolate some controls in a separate process in WPF?)
  • 使用Python 2.7的MSI安装的默认安装目录是什么?(What is the default installation directory with an MSI install of Python 2.7?)
  • 寻求多次出现的表达式(Seeking for more than one occurrence of an expression)
  • ckeditor config.protectedSource不适用于editor.insertHtml上的html元素属性(ckeditor config.protectedSource dont work for html element attributes on editor.insertHtml)
  • linux只知道文件名,不知道在哪个目录,怎么找到文件所在目录
  • Actionscript:检查字符串是否包含域或子域(Actionscript: check if string contains domain or subdomain)
  • 将CouchDB与AJAX一起使用是否安全?(Is it safe to use CouchDB with AJAX?)
  • 懒惰地初始化AutoMapper(Lazily initializing AutoMapper)
  • 使用hasclass为多个div与一个按钮问题(using hasclass for multiple divs with one button Problems)
  • Windows Phone 7:检查资源是否存在(Windows Phone 7: Check If Resource Exists)
  • 无法在新线程中从FREContext调用getActivity()?(Can't call getActivity() from FREContext in a new thread?)
  • 在Alpine上升级到postgres96(/ usr / bin / pg_dump:没有这样的文件或目录)(Upgrade to postgres96 on Alpine (/usr/bin/pg_dump: No such file or directory))
  • 如何按部门显示报告(How to display a report by Department wise)
  • Facebook墙贴在需要访问令牌密钥后无法正常工作(Facebook wall post not working after access token key required)
  • Javascript - 如何在不擦除输入的情况下更改标签的innerText(Javascript - how to change innerText of label while not wiping out the input)
  • WooCommerce / WordPress - 不显示具有特定标题的产品(WooCommerce/WordPress - Products with specific titles are not displayed)