I use the following code to send binary data to CGI C++ program from Android app (it is called in doInBackground within AsyncTask):
public static HttpResponse makeRequestPost(String uri, MyObject obj) {
try {
HttpPost httpPost = new HttpPost(uri);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
DataOutputStream dataStream = new DataOutputStream(stream);
obj.writeRawObject(dataStream);
byte[] byteArray = stream.toByteArray();
ByteArrayEntity entity = new ByteArrayEntity(byteArray);
entity.setContentType("application/octet-stream");
entity.setChunked(true);
httpPost.setEntity(entity);
return new DefaultHttpClient().execute(httpPost);
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "UnsupportedEncodingException. " + e.getMessage());
} catch (ClientProtocolException e) {
Log.e(TAG, "ClientProtocolException. " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "IOException. " + e.getMessage());
}
return null;
}
I tested the same server using CURL with data written to a file using:
obj.writeRawObject(dataStream);
Also, both byteArray and entity variables in the code above contain correct data before calling execute(httpPost).
For some reason, on the server side
char* lenstr = getenv("CONTENT_LENGTH");
returns NULL when I run the app. Data I am trying to send are from a few bytes to 30 kB. It doesn't get them on the server side regardless the size. App can communicate with the server but do not attach a binary data. Is it something I am missing?
Something like this works from CURL:
curl -i -H "Content-Type:application/octet-stream" -X POST --data-binary #file_with_my_obj.bin <url>
Appreciate any ideas.
Can you try using binary/octet-stream instead of application/octet-stream in setContentType ?
Related
I am trying to get the html source of a webpage through java code using Jsoup. Below is the code I am using to fetch the page. I am getting a 500 Internal Server Error.
String encodedUrl = URIUtil.encodePathQuery(urlToFetch.trim(), "ISO-8859-1");
Response res = Jsoup.connect(encodedUrl)
.header("Accept-Language", "en")
.userAgent(userAgent)
.data(data)
.maxBodySize(bodySize)
.ignoreHttpErrors(true)
.ignoreContentType(true)
.timeout(10000)
.execute();
However, when I fetch the same page with wget from command line, it works. A simple HttpClient from code also works.
// Create an instance of HttpClient.
HttpClient client = new HttpClient();
// Create a method instance.
GetMethod method = new GetMethod(url);
// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
try {
// Execute the method.
int statusCode = client.executeMethod(method);
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
}
// Read the response body.
byte[] responseBody = method.getResponseBody();
// Deal with the response.
// Use caution: ensure correct character encoding and is not binary data
System.out.println(new String(responseBody));
} catch (HttpException e) {
System.err.println("Fatal protocol violation: " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.err.println("Fatal transport error: " + e.getMessage());
e.printStackTrace();
} finally {
// Release the connection.
method.releaseConnection();
}
Is there anything I would need to change in the parameters for Jsoup.connect() method for it work?
This however does not happen for all urls. It is specifically happening for pages from this website:
http://xyo.net/iphone-app/instagram-RrkBUFE/
You need Accept header.
Try this:
String encodedUrl = "http://xyo.net/iphone-app/instagram-RrkBUFE/";
Response res = Jsoup.connect(encodedUrl)
.header("Accept-Language", "en")
.ignoreHttpErrors(true)
.ignoreContentType(true)
.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
.followRedirects(true)
.timeout(10000)
.method(Connection.Method.GET)
.execute();
System.out.println(res.parse());
It works.
Please also note that the site is trying to set cookies, you may need to handle them.
Hope it will help.
Problem: Trying to upload bigger than ~ 50 mb files, $_FILES return empty array.
I try change limits on php (a lot of combination) but it useleass..
my class at java:
public void upload() throws Exception {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(this.url);
try {
FileBody bin = new FileBody(this.file);
#SuppressWarnings("deprecation")
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("file", bin);
httppost.setEntity(reqEntity);
System.out.println("Requesting : " + httppost.getRequestLine());
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httppost, responseHandler);
System.out.println("responseBody : " + responseBody);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
httpclient.getConnectionManager().shutdown();
}
}
my php code to print array for respawn:
<?php
ini_set('file_uploads', 1);
ini_set('max_file_uploads', '9999999999M');
ini_set('post_max_size', '2000M');
ini_set('max_input_time', 3600);
ini_set('max_execution_time', 3600);
print_r($_FILES);
?>
You could try to add the mime type of the file when you create the FileBody. For example:
FileBody bin = new FileBody(this.file, "application/octect-stream");
Another solution is to use the HttpURLConnection client that is easier to use and less error prone. Also, Google recommends to use it for new applications.
One side or the other is breaking the http connection being used by the POST action.
Do you know which side ( client or server )
If you do not know , maybe you should try to rule out the server by using CURL to do the M-Multipart Post of one of your big ( +50 ) files.
Invoke CURL to upload and add the -v switch for verbose log so you can analyse the process.
Android POST action on files of 50 - 100 meg should work fine.
Since you are doing big uploads , you would want a client that you can send headers "expect 100 Continue" and where you can employ chunked transfer encoding along with a client side thread that can provide data to a buffer that is wrapped by something like a byteArrayEntity
apache or nginX on std config should handle this fine. If your php process is abending then maybe you need to check phpinfo.
I have been running into some issues with a small Android project for school. I need to request a password from an online database via a .php by sending it the username. It should return an encrypted password. But there seems to be something wrong with the method I use to connect to the database and receive the password. LogCat gives me these:
Error in HTTP connection java.net.UnknownHostException: boekenapp.atwebpages.com
Error converting result java.lang.NullPointerException
Error parsing data org.json.JSONException: end of input at character 0 of
So my question: What did I do wrong?/What do I need to change to make it work?
The code:
public static String phpconnect(String name, String value) {
String result = "";
InputStream is = null;
//variables to send to database
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair(name,value));
//HTTP post
try{
HttpClient httpclient = new DefaultHttpClient();
URI connection = new URI("http://boekenapp.atwebpages.com/phpscript.php");
HttpPost httppost = new HttpPost(connection);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch(Exception e) {
Log.e("log_tag", "Error in HTTP connection "+e.toString());
}
//convert response to string
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result=sb.toString();
} catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
//parse JSON data
try{
JSONArray jArray = new JSONArray(result);
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
Log.i("log_tag","userid: "+json_data.getInt("userid")+", password: "+json_data.getString("password"));
}
} catch(JSONException e) {
Log.e("log_tag", "Error parsing data "+e.toString());
}
return "";
}
The second try block will always execute, as you only log in the first catch block.
You should consider a return statement or a throw statement. An alternative is to embed the second try block inside the first one, but that's less readable maybe.
In your case, the problem is that the connection itself fails. Are you sure you have network up ? Can you ping the host from your computer and from Android (you can use adb shell ping <host> on CLI).
And don't truncate the error stacks on their first line, a stack has to be read fully, top-down until you find your piece of code that is causing the bug.
First of all the URL from this code used in a browser redirects to www.alotspace.com/error-404/ Just so you know.
Without testing, just looking at the code, I would start with checking the status line of the response. This is how
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
// here all is OK, you can check for 404 and so on
}
Also I see you handling the response with a buffered reader putting everything in a StringBuilder further in code. A better alternative would be using gson.
But focus on the initial network related exception first. The other exceptions are just a result of the separate try/catch blocks (as #Snicolas pointed out already). Unknownhost sounds like no network. Being redirect would just return different output than expected, not unkownhost. To verify that browse to the url from your android device you're testing on.
I want to save a document in CouchDB server for that I am writing my own PUT request. I can do so using curl command:
> curl -vX PUT http://127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af/artwork.jpg?rev=2-2739352689 --data-binary #artwork.jpg -H "Content-Type: image/jpg"
How can I write the same in PUT Request form in Java like:
HttpPut request = new HttpPut(url);
StringEntity stringEntity = null;
try {
stringEntity = new StringEntity(
(new JSONObject(map)).toString());
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
stringEntity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
request.setHeader("Content-type", "application/json");
request.setEntity(stringEntity);
Any idea, how to write such a put request as written in Curl command given above.
You need to deal with binary data, I was just doing this today and answered another post:
Couchdb Upload Image via Httpclient
I have a problem with my app, when i try to send a text to my apache server which contains characters like má mé mí mó mú it sent the character as m?. How can i solve that?
This is my code:
public boolean loginstatus(String reporte, String user) {
File file = new File(fileUri.getPath());
try {
MultipartEntityBuilder entity = MultipartEntityBuilder.create();
Log.e("enviando", "archivo "+fileUri.getPath());
Log.e("enviando", "reporte "+reporte);
Log.e("enviando", "usuario "+user);
entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
entity.addTextBody("reporte", reporte);
entity.addTextBody("usuarioID",user);
if (file.length() <= 0){
}else{
entity.addPart("archivo", new FileBody(file));
}
final HttpEntity yourEntity = entity.build();
httppost.setEntity(yourEntity);
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
First of all, the problem here is your encoding.
Either the database's table is not encoded to use UTF-8 or the String you send isnt.
table issue:
you can use CHARACTER SET utf8 on your db table.
String issue:
The elegant way to solve it is using
StringEntity entity = new StringEntity(Yourtext, "UTF-8");
The other way is to use your String's getBytes("UTF-8") function and use DataOutputStream