I'm making a Java application, and need the user to be able to upload a file to a server through PHP. The problem is that when the user uploads the file, the PHP script doesn't seem to "catch" the file.
This is the code I have so far.
PHP:
<?php
$target_path = "uploads/";
$target_path = $target_path . basename($_FILES['uploadedfile']['name']);
if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "1";
exit();
}
echo "0";
?>
Java:
String filename = "C:\Users\XXX\Pictures\Capture.PNG";
public void uploadFile() {
text = "";
String CrLf = "\r\n";
String filename = filepath.split("/")[filepath.split("/").length-1];
URLConnection conn = null;
OutputStream os = null;
InputStream is = null;
try {
URL con = new URL(connection);
conn = con.openConnection();
conn.setDoOutput(true);
InputStream imgIS = new FileInputStream(filepath);
byte[] imgData = new byte[imgIS.available()];
imgIS.read(imgData);
String message1 = "";
message1 += "-----------------------------4664151417711" + CrLf;
message1 += "Content-Disposition: form-data; name=\"uploadedfile\"; filename=\"Image0001.png\""
+ CrLf;
message1 += "Content-Type: image/png" + CrLf;
message1 += CrLf;
// the image is sent between the messages in the multipart message.
String message2 = "";
message2 += CrLf + "-----------------------------4664151417711--"
+ CrLf;
conn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=---------------------------4664151417711");
// might not need to specify the content-length when sending chunked
// data.
conn.setRequestProperty("Content-Length", String.valueOf((message1
.length() + message2.length() + imgData.length)));
System.out.println("open os");
os = conn.getOutputStream();
System.out.println(message1);
os.write(message1.getBytes());
// SEND THE IMAGE
int index = 0;
int size = 1024;
do {
System.out.println("write:" + index);
if ((index + size) > imgData.length) {
size = imgData.length - index;
}
os.write(imgData, index, size);
index += size;
} while (index < imgData.length);
System.out.println("written:" + index);
System.out.println(message2);
os.write(message2.getBytes());
os.flush();
System.out.println("open is");
is = conn.getInputStream();
char buff = 512;
int len;
byte[] data = new byte[buff];
do {
System.out.println("READ");
len = is.read(data);
if (len > 0) {
System.out.println(new String(data, 0, len));
}
} while (len > 0);
System.out.println("DONE");
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("Close connection");
try {
os.close();
} catch (Exception e) {
}
try {
is.close();
} catch (Exception e) {
}
try {
} catch (Exception e) {
}
}
}
When getting the output from the PHP script, it always returns a "0".
I've tried a lot of different things, but nothing seems to work.
Related
In my local it works perfectly, but when I deploy it gives me this error
nested exception is java.net.ConnectException: Connection timed out (Connection timed out)
with https everything works normal, but http does not work and it gives me the timeout error.
I also just did the tests with restTemplate, OkHttpClient and I get the same result
What am I doing wrong or what should I configure to work, I hope your help, I would be too grateful
public String getFile(String baseName, String extensioFile) {
String rpt;
int BUFFER_SIZE = 4096;
String urlDonwload = "http://datos.susalud.gob.pe/node/223/download";
try {
URL url = new URL(urlDonwload);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)");
httpConn.setConnectTimeout(900000);
httpConn.setReadTimeout(7200000);
int responseCode = httpConn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpConn.getHeaderField("Content-Disposition");
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10, disposition.length() - 1);
}
} else {
// extracts file name from URL
// fileName = urlCamaUci.substring(urlCamaUci.lastIndexOf("/") + 1,
// urlCamaUci.length());
LocalDateTime currentDate = LocalDateTime.now(ZoneOffset.of("-05:00"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatDateTime = currentDate.format(formatter);
System.out.println();
fileName = baseName + "_" + formatDateTime.replace(" ", "_").replace(":", "-") + "." + extensioFile;
}
InputStream inputStream = httpConn.getInputStream();
// String saveFilePath = PATH + File.separator + fileName;
File pathSave = new File(fileName);
FileOutputStream outputStream = new FileOutputStream(pathSave.getCanonicalPath());
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
rpt = pathSave.getCanonicalPath();
} else {
rpt = "FAILED";
}
httpConn.disconnect();
} catch (Exception e) {
System.out.println("error search path");
System.out.println(e.getMessage());
rpt = "FAILED";
}
return rpt;
}
I am saving a file to disk after downloading it from server, but I believe it gets corrupted while saving on the disc. If the same file is downloaded using chrome on mac or using any other method, the file downloads and reads normally. The corruption seems to be in the saving process of the file. I am adding the code to help find out the problem. The file is a css file.
Corruption:
Some whitespace sort of characters appear when reading the file. A surprising thing that I tried and noticed is that if I reduce the BUFFER_SIZE to 32 from 4096, the file does not get corrupt, I couldn't figure out why. Also, reducing BUFFER_SIZE reduces whitespaces / corrupted characters.
Appreciate any pointers in the right direction. Thanks
private static final int BUFFER_SIZE = 4096;
// saves file to disk and returns the contents of the file.
public static String downloadFile(Context context, String filePath, String destParent) {
String content = null;
StringBuilder sb = new StringBuilder();
HttpURLConnection connection = null;
InputStream is = null;
FileOutputStream os = null;
String sUrl = Urls.makeWebAssetUrl(filePath); /// consider this my file URL
String destFile = getContextBaseDir(context) + (destParent != null ? File.separator + destParent : "") + File.separator + filePath;
try {
URL url = new URL(sUrl);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
File outFile = new File(destFile);
if (!outFile.getParentFile().exists()) {
if (!outFile.getParentFile().mkdirs()) {
throw new RuntimeException("Unable to create parent directories for " + filePath);
}
}
is = connection.getInputStream();
os = new FileOutputStream(outFile);
int bytesRead = 0;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = is.read(buffer)) != -1) {
sb.append(new String(buffer, 0, bytesRead, DEFAULT_ENCODING));
os.write(buffer);
}
content = sb.toString();
}
else {
LogUtils.LOGW(TAG, responseCode + " while connecting to " + sUrl + ": " + connection.getResponseMessage());
}
} catch(Exception e) {
LogUtils.LOGE(TAG, "Error while downloading " + sUrl, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
LogUtils.LOGE(TAG, "Error closing inputStream while downloading " + sUrl, e);
}
}
if (os != null) {
try {
os.flush();
} catch (IOException e) {
LogUtils.LOGE(TAG, "Error flushing outputStream while downloading " + sUrl, e);
}
try {
os.close();
} catch (IOException e) {
LogUtils.LOGE(TAG, "Error closing outputStream while downloading " + sUrl, e);
}
}
}
return content;
}
os.write(buffer);
The problem is here. It should be:
os.write(buffer, 0, bytesRead);
I don't know why you are also accumulating the content in a StringBuffer and returning it as a String. That won't scale, and in any cast it's redundant. Remove.
I have a problem in sending the body of http response,and I think the problem in this line out.write(buffer, 0, bytes); please help me .
DataInputStream din = new DataInputStream(ClientConn.getInputStream());
OutputStream ot = ClientConn.getOutputStream();
BufferedOutputStream out = new BufferedOutputStream(ot);
String request = din.readLine().trim();
System.out.println(request);
StringTokenizer st = new StringTokenizer(request);
String header = st.nextToken();
System.out.println(header);
if (header.equals("GET")) {
String fileName = st.nextToken();
String file = fileName.substring(1, fileName.length());
System.out.println(file);
FileInputStream fin = null;
boolean fileExist = true;
try {
fin = new FileInputStream(file);
}
catch (Exception ex) {
fileExist = false;
}
String ServerLine = "Simple HTTP Server";
String StatusLine = null;
String ContentTypeLine = null;
String ContentLengthLine = null;
String ContentBody = null;
if (fileExist) {
StatusLine = "HTTP/1.0 200 OK";
ContentTypeLine = "Content-type: text/html";
ContentLengthLine = "Content-Length: " + (new Integer(fin.available()).toString());
} else {
StatusLine = "HTTP/1.0 200 OK";
ContentTypeLine = "Content-type: text/html";
ContentBody = "<HTML>" +
"<HEAD><TITLE>404 Not Found</TITLE></HEAD>" +
"<BODY>404 Not Found" +
"</BODY></HTML>";
ContentLengthLine = (new Integer(ContentBody.length()).toString());
}
out.write(StatusLine.getBytes());
out.write(ServerLine.getBytes());
out.write(ContentTypeLine.getBytes());
out.write(ContentLengthLine.getBytes());
// output.writeUTF(file);
if (fileExist) {
byte[] buffer = new byte[1024];
int bytes = 0;
while ((bytes = fin.read(buffer)) != -1) {
out.write(buffer, 0, bytes);
for (int iCount = 0; iCount < bytes; iCount++) {
int temp = buffer[iCount];
System.out.print((char) temp);
}
}
}
out.flush();
fin.close();
} else {
//out.write(ContentBody.getBytes());
}
out.close();
ClientConn.close();
Your header is not properly written into the OutputStream, you forget to write the EOL characters which are "\r\n" at the end of each line. And before starting to write the content of your body you need to write the EOL characters too.
In other words, you need to do something like this:
String eol = "\r\n";
Charset charset = Charset.forName("ASCII");
byte[] eolBytes = eol.getBytes(charset);
out.write(StatusLine.getBytes(charset));
out.write(eolBytes);
out.write( ServerLine.getBytes(charset));
out.write(eolBytes);
out.write(ContentTypeLine.getBytes(charset));
out.write(eolBytes);
out.write( ContentLengthLine.getBytes(charset));
out.write(eolBytes);
// End of the header
out.write(eolBytes);
// Here the body begin
Indeed your header must be encoded into ASCII.
Response update:
Other remarks regarding your code:
Use the method File#exists() to check if a file exist.
Use Files.getAttribute(Paths.get("/path/to/my/file"), "size") to get the size of your file
In case the file doesn't exist you just don't write the body in your current code.
static String username = "######";
static String password = "#####";
static String senderid = "###";
static String message = "वउह";
static String mobileNo = "08447475458";
static String mobileNos = "08447475458,08447475458";
static String scheduledTime = "20110701 02:27:00";
static HttpURLConnection connection = null;
public static void main(String[] args) {
try {
URL url = new URL("http://msdgweb.mgov.gov.in/esms/sendsmsrequest");
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setFollowRedirects(true);
connection = sendSingleSMS(username, password, senderid,
mobileNo, message);
System.out.println("Resp Code:" + connection.getResponseCode());
System.out.println("Resp Message:"
+ connection.getResponseMessage());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Method for sending single SMS.
public static HttpURLConnection sendSingleSMS(String username,
String password, String senderId,
String mobileNo, String message) {
try {
byte[] bytes = message.getBytes("UTF-8");
String smsservicetype = "singlemsg"; // For single message.
String query = "username=" + URLEncoder.encode(username)
+ "&password=" + URLEncoder.encode(password)
+ "&smsservicetype=" + URLEncoder.encode(smsservicetype)
+ "&content=" + URLDecoder.decode(message,"utf-8") + "&mobileno="
+ URLEncoder.encode(mobileNo) + "&senderid="
+ URLEncoder.encode(senderId);
connection.setRequestProperty("Content-length", String
.valueOf(query.length()));
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset = utf-8");
connection.setRequestProperty("User-Agent",
"Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)");
DataOutputStream output = new DataOutputStream(connection
.getOutputStream());
int queryLength = query.length();
output.writeBytes(query);
System.out.println(query);
DataInputStream input = new DataInputStream(connection
.getInputStream());
for (int c = input.read(); c != -1; c = input.read())
System.out.print((char) c);
input.close();
} catch (Exception e) {
System.out.println("Something bad just happened.");
System.out.println(e);
e.printStackTrace();
}
return connection;
I am using this code to send sms from gateway but this code is fine if the text is english but if I give some hindi text then its not able to read it and user gets some characters.
the output is something like
व� हव�� व�हव ��व� हवहব व�ह
The DataInputStream is reading bytes, but then you have to properly convert those bytes to characters using the correct encoding. For that, you could construct a String using the constructor as follows:
String hindiCharSequence = new String(bytes, "UTF-8");
The answer from #ChthonicProject is the correct answer to accept, here a bit code. It uses a ByteArrayOutputStream to collect the bytes. A DataInputStream is more useful for reading binary ints and such. Better use just a buffering. And/or read a byte[] buffer of say 160 bytes.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (BufferedInputStream input = new BufferedInputStream(connection
.getInputStream())) {
for (int c = input.read(); c != -1; c = input.read()) {
baos.write(c);
}
} // Closes input.
String msg = new String(baos.toByteArray(), StandardCharsets.UTF_8);
System.out.print(msg);
What you did, was considering every byte as a char. But with UTF-8 several bytes may make up a char, which is 16 bit.
May be the problem is with the SMS encoding. By default it uses GSM 7-bit alphabet.
Check if you can specify which encoding will be used in SMS encoding.
Applied this belore query string and its done
System.out.println(message);
String finalmessage = "";
String sss = "";
char ch = 0;
for(int i = 0 ; i < message.length();i++){
ch = message.charAt(i);
int j = (int) ch;
// System.out.println("iiii::"+j);
sss = "&#"+j+";";
finalmessage = finalmessage+sss;
}
System.out.println("ddd"+finalmessage);
message=finalmessage;
System.out.println("unicoded message=="+message);
I am uploading a file to a php server from my java application and it uploads everything fine but I have noticed if it has a character such as ' in it then the in the file it will be \' not '
for example if I upload the file with the following code in java:
public static void main(String[] args)
{
FILE tmpFile = new FILE(EncryptionUtil.EncryptAndZip("tes't file.txt").getAbsoluteFile().toString());
postData
(
UPLOAD_URL + "?filename=" + URLEncoder.encode(file.getFileName() + ".zip", "utf-8"),
tmpFile.getFileName() + ".zip",
tmpFile.getFileLoader().readAllBytes() // FILE.getFileLoader().readAllBytes() is just a wrapper and reads all bytes from a file to byte[]
);
}
private static final String CrLf = "\r\n";
public static void postData(String url, String filename, byte[] byteData) throws IOException
{
URLConnection conn = null;
InputStream is = null;
OutputStream os = null;
try
{
URL obj = new URL(url);
System.out.println("url:" + obj);
conn = obj.openConnection();
conn.setDoOutput(true);
String message1 = "";
message1 += "-----------------------------4664151417711" + CrLf;
message1 += "Content-Disposition: form-data; name=\"uploadedfile\"; filename=\"" + filename + "\""
+ CrLf;
message1 += "Content-Type: application/octet-stream" + CrLf;
message1 += CrLf;
String message2 = "";
message2 += CrLf + "-----------------------------4664151417711--"
+ CrLf;
conn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=---------------------------4664151417711");
conn.setRequestProperty("Content-Length", String.valueOf((message1
.length() + message2.length() + byteData.length)));
os = conn.getOutputStream();
os.write(message1.getBytes());
int index = 0;
int size = 1024;
do
{
if ((index + size) > byteData.length)
{
size = byteData.length - index;
}
os.write(byteData, index, size);
index += size;
}
while (index < byteData.length);
os.write(message2.getBytes());
os.flush();
is = conn.getInputStream();
char buff = 512;
int len;
byte[] data = new byte[buff];
do
{
len = is.read(data);
if (len > 0)
{
System.out.println(new String(data, 0, len));
}
}
while (len > 0);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
os.close();
}
catch (Exception e)
{
}
try
{
is.close();
}
catch (Exception e)
{
}
try
{
}
catch (Exception e)
{
}
}
}
response from server
url: http://127.0.0.1/cloudstore/upload.php?filename=tes%27t+.txt.zip
name of file user wants to save as: tes\'t file.txt.zip
actual save name: tes\'t file.txt.zip
Array
(
[name] => tes't file.txt.zip
[type] => application/octet-stream
[tmp_name] => /tmp/phpgYl0QT
[error] => 0
[size] => 1274598
)
and below is my php file upload.php
<?php
$target_path = "" . $_GET['filename'];
echo ' name of file user wants to save as: '.$target_path.'<br/>';
if (!file_exists(dirname($target_path))) {
mkdir(dirname($target_path), 0777, true);
}
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "actual save name: ".basename( $_FILES['uploadedfile']['name'])." <br/>";
} else{
echo "There was an error uploading the file, please try again!<br />";
}
print_r($_FILES['uploadedfile']);
?>
what would be causing this issue I think it is php trying to sanitize the input? how would I stop this from occurring?
As wished by the OP, to close the question.
Use stripslashes()
It helps to un-quote a quoted string, which is the cause.
It will change tes\'t to tes't if desired to be saved as such, and if so desired.
From the manual:
An example use of stripslashes() is when the PHP directive magic_quotes_gpc is on (it was on by default before PHP 5.4), and you aren't inserting this data into a place (such as a database) that requires escaping. For example, if you're simply outputting data straight from an HTML form.
I would usually just prefer to turn off magic quotes if it is on. By the way it's already deprecated in newer PHP versions.