My situation is illustrated in the figure below:
I have a file X on the main server A which I want to download from my local computer B and the file X is downloadable through HTTP. But, for some reason I am not allowed to download file from the main server A. However, I have an access to another server C which has PHP installed.
I now want to download the file X via the server C by calling some PHP script on server C from my local computer B.
Is it possible to write one PHP script to do the above?
Any help in writing so will be highly appreciated.
I'm not completely sure of what you need but you can use the following script to act as proxy between 2 servers.
PUT THIS FILE ON SERVER C
phpProxy.php
<?php
$myPass = "Secr3t";
if( $myPass == $_GET['pass'] ){
$remoteFile = $_GET['rf'];
$filename = basename( $remoteFile );
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$filename\"");
echo file_get_contents( $remoteFile );
}
USE AS:
phpProxy.php?rf=http://phs.googlecode.com/files/Download%20File%20Test.zip&pass=Secr3t
NOTES:
1 - I've added a password otherwise the script is very unsafe!
2 - If possible, use https to avoid MITM
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
php How do I start an external program running - Having trouble with system and exec
how to open exe with php?
I had this idea and make hard to success it for several years,but failed at last. any one tell me a success method to do the job ?
<?php
if(isset($_POST['file_path'])){
/* -------
using "notepad++.exe" to open "test.php" file.
or run a bat file which calling "notepad++.exe" to open "test.php" file.
how to seting php.ini or firefox or any setting to do this job.
it is only for conveniently developing web page in my PC ,not for web servers
------- */
}
?>
<form action="test.php" method="post">
<input type="text" name="file_path" value="test.php"/>
<button type="submit">open with notepad++</button>
</form>
This would create something like:
To launch a program on the computer which runs the webserver:
<?php
exec('"C:\Program Files (x86)\Notepad++\notepad++.exe" "C:\foo.php"');
The above will work on vista/win7 IF the webserver does not run as a windows service. For example, if you run apache and it automatically starts when your computer boots, you probably installed it as a service. You can check to see if apache shows up in the windows services tab/thingy.
If the webserver runs as a service, you'll need to look into enabling the "allow desktop interaction" option for the service. But otherwise:
An easy test using php's new built in webserver(php 5.4+). The key thing here is you manually start the server from a shell, so it runs as your user instead of as a service.
<?php
// C:\my\htdocs\script.php
exec('"C:\Program Files (x86)\Notepad++\notepad++.exe" "C:\foo.php"');
start a webserver via a command window
C:\path\to\php.exe -S localhost:8000 -t C:\my\htdocs
Then in your browser
http://localhost:8000/script.php
I assume you are wanting the client device to open Notepad++ not the remote server. If this is the case, the best you can do is to serve up the file with the proper file type header and hope the client has Notepad ++ set up as the default application to open such a file.
Something like this should do it:
header('Content-type: text/plain');
header('Content-Disposition: attachment; filename="' . $file_name . '"'); // forces file download
header('Content-length: ' . filesize($file_path));
header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); // make sure file is re-validated each time it is requested
$fh = fopen($file_path, 'r');
while(!feof($fh)) {
$buffer = fread($fh, 2048);
echo $buffer;
}
fclose($fh);
Where $file_name is the name of the file (not the full path) and $file_path is the full path to the file
the finally successful way I tested.
thank Charles ,refer to php How do I start an external program running - Having trouble with system and exec
Start->Run, type "services.msc" to bring up Services control (other ways to get there, this is easiest IMO)
Locate your Apache service (mine was called "wampapache" using WampServer 2.0)
Open the service properties (double-click or right click->properties)
Flip to the Log On account and ensure the checkbox titled "Allow service to interact with Desktop" is checked
Flip back to the General tab, stop the service, start the service
then: in php
pclose(popen("start /B \"d:\\green soft\\notepad++5.8.4\\notepad++.exe\" \"d:\\PHPnow-1.5.6\\htdocs\\laji\\a.php\"", "r"));
Thank all your good guys, what a great help . I had finally made my idea to be true. Happy new year !
never had a reason to do so, but have you tried passthru() ?
http://php.net/manual/en/function.passthru.php
EDIT:
sorry the OP was really unclear at first glance..
what I would do is parse the file into a string or whatnot, then force the browser to treat that as a download.. php is server sided so you can`t only ask the browser to do some stuff..
$someText = 'some text here';
header('Content-type: text/plain');
header('Content-Disposition: attachment; filename="text.txt"');
echo $someText;
<?php
$youtubeUrl = "https://www.youtube.com/watch?v=Ko2JcxecV2E";
$content = json_encode ($file = shell_exec("youtube-dl.exe $youtubeUrl "));
$input_string =$content;
$regex_pattern = "/Destination:(.*.mp4)/";
$boolean = preg_match($regex_pattern, $input_string, $matches_out);
$extracted_string=$matches_out[0];
$file =explode(': ',$extracted_string,2)[1];
// Quick check to verify that the file exists
if( !file_exists($file) ) die("File not found");
// Force the download
header("Content-Disposition: attachment; filename=\"$file\"" );
header("Content-Length: " . filesize($file));
header("Content-Type: application/octet-stream;");
readfile($file);
?>
When I run this file the respective YouTube video is first downloaded to the localhost server folder where this PHP file is, using youtube-dl.exe and then it is pushed from that folder to browser download (forced download).
How to directly start the download to user's browser?
Also the file is running fine on localhost but not on remote server.
First, you need to use a version of youtube-dl for a platform of your webserver. The youtube-dl.exe is a build for Windows, while most webhostings use Linux.
Then use the passthru PHP function to run the youtube-dl with the -o - command-line parameter. The parameters makes youtube-dl output the downloaded video to its standard output, while the passthru passes the standard output to a browser.
You also need to output the headers before the the passthru. Note that you cannot know the download size in this case.
header("Content-Disposition: attachment; filename=\"...\"" );
header("Content-Type: application/octet-stream");
passthru("youtube-dl -o - $youtubeUrl");
If you need a video metadata (like a filename), you can run the youtube-dl first with the -j command-line parameter to get the JSON data without downloading the video.
Also you need 1) Python interpreter on the web server 2) to be able to use the passthru function 3) connectivity to YouTube from the PHP scripts. All these are commonly restricted on webhostings.
The trouble is probably within: shell_exec("youtube-dl.exe $youtubeUrl ")
Firstly, some hosts disable shell_exec for security reasons.
Secondly, youtube-dl.exe looks like it is probably a windows script, where as your remote server is probably Linux based.
I'm currently using the following PHP function to allow a user to select a file and then download it. This happens over FTP. However, if the user chooses a large file then while the download is occurring it locks up the server for any other requests. Is there any way I can host the file while having PHP continue to respond to requests?
I need PHP to verify that the user is permitted to download the file with their credentials so I can't just host it as an asset. The file is located on an FTP server.
function download($file) {
$fileStream = "";
if($this->get($file)) {
//Send header to browser to receive a file
header("Content-disposition: attachment; filename=\"$file\"");
header("Content-type: application/octet-stream");
header("Pragma: ");
header("Cache-Control: no-cache");
header("Expires: 0");
$data = readfile($this->downloadDir . $file);
$i=0;
while ($data[$i] != "")
{
$fileStream .= $data[$i];
$i++;
}
unlink($this->downloadDir . $file);
echo $fileStream;
exit;
} else {
return false;
}
}
PHP is not the best solution for this kind of work, but it can delegate the job to the web server you are using. And as the file is in the same place as your application, this can work.
All major web servers that usually run PHP applications (Apache, lighttpd and nginx) have all support for XSendfile.
To use it, you have to first enable the functionality in your web server (check the links above for each of the web servers), then in your script add a new header:
Apache:
header("X-Sendfile: $location_of_file_to_download");
Lighttpd:
header("X-LIGHTTPD-send-file: $location_of_file_to_download");
nginx:
header("X-Accel-Redirect: $location_of_file_to_download");
The web server will catch this header from your application, and will replace the body of your PHP response with the file. And while it servers this file to the user, the PHP gets unblocked and ready to server a new user.
(The other headers will be kept, so you can retain the content-type and content-disposition headers)
Since PHP is single-threaded, you would have to make a structure for each request. Then, instead of just processing one request at a time, you should loop through the structures and slowly process all of them concurrently (as in send a few hundred kb to one, then move onto the next, etc).
Honestly, PHP doesn't sound like the right language to do this job. Why not using a purpose built FTP server like vsftp or something of that nature?
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
php How do I start an external program running - Having trouble with system and exec
how to open exe with php?
I had this idea and make hard to success it for several years,but failed at last. any one tell me a success method to do the job ?
<?php
if(isset($_POST['file_path'])){
/* -------
using "notepad++.exe" to open "test.php" file.
or run a bat file which calling "notepad++.exe" to open "test.php" file.
how to seting php.ini or firefox or any setting to do this job.
it is only for conveniently developing web page in my PC ,not for web servers
------- */
}
?>
<form action="test.php" method="post">
<input type="text" name="file_path" value="test.php"/>
<button type="submit">open with notepad++</button>
</form>
This would create something like:
To launch a program on the computer which runs the webserver:
<?php
exec('"C:\Program Files (x86)\Notepad++\notepad++.exe" "C:\foo.php"');
The above will work on vista/win7 IF the webserver does not run as a windows service. For example, if you run apache and it automatically starts when your computer boots, you probably installed it as a service. You can check to see if apache shows up in the windows services tab/thingy.
If the webserver runs as a service, you'll need to look into enabling the "allow desktop interaction" option for the service. But otherwise:
An easy test using php's new built in webserver(php 5.4+). The key thing here is you manually start the server from a shell, so it runs as your user instead of as a service.
<?php
// C:\my\htdocs\script.php
exec('"C:\Program Files (x86)\Notepad++\notepad++.exe" "C:\foo.php"');
start a webserver via a command window
C:\path\to\php.exe -S localhost:8000 -t C:\my\htdocs
Then in your browser
http://localhost:8000/script.php
I assume you are wanting the client device to open Notepad++ not the remote server. If this is the case, the best you can do is to serve up the file with the proper file type header and hope the client has Notepad ++ set up as the default application to open such a file.
Something like this should do it:
header('Content-type: text/plain');
header('Content-Disposition: attachment; filename="' . $file_name . '"'); // forces file download
header('Content-length: ' . filesize($file_path));
header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); // make sure file is re-validated each time it is requested
$fh = fopen($file_path, 'r');
while(!feof($fh)) {
$buffer = fread($fh, 2048);
echo $buffer;
}
fclose($fh);
Where $file_name is the name of the file (not the full path) and $file_path is the full path to the file
the finally successful way I tested.
thank Charles ,refer to php How do I start an external program running - Having trouble with system and exec
Start->Run, type "services.msc" to bring up Services control (other ways to get there, this is easiest IMO)
Locate your Apache service (mine was called "wampapache" using WampServer 2.0)
Open the service properties (double-click or right click->properties)
Flip to the Log On account and ensure the checkbox titled "Allow service to interact with Desktop" is checked
Flip back to the General tab, stop the service, start the service
then: in php
pclose(popen("start /B \"d:\\green soft\\notepad++5.8.4\\notepad++.exe\" \"d:\\PHPnow-1.5.6\\htdocs\\laji\\a.php\"", "r"));
Thank all your good guys, what a great help . I had finally made my idea to be true. Happy new year !
never had a reason to do so, but have you tried passthru() ?
http://php.net/manual/en/function.passthru.php
EDIT:
sorry the OP was really unclear at first glance..
what I would do is parse the file into a string or whatnot, then force the browser to treat that as a download.. php is server sided so you can`t only ask the browser to do some stuff..
$someText = 'some text here';
header('Content-type: text/plain');
header('Content-Disposition: attachment; filename="text.txt"');
echo $someText;
I want to save a file from the online system and save it into specific,ex. C:/myFolder/. So,if in the C:/ there is no myFolder name,the system will automatically detect and create the folder in C drive, and save the file into that folder. When I try system locally, it can create the folder and the file into C drive.
But when it upload my file into the server, the folder was created within the server, not in the local computer. Can anyone help me how to solve this? how to create a folder in local computer and save file into that folder from online system?
Below is the code that works when the system runs locally:
$directory = 'C:/sales/'.$filename.'.txt';
$path_name = 'C:/sales/';
if ( ! is_dir($path_name)) {
mkdir($path_name);
}
if(mysql_num_rows($query))
{
$fp = fopen($directory, 'w');
if($fp)
{
for($i = 0; $i < mysql_num_rows($query); $i++)
{
$f = mysql_fetch_array($query);
$orderFee_q = mysql_query("select * from sales_order where status in ('waiting', 'waiting1', 'waiting2', 'approved') and outstanding = 'N' order by so_no desc");
$get_orderFee = mysql_fetch_array($orderFee_q);
$line = $f["id"]."\t".$f["so_no"];
if(trim($line) != '') {fputs($fp, $line."\r\n");}
}
}
fclose($fp);
}
$download_name = basename($filename);
if(file_exists($filename))
{
header('Content-Description: File Transfer');
header('Content-Type: application/force-download');
header('Content-Transfer-Encoding: Binary');
header("Content-Disposition: attachment; filename=".$download_name);
header('X-SendFile: '.$filename);
header('Pragma: no-cache');
header("Expires: 0");
readfile($filename);
}
Simply, you can't do that in php or any other server side language.
Edit:
Reason is simple server side application and scripts have access only to local resources where they are launched. So when you run your application on local computer, everything works as you wish for. But because of how HTTP works and because of safety reasons you cannot access user local files.
You could create a desktop application that interacts with your server, which would allow you to do something like this.
You can not tell the user where to save the file you sending. Even with JavaScript. Server Site languages can manipulata the files on the server, not on the client's machine, by defaylt.But anyway it is not possible to access client's files without the permision of the client. Possibly this could be done by an ActiveX component, but client should agree and accept this action. Otherwise untill now your computer would have more virusese than your files. So the browser makes a protected invironment for safe browsing. You have already set the name of the file you are sending ... so that's the max possible you can do server side.