PHP miniwebsever file download - php

$httpsock = #socket_create_listen("9090");
if (!$httpsock) {
print "Socket creation failed!\n";
exit;
}
while (1) {
$client = socket_accept($httpsock);
$input = trim(socket_read ($client, 4096));
$input = explode(" ", $input);
$input = $input[1];
$fileinfo = pathinfo($input);
switch ($fileinfo['extension']) {
default:
$mime = "text/html";
}
if ($input == "/") {
$input = "index.html";
}
$input = ".$input";
if (file_exists($input) && is_readable($input)) {
echo "Serving $input\n";
$contents = file_get_contents($input);
$output = "HTTP/1.0 200 OK\r\nServer: APatchyServer\r\nConnection: close\r\nContent-Type: $mime\r\n\r\n$contents";
} else {
//$contents = "The file you requested doesn't exist. Sorry!";
//$output = "HTTP/1.0 404 OBJECT NOT FOUND\r\nServer: BabyHTTP\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n$contents";
function openfile()
{
$filename = "a.pl";
$file = fopen($filename, 'r');
$filesize = filesize($filename);
$buffer = fread($file, $filesize);
$array = array("Output"=>$buffer,"filesize"=>$filesize,"filename"=>$filename);
return $array;
}
$send = openfile();
$file = $send['filename'];
$filesize = $send['filesize'];
$output = 'HTTP/1.0 200 OK\r\n';
$output .= "Content-type: application/octet-stream\r\n";
$output .= 'Content-Disposition: attachment; filename="'.$file.'"\r\n';
$output .= "Content-Length:$filesize\r\n";
$output .= "Accept-Ranges: bytes\r\n";
$output .= "Cache-Control: private\n\n";
$output .= $send['Output'];
$output .= "Content-Transfer-Encoding: binary";
$output .= "Connection: Keep-Alive\r\n";
}
socket_write($client, $output);
socket_close ($client);
}
socket_close ($httpsock);
Hello, I am snikolov i am creating a miniwebserver with php and i would like to know how i can send the client a file to download with his browser such as firefox or internet explore i am sending a file to the user to download via sockets, but the cleint is not getting the filename and the information to download can you please help me here,if i declare the file again i get this error in my server
Fatal error: Cannot redeclare openfile() (previously declared in C:\User
s\fsfdsf\sfdsfsdf\httpd.php:31) in C:\Users\hfghfgh\hfghg\httpd.php on li
ne 29, if its possible, i would like to know if the webserver can show much banwdidth the user request via sockets, perl has the same option as php but its more hardcore than php i dont understand much about perl, i even saw that a miniwebserver can show much the client user pulls from the server would it be possible that you can assist me with this coding, i much aprreciate it thank you guys.

You are not sending the filename to the client, so how should it know which filename to use?
There is a drawback, you can provide the desired filename in the http header, but some browsers ignore that and always suggest the filename based on the last element in URL.
For example http://localhost/download.php?help.me would result in the sugested filename help.me in the file download dialogue.
see: http://en.wikipedia.org/wiki/List_of_HTTP_headers

Everytime you run your while (1) loop you declare openfile function. You can declare function only once. Try to move openfile declaration outside loop.

$httpsock = #socket_create_listen("9090");
if (!$httpsock) {
print "Socket creation failed!\n";
exit;
}
while (1) {
$client = socket_accept($httpsock);
$input = trim(socket_read ($client, 4096));
$input = explode(" ", $input);
$input = $input[1];
$fileinfo = pathinfo($input);
switch ($fileinfo['extension']) {
default:
$mime = "text/html";
}
if ($input == "/") {
$input = "index.html";
}
$input = ".$input";
if (file_exists($input) && is_readable($input)) {
echo "Serving $input\n";
$contents = file_get_contents($input);
$output = "HTTP/1.0 200 OK\r\nServer: APatchyServer\r\nConnection: close\r\nContent-Type: $mime\r\n\r\n$contents";
} else {
//$contents = "The file you requested doesn't exist. Sorry!";
//$output = "HTTP/1.0 404 OBJECT NOT FOUND\r\nServer: BabyHTTP\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n$contents";
$filename = "dada";
$file = fopen($filename, 'r');
$filesize = filesize($filename);
$buffer = fread($file, $filesize);
$send = array("Output"=>$buffer,"filesize"=>$filesize,"filename"=>$filename);
$file = $send['filename'];
$output = 'HTTP/1.0 200 OK\r\n';
$output .= "Content-type: application/octet-stream\r\n";
$output .= "Content-Length: $filesize\r\n";
$output .= 'Content-Disposition: attachment; filename="'.$file.'"\r\n';
$output .= "Accept-Ranges: bytes\r\n";
$output .= "Cache-Control: private\n\n";
$output .= $send['Output'];
$output .= "Pragma: private\n\n";
// $output .= "Content-Transfer-Encoding: binary";
//$output .= "Connection: Keep-Alive\r\n";
}
socket_write($client, $output);
socket_close ($client);
}
socket_close ($httpsock);

Related

Rename file from incoming http POST using php

I am trying to rename a file that I am accepting via http POST. Please see the code:
<?php
$xmlData = fopen('php://input' , 'rb');
while (!feof($xmlData)) { $xmlString .= fread($xmlData, 4096); }
fclose($xmlData);
file_put_contents('temp/message' . date('m-d-y') . '-' . time() . '.xml', $xmlString, FILE_APPEND);
$xml = new SimpleXMLElement($xmlString);
$id = trim($xml->MSG->ID);
$receiver = trim($xml->MSG->RECEIVER);
$message = trim($xml->MSG->MESSAGE);
$sender = trim($xml->MSG->SENDER);
$binary = trim($xml->MSG->BINARY);
$sent = trim($xml->MSG->SENT);
foreach ($xml->{'line-items'}->{'line-item'} as $lineItem) {
array_push($messageTitles, trim($lineItem->title));
}
header('HTTP/1.0 200 OK');
exit();
Now I am at a slight loss at how to rename this?
You don't even need to save the file in order to process the XML tree. So you can process the file and move the file_put_contents(...) at the end.
<?php
$xmlData = fopen('php://input' , 'rb');
while (!feof($xmlData)) { $xmlString .= fread($xmlData, 4096); }
fclose($xmlData);
$xml = new SimpleXMLElement($xmlString);
$id = trim($xml->MSG->ID);
$receiver = trim($xml->MSG->RECEIVER);
$message = trim($xml->MSG->MESSAGE);
$sender = trim($xml->MSG->SENDER);
$binary = trim($xml->MSG->BINARY);
$sent = trim($xml->MSG->SENT);
foreach ($xml->{'line-items'}->{'line-item'} as $lineItem) {
array_push($messageTitles, trim($lineItem->title));
}
file_put_contents("temp/$receiver.xml", $xmlString, FILE_APPEND); // warning: security issue here
header('HTTP/1.0 200 OK');
exit();
Please note that you should enforce security restrictions to prevent the user from naming your file with an arbitrary name.

my CSV attachment is empty! PHP [duplicate]

This question already has an answer here:
PHP attachment in email is empty
(1 answer)
Closed 9 years ago.
Im trying to take data from the database and display it in a CSV file which is both downloadable and emailed to someone. I have managed to get the downloadable file working and it displays all of the correct data. It also sends a CSV file to the necessary person but that CSV file is empty and no data is displayed in it.
Here is my code:
$myroot = "../../";
include($myroot . "inc/functions.php");
// output headers so that the file is downloaded rather than displayed
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=surveys.csv');
$output = fopen('php://output', 'w');
// Create CSV file
fputcsv($output, array('Name', 'Branch', 'Website','Company', 'Question1', 'Question2', 'Question3', 'Question4', 'Question5'));
$mysql_connection = db_connect_enhanced('*****','*****','*****','*****');
$query='SELECT * FROM *****.*****';
$surveys = db_query_into_array_enhanced($mysql_connection, $query);
$count = count($surveys);
$data = array();
for($i=0; $i<=$count; $i++){
$data[] = array($surveys[$i]['FeedbackName'], $surveys[$i]['BranchName'], $surveys[$i]['FeedbackWebsite'], $surveys[$i]['FeedbackCompany'], $surveys[$i]['Question1'], $surveys[$i]['Question2'], $surveys[$i]['Question3'], $surveys[$i]['Question4'], $surveys[$i]['Question5']);
}
foreach( $data as $row )
{
fputcsv($output, $row, ',', '"');
}
fclose($output);
$encoded = chunk_split(base64_encode($output));
// create the email and send it off
$subject = "File you requested from RRWH.com";
$from = "*****#*****.com";
$headers = 'MIME-Version: 1.0' . "\n";
$headers .= 'Content-Type: multipart/mixed;
boundary="----=_NextPart_001_0011_1234ABCD.4321FDAC"' . "\n";
$message = '
This is a multi-part message in MIME format.
------=_NextPart_001_0011_1234ABCD.4321FDAC
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
Hello
We have attached for you the PHP script that you requested from http://rrwh.com/scripts.php
as a zip file.
Regards
------=_NextPart_001_0011_1234ABCD.4321FDAC
Content-Type: application/octet-stream; name="';
$message .= "surveys.csv";
$message .= '"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="';
$message .= "surveys.csv";
$message .= '"
';
$message .= $encoded;
$message .= '
------=_NextPart_001_0011_1234ABCD.4321FDAC--
';
mail("*****#*****.com", $subject, $message, $headers, "-f$from");
I've spent a day and a half on this but I cant see the problem. Could someone please point it out to me as to why the attached CSV file is empty?
i'm getting kind of desperate and stressed out :( please someone help me.
base64_encode() expects the parameter to be a string and you give it a (closed) resource.
Try to read the resource into a string, or use file_get_contents or build your string while you write into the resource.
Update:
Try and replace
foreach( $data as $row )
{
fputcsv($output, $row, ',', '"');
}
fclose($output);
$encoded = chunk_split(base64_encode($output));
by
$myoutput = '"Name","Branch","Website","Company","Question1","Question2","Question3","Question4","Question5"';
foreach( $data as $row )
{
$myoutput .= "\"".implode('","',$row)."\"\n";
fputcsv($output, $row, ',', '"');
}
fclose($output);
$encoded = chunk_split(base64_encode($myoutput));
This way, everything you write into your output you also write into a new variable ($myoutput). Since this is a string you can use it with base64_encode().

WebSocket: sending data server to client not working

I made a simple php code to test WebSocket, the client connects without problems, could receive data without probemas, but I can not send data from server to client, please correct my code to work, thanks
server.php
$in = '';
$content = '';
$connected = 0;
while($in != "quit"){
if(!$connected){
$in=trim(fgets(STDIN));
$pos = strpos($in, 'Sec-WebSocket-Key:');
if($pos !== false){
$key = str_replace('Sec-WebSocket-Key: ','',$in);
$magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
$resp = shell_exec("echo -n $key$magic | openssl sha1 -binary | base64");
}
if($in == ""){
$head = "HTTP/1.1 101 Switching Protocols\r\n";
$head.= "Connection: Upgrade\r\n";
$head.= "Upgrade: websocket\r\n";
$head.= "Sec-WebSocket-Accept: $resp\r\n";
$head.= "\r\n";
echo $head;
$connected = 1;
}
}else{
sleep(3);
$hex = "810461626364"; //abcd
$byte = str_split($hex, 2);
$out = '';
foreach($byte as $b){
$out.= chr(hexdec($b));
}
echo $out;
}
}
type in terminal:
ncat -l 12345 -c 'php -q server.php'
and connect the client to localhost:12345
solved, it was not working because it had two line breaks after the response header, I changed this
$head.= "Sec-WebSocket-Accept: $resp\r\n";
$head.= "\r\n";
echo $head;
for this
$head.= "Sec-WebSocket-Accept: $resp\r\n";
echo $head;
and it worked.

Using PHP to read a web page with fsockopen(), but fgets is not working

Im using this code here: http://www.digiways.com/articles/php/httpredirects/
public function ReadHttpFile($strUrl, $iHttpRedirectMaxRecursiveCalls = 5)
{
// parsing the url getting web server name/IP, path and port.
$url = parse_url($strUrl);
// setting path to '/' if not present in $strUrl
if (isset($url['path']) === false)
$url['path'] = '/';
// setting port to default HTTP server port 80
if (isset($url['port']) === false)
$url['port'] = 80;
// connecting to the server]
// reseting class data
$this->success = false;
unset($this->strFile);
unset($this->aHeaderLines);
$this->strLocation = $strUrl;
$fp = fsockopen ($url['host'], $url['port'], $errno, $errstr, 30);
// Return if the socket was not open $this->success is set to false.
if (!$fp)
return;
$header = 'GET / HTTP/1.1\r\n';
$header .= 'Host: '.$url['host'].$url['path'];
if (isset($url['query']))
$header .= '?'.$url['query'];
$header .= '\r\n';
$header .= 'Connection: Close\r\n\r\n';
// sending the request to the server
echo "Header is: <br />".str_replace('\n', '\n<br />', $header)."<br />";
$length = strlen($header);
if($length != fwrite($fp, $header, $length))
{
echo 'error writing to header, exiting<br />';
return;
}
// $bHeader is set to true while we receive the HTTP header
// and after the empty line (end of HTTP header) it's set to false.
$bHeader = true;
// continuing untill there's no more text to read from the socket
while (!feof($fp))
{
echo "in loop";
// reading a line of text from the socket
// not more than 8192 symbols.
$good = $strLine = fgets($fp, 128);
if(!$good)
{
echo 'bad';
return;
}
// removing trailing \n and \r characters.
$strLine = ereg_replace('[\r\n]', '', $strLine);
if ($bHeader == false)
$this->strFile .= $strLine.'\n';
else
$this->aHeaderLines[] = trim($strLine);
if (strlen($strLine) == 0)
$bHeader = false;
echo "read: $strLine<br />";
return;
}
echo "<br />after loop<br />";
fclose ($fp);
}
This is all I get:
Header is:
GET / HTTP/1.1\r\n
Host: www.google.com/\r\n
Connection: Close\r\n\r\n
in loopbad
So it fails the fgets($fp, 128);
Is there a reason you aren't using PHP's built-in, enabled-by-default ability to fetch remote files using fopen?
$remote_page = file_get_contents('http://www.google.com/'); // <- Works!
There are also plenty of high-quality third-party libraries, if you need to do something like fetch headers without thinking too hard. Try Zend_Http_Client on for size.
The flaw is here:
$good = $strLine = fgets($fp, 128);
if(!$good)
{
echo 'bad';
return;
}
fgets() returns either a string on success, or FALSE on failure. However, if there was no more data to be returned, fgets() will return the empty string (''). So, both $good and $strLine are set to the empty string, which PHP will happily cast to FALSE in the if() test. You should rewrite as follows:
$strLine = fgets($fp, 128);
if ($strLine === FALSE) { // strict comparison - types and values must match
echo 'bad';
return;
}
There's no need for the double assignment, as you can test $strLine directly.

Are sockets so slow in PHP?

I'm using this code for sockets. Console says that the page is processed for a very small amount of time, but Chrome says that page is loading for ~1 second!
$this->serv_sock = socket_create(AF_INET, SOCK_STREAM, 0);
socket_bind($this->serv_sock, $this->serv, $this->port) or die("Could not bind to address\n");
socket_listen($this->serv_sock);
while (1) {
echo "Waiting...\n";
$client = socket_accept($this->serv_sock);
$start_mtime = microtime(true);
echo "Accepted at ".$start_mtime.".\n";
$input = '';
$len = 0;
do {
//echo "Reading.\n";
$inp = socket_read($client, 1024);
$input .= $inp;
if (strpos($input, "\n\n") === false && strpos($input, "\r\n\r\n") === false)
continue;
if (!$len) {
if (!preg_match("/Content-Length: (\d+)/", $input, $matches)) {
break;
}
$len = $matches[1];
if (!$len)
break;
echo "We want $len bytes.\n";
}
if (strpos($input, "\n\n") !== false)
list($headers, $content) = explode("\n\n", $input);
else
list($headers, $content) = explode("\r\n\r\n", $input);
if (strlen($content) >= $len)
break;
} while ($inp);
echo "Calling callback as ".microtime(true).".\n";
if (strpos($input, "\n\n") !== false)
list($headers, $content) = explode("\n\n", $input);
else
list($headers, $content) = explode("\r\n\r\n", $input);
$output = $this->translate($callback, $headers, $content); // nothing slow here
$time_end = microtime(true);
echo "Sending output at ".$time_end." (total ".($time_end - $start_mtime).")\n\n";
$output = "HTTP/1.0 Ok\n".
"Content-Type: text/html; charset=utf-8\n".
"Content-Length: ".strlen($output)."\n".
"Connection: close\n\n".
$output;
socket_write($client, $output);
socket_close($client);
}
If I understand what you're saying. As far as I know there is a difference between server processing time and client processing time.
The time it actually takes to process the information on the server will always be less. Once the server finishes processing the information the data still has to be sent to the browser and has to be rendered. The time for the data to get there and for the browser to render is what I'm suspecting the reason is as to why Chrome is telling you it's taking ~1 second.

Categories