RE: Looking for an app...

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> -----Original Message-----
> From: bruce [mailto:bedouglas@xxxxxxxxxxxxx]
> Sent: Thursday, January 15, 2009 12:18 PM
> To: php-general@xxxxxxxxxxxxx
> Subject:  Looking for an app...
> 
> Hi List!
> 
> 
> I know this is somewhat basic.. and I am searching google as I type!
> I'm
> looking for a client/server app that allows me to have a quick/dirty
> client
> that can upload/download a file to a server app, with the server app
> copying
> the file to a given dir...
> 
> Code samples, or pointers to a site where I can download this would be
> great!! I don't want a straight FTP, as I want to do more things with
> the
> server piece...
> 
> And yes, a php/apache kind of app would be cool..
> 
> thanks!!

Okay, guys... as promised, I have finally dug up my Java/PHP code for
this and wrapped the data in Base64 encoding to (hopefully) avoid the
missing byte errors I had been experiencing previously.

The following code is untested, as I have added Base64 encoding/decoding
since the last time I played with this, and I'm not at my home computer
to test it out.

There are three Java files involved: uploadApp.java, which is my own
code, and you can see below; ClientHttpRequest.java, which you can find
online [1]; and finally, Base64.java, which you can also find online
[2].

On the PHP side, there is a very simple script (shown below) which grabs
the segmented data, decodes it, and appends it to a file being uploaded.
WARNING: There is no check for missing bytes, and no guarantee that
everything is being sent! There is also no garbage collection with
regard to the temp folder used for "parts." This is a base
implementation with no frills. Well, ok--there's one frill: you can use
the "hash" field POST value as a flimsy security layer for the
connection. If the client's hash doesn't match the server's, the file
part is rejected and the upload fails. It's currently set to a constant
"abcdef123456" but could easily be generated programmatically based on
user data.

Without further adieu, here it is...

uploadApp.java:
**********
package postmusic;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class uploadApp implements ActionListener
{
	private uploadApp that;

	// url for POST
	private java.net.URL postUrl;

	// UI components
	private JFrame frmMain;
	private JPanel pnlMain;
	private JLabel lblFilename;
	private JTextField txfFilename;
	private JPanel pnlButtons;
	private JButton btnBrowse;
	private JButton btnOk;
	private JButton btnCancel;
	private JFileChooser flcSelectFile;

	public uploadApp()
	{
		that = this;

		try
		{
			postUrl = new
java.net.URL("http://localhost/postmusic/upload.php";);
		}
		catch(Exception e) { }

		buildGUI();
	}

	// build and show the user interface
	private void buildGUI()
	{
		frmMain = new JFrame("Postmusic.org Upload");

		pnlMain = new JPanel();
		pnlMain.setLayout(new BorderLayout());
		pnlButtons = new JPanel();

		lblFilename = new JLabel("File to upload: ");
		txfFilename = new JTextField(20);
		flcSelectFile = new JFileChooser();

		btnBrowse = new JButton("Browse");
		btnBrowse.addActionListener(that);
		btnOk = new JButton("Upload");
		btnOk.addActionListener(that);
		btnCancel = new JButton("Cancel");
		btnCancel.addActionListener(that);

		pnlMain.add(lblFilename, BorderLayout.NORTH);
		pnlMain.add(txfFilename, BorderLayout.CENTER);
		pnlButtons.add(btnBrowse);
		pnlButtons.add(btnOk);
		pnlButtons.add(btnCancel);
		pnlMain.add(pnlButtons, BorderLayout.SOUTH);

		frmMain.getContentPane().add(pnlMain);
		frmMain.pack();
		frmMain.setVisible(true);
	}

	public void actionPerformed(ActionEvent ae)
	{
		int returnVal;

		// "browse" clicked
		if(ae.getSource() == btnBrowse)
		{
			returnVal =
flcSelectFile.showOpenDialog(frmMain);

			if(returnVal == JFileChooser.APPROVE_OPTION)
			{
	
txfFilename.setText(flcSelectFile.getSelectedFile().getPath());
			}
		}
		// "upload" clicked
		else if(ae.getSource() == btnOk)
		{
			File fileToUpload = new
File(txfFilename.getText());

			// invalid file chosen
			if(!fileToUpload.exists())
			{
				JOptionPane.showMessageDialog(frmMain,
					"File to upload does not
exist.", "Error!",
					JOptionPane.ERROR_MESSAGE);
				return;
			}

			// post the form data
			try
			{
				FileInputStream fis = new
FileInputStream(fileToUpload);
				long totalParts = fileToUpload.length()
/ 1024;
				byte[] chunkToUpload = new byte[1024];
				int bytesRead = 0;

				if(fileToUpload.length() % 1024 != 0)
					totalParts++;

				for(int i = 1; i <= totalParts; i++)
				{
					bytesRead =
fis.read(chunkToUpload, 0, 1024);
					String encodedText =
Base64.encodeBytes(chunkToUpload);
					ClientHttpRequest chreq;
					chreq = new
ClientHttpRequest(postUrl);
					chreq.setParameter("hash",
"abcdef123456");
					chreq.setParameter("part", i);
					chreq.setParameter("total",
totalParts);
					chreq.setParameter("upload",
encodedText);
					chreq.setParameter("filename",
fileToUpload.getName());

					InputStream is = chreq.post();
					StringBuffer sb = new
StringBuffer();
					int curByte = is.read();

					// read the results from the PHP
server
					do
					{
						sb.append((char)
curByte);
						curByte = is.read();
					}
					while(curByte > -1);

					is.close();
					String resultCode =
sb.toString().trim();
					System.out.println(resultCode +
" of " + bytesRead
						+ " received.");

					// if the message isn't "OK",
then fail
					if(resultCode.contains("FAIL"))
					{
						throw new
Exception("Server-side failure uploading " +
	
fileToUpload.getName());
					}
				}

				fis.close();
				JOptionPane.showMessageDialog(frmMain,
						"File upload
successful!", "Success!",
	
JOptionPane.INFORMATION_MESSAGE);
				System.exit(0);
			}
			catch(Exception e)
			{
				JOptionPane.showMessageDialog(frmMain,
"File upload failed!",
					"Error!",
JOptionPane.ERROR_MESSAGE);
				System.err.println(e.toString());
				return;
			}
		}
		// "cancel" clicked
		else if(ae.getSource() == btnCancel)
		{
			System.exit(0);
		}
	}

	public static void main(String[] args)
	{
		new uploadApp();
	}
}
**********

upload.php:
**********
<?php
	$hashCode = "abcdef123456";

	if($_POST['hash'] == $hashCode)
	{
	  	if(!isset($_POST['part'])
			|| !isset($_POST['upload'])
			|| !isset($_POST['total'])
			|| !isset($_POST['filename']))
  		{
  			die("FAIL - post syntax");
	  	}

  		$part = $_POST['part'];
	  	$total = $_POST['total'];
  		$chunkData =
base64_decode(stripslashes($_POST['upload']));
	  	$wholeFile = "uploads/" .
stripslashes($_POST['filename']);

 			$of = fopen($wholeFile, 'a+') or
				die("FAIL - opening output file");

			if(fwrite($of, $chunkData) < 0)
				die("FAIL - writing file");

	  	echo strlen($chunkData);
	}
	else
	{
		die("FAIL - hash");
	}
?>
**********

The "postUrl" variable in uploadApp.java will need to be given a
different value, depending on your implementation. Also--I realize this
is nothing fancy. I am WELL aware of that. However, the last time I
tested it, I could upload a 2gb video file with a little bit of garbling
on the other end. Now that Base64 encoding is being employed (and
again--this part has NOT been tested!!), maybe it will get it across
without any garbling at all.

Note - the Java files have two caveats: First, they need to be compiled
into a *.jar and run from the user's machine or run as a SIGNED applet
from the server. Second, they are all included in a package named
"postmusic". This can be easily changed to whatever you would rather use
(or don't use packages--it's your call).

Again, I stress that this has not been tested since the addition of
Base64 encoding/decoding, and that I am well aware of the code's...
um... simplicity. However, last time I checked, it uploaded huge videos
with 90% accuracy. Hopefully, that encoding/decoding bubble wrap will
get the file parts across without incident (although Base64 is adding
quite a few bytes to be transferred beyond just the underlying data).

Use at your own risk. Hopefully, this will spark someone else to take
the algorithms a bit further. :) I may do so myself if I find time, but
I've been very busy with other projects lately [3].

Links:
	1. http://www.devx.com/java/Article/17679/0/page/3
	2. http://iharder.sourceforge.net/current/java/base64/
	3. http://sites.google.com/site/rexcrawler

HTH,


// Todd

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux