> -----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