How to use PHP or any other language to read an uploading-file to allow download of the uploading-file while it is uploading?
Example sites that does this are:
http://www.filesovermiles.com/
http://host03.pipebytes.com/
Use this: http://www.php.net/manual/en/apc.configuration.php#ini.apc.rfc1867
In the array the file name is included as temp_filename - so you can pass that to your other program, which can read from the file and stream it live. The array also includes a file size so that program can make sure not to try to read beyond the end of the file.
I don't think this is possible in PHP because PHP takes care of receiving the download and only hands over control when it has the complete file. When writing CGI programs or Java servlets you read the upload from the socket so you are in control while receiving the file and you can administer if it is still uploading and how much has been received so another process could read this data and start sending what is already there.
One of the site's you've given as an example is just downloading a file from an URL or from the client computer, stores it temporarily and assigns a code to that file to make it identifiable.
After uploading, any other user who has the code can then download that file again.
This is more a question how you operate a server system then writing the code.
You can download files to the local system by making use of file_get_contents and file_put_contents.
If you want to stream file-data from the server to the browser, you can make use of readfile PHP Manual.
Related
My application is keeping watch on a set of folders where users can upload files. When a file upload is finished I have to apply a treatment, but I don't know how to detect that a file has not finish to upload.
Any way to detect if a file is not released yet by the FTP server?
There's no generic solution to this problem.
Some FTP servers lock the file being uploaded, preventing you from accessing it, while the file is still being uploaded. For example IIS FTP server does that. Most other FTP servers do not. See my answer at Prevent file from being accessed as it's being uploaded.
There are some common workarounds to the problem (originally posted in SFTP file lock mechanism, but relevant for the FTP too):
You can have the client upload a "done" file once the upload finishes. Make your automated system wait for the "done" file to appear.
You can have a dedicated "upload" folder and have the client (atomically) move the uploaded file to a "done" folder. Make your automated system look to the "done" folder only.
Have a file naming convention for files being uploaded (".filepart") and have the client (atomically) rename the file after upload to its final name. Make your automated system ignore the ".filepart" files.
See (my) article Locking files while uploading / Upload to temporary file name for an example of implementing this approach.
Also, some FTP servers have this functionality built-in. For example ProFTPD with its HiddenStores directive.
A gross hack is to periodically check for file attributes (size and time) and consider the upload finished, if the attributes have not changed for some time interval.
You can also make use of the fact that some file formats have clear end-of-the-file marker (like XML or ZIP). So you know, that the file is incomplete.
Some FTP servers allow you to configure a hook to be called, when an upload is finished. You can make use of that. For example ProFTPD has a mod_exec module (see the ExecOnCommand directive).
I use ftputil to implement this work-around:
connect to ftp server
list all files of the directory
call stat() on each file
wait N seconds
For each file: call stat() again. If result is different, then skip this file, since it was modified during the last seconds.
If stat() result is not different, then download the file.
This whole ftp-fetching is old and obsolete technology. I hope that the customer will use a modern http API the next time :-)
If you are reading files of particular extensions, then use WINSCP for File Transfer. It will create a temporary file with extension .filepart and it will turn to the actual file extension once it fully transfer the file.
I hope, it will help someone.
This is a classic problem with FTP transfers. The only mostly reliable method I've found is to send a file, then send a second short "marker" file just to tell the recipient the transfer of the first is complete. You can use a file naming convention and just check for existence of the second file.
You might get fancy and make the content of the second file a checksum of the first file. Then you could verify the first file. (You don't have the problem with the second file because you just wait until file size = checksum size).
And of course this only works if you can get the sender to send a second file.
I'm trying to serve a file for download to a user, and I'm having trouble with fpassthru. The function I'm using to download a file is:
http://pastebin.com/eXDpgUqq
Note that the file is successfully created from a blob, and is in fact the file I want the user to download. The script exits successfully, and reports no errors, but the file is not downloaded. I can't for the life of me think what's wrong.
EDIT: I removed the error suppression from fopen(), but it still reports no error. Somehow the data in the output buffer is never being told to be downloaded by the browser.
I tried your code (without the blob part), and it worked fine. I can download a binary file. Based on my experience, here are something to check:
Has the file been completely saved before you initiate the reading? Check the return value of file_put_contents.
How large is the file? fpassthru reads the whole file into memory. If the file is too large, memory might be insufficient. Please refer to http://board.phpbuilder.com/showthread.php?10330609-RESOLVED-php-driven-file-download-using-fpassthru for more information.
Instead of downloading the file to local server (reading the whole file into server’s memory, and letting the client download the file from the server), you can create an SAS URL, and simply redirect the browser to the URL. Azure will take care of download automatically. You many want to refer to http://blogs.msdn.com/b/azureossds/archive/2015/05/12/generating-shared-access-signature-sas-using-php.aspx for a sample.
I was able to download the file by passing a stream obtained with the Azure API directly to fpassthru, without creating a file. Unfortunately, I can't show the code because it belongs to a project that I have finished working on and the code is no longer available to me.
We are using Zend_Form inside a PHP application for building an input file html element. We can set the 'destination' of this element, and when calling receive() the file will be saved to the specified location.
We want to be able not to save the file to disc at all, but grab the file as a byte array and do something else with it.
Is this possible? If it is not possible with Zend_Form(), can it be done any other way?
EDIT: The reason why we cannot write to disc is because the application runs on Azure, and it seems that it does not have write access rights anywhere, not even in the temp folder. We get an exception from Zend saying that 'The given destination is not writeable'.
The only thing that seems viable would be to save the file using the php://memory protocol.
I've never had reason to implement but it looks a simple as setting the save location of the file to php://memory here is the link to the manual page PHP I/O Wrappers.
All PHP uploads are written to the file system regardless of using Zend or not (see upload_tmp_dir and POST method uploads).
Files will, by default be stored in the server's default temporary
directory, unless another location has been given with the
upload_tmp_dir directive in php.ini.
Instead of using receive to process the upload, try accessing it directly using the $_FILES array which would let you read the file into a string using file_get_contents() or similar functions. You can however, still use Zend_Form to create and handle the form in general.
You could set up shared memory upload_tmp_dir to map a filesystem to memory where uploaded files are held. Be cautious with this as if someone attempts to upload a very large file, it will go into memory which could affect performance or your cost of service.
Ultimately, Zend_File_Transfer_Adapter_Http::receive() calls move_uploaded_file() to move the file from its temporary location to the permanent location. In addition it makes sure the upload is valid and filters it, and marks it as received so it cannot be moved again (as that would fail).
I have a file located on my server and I want to remotely access that file from another server and execute source code of the file from another PHP file located on the another server.
I have had a look at “File_get_contents” however this only obtains the content displayed by that PHP file, as can be seen below.
So therefore is it possible for a PHP file from an external server to read the source code of the PHP file located on my server and execute the commands on the external server?
You can use an extension other than .php for the source file, then use file_get_contents (or similar) to retrieve the contents.
Not using the php extensions will prevent PHP from parsing it as code, and just send it over as text instead.
However, that will also make the source readable to anyone who navigates to the file in a browser, as well as introducing a possible major vulnerability. You should look into why this is necessary and if it can be avoided somehow (perhaps calling the file on the other server with GET or POSTed parameters).
Is it possible in PHP to configure it to somehow not save files to disk at all? As a matter of fact, the best thing would be to get the script going before even reading the entire POST body. (Keeping my hopes high ;))
You can turn off file uploads via a configuration setting in PHP.
http://php.net/manual/en/ini.core.php#ini.file-uploads
PHP needs a place to temporarily store the files content for you to be able to interact with it through PHP - although, you don't have to do anything else other then access the temporary file to get the data:
$content = file_get_contents($_FILES["user_file"]["tmp_name"]);
From here on you can manipulate with the files content without having to move the uploaded file to another location before accessing it.
You can use HTTP PUT requests to directly upload a file. PHP will not handle the upload directly (e.g. set it up in $_FILES). Instead, you have to read the raw bytes from the php://input pseudo-url and from there can do whatever you want.
There's some details and examples here.