Friday, November 07, 2008

Meta Refresh and Referrer Problem

Hi All,

Just came around the problem that when meta refresh is used referrer is cleared by Firefox, IE and some other browser. Just tested on firefox it cleared. The scenario for me is i have to redirect the user after few second, so i used meta refresh, but client complaint he is not getting referrer. So came up with the quick small javascript code.

// delay parameter is in sec.
// url paramter should be full url including http://
// example usage: delayRedirect(2,'http://localhost/test/referrer.php');
function delayRedirect(delay, url)
{
var delaySec = delay * 1000;
setTimeout("window.location.href='"+url+"'",delaySec);
}

Thursday, October 23, 2008

Turn OFF Caching for specific file with the help of .htaccess

Was just searching how to turn off cache for some of the file got the code so thought of sharing with you guys.

<# Files ansarahmed.css #>
<# IfModule mod_headers.c #>
Header set Cache-Control "must-revalidate"
<# /IfModule #>
<# /Files #>

Note:- Please remove hashes(#). Blogger is not allowing me to post the code sorry.

Monday, October 13, 2008

Outputting CSV as a Downloadable File in PHP

Nearly every application you could write in for the business sphere in PHP probably requires some sort of data export, most likely in the CSV format.

The easiest way to provide a downloadable file is by altering the headers and echo'ing the file content. In our case:

header("Content-type: text/csv");
header("Cache-Control: no-store, no-cache");
header('Content-Disposition: attachment; filename="filename.csv"');

We want to set our applicable Content-Type so that the browsers associate the file properly. Just relying on the extension doesn't work, even in Windows. The magic is in the third header setting, "Content-Disposition," which informs the browser to download as a separate file (don't open a new window and display a blank page, just display the file download box) and tell the browser the filename is "filename.csv". This way rewrite rules like http://localhost/export/csv/ will result in a download box that declares the file "filename.csv" rather than a randomly assigned name or whatever the current url is.

Into the meat of the CSV export. At the very beginning we need to open up a stream to the PHP output (the same place where echo sends its string content, which is NOT stdout):

$outstream = fopen("php://output",'w');


Next we're going to assume you already have your data packed nicely into an array (or array of arrays) so long as we have a single array per row/line.

The magic comes into play using the build in PHP function fgetcsv(). fgetcsv() takes an array for a single row and outputs it, automatically escaping output according to column and enclosure delimiters!

fgetcsv() requires a file resource as its first parameter and the magic of PHP streams is they act like a file resource (actually a file resource is just a file stream), so we give it $outstream to make fputcsv() echo its output. We fill in the rest of the parameters according to the php.net documentation and voila we have:

header("Content-type: text/csv");
header("Cache-Control: no-store, no-cache");
header('Content-Disposition: attachment; filename="filename.csv"');

$outstream = fopen("php://output",'w');

$test_data = array(
array( 'Cell 1,A', 'Cell 1,B' ),
array( 'Cell 2,A', 'Cell 2,B' )
);

foreach( $test_data as $row )
{
fputcsv($outstream, $row, ',', '"');
}

fclose($outstream);

For more output stream craziness, zaemis from the #phpc IRC channel on freenode shared a code snipped that outputs CSV either to the output buffer OR will return it as a string using some clever streams hackery:

function exportCSV($data, $col_headers = array(), $return_string = false)
{
$stream = ($return_string) ? fopen ('php://temp/maxmemory', 'w+') : fopen ('php://output', 'w');

if (!empty($col_headers))
{
fputcsv($stream, $col_headers);
}

foreach ($data as $record)
{
fputcsv($stream, $record);
}

if ($return_string)
{
rewind($stream);
$retVal = stream_get_contents($stream);
fclose($stream);
return $retVal;
}
else
{
fclose($stream);
}
}

Saturday, October 11, 2008

Filter Extension and Function in PHP

Was just going through the ppt and sample code of Tony Bibbs talk on about injection flaws, Cross Site Scripting (CSS) and Cross Site Request Forgeries (CSRF) given by him in Information Security Office (ISO), Came to know about useful Filter Function and Extension(This extension serves to validate and filter data coming from some insecure source, such as user input. ) in PHP.

Find the code and use of Filter function in action in below link
http://devzone.zend.com/node/view/id/1113

Find the documentation in below link
http://www.php.net/manual/en/intro.filter.php

Friday, September 19, 2008

Monday, September 15, 2008

History of the browser user-agent string

By Aaron Andersen..

In the beginning there was NCSA Mosaic, and Mosaic called itself NCSA_Mosaic/2.0 (Windows 3.1), and Mosaic displayed pictures along with text, and there was much rejoicing.

And behold, then came a new web browser known as “Mozilla”, being short for “Mosaic Killer,” but Mosaic was not amused, so the public name was changed to Netscape, and Netscape called itself Mozilla/1.0 (Win3.1), and there was more rejoicing. And Netscape supported frames, and frames became popular among the people, but Mosaic did not support frames, and so came “user agent sniffing” and to “Mozilla” webmasters sent frames, but to other browsers they sent not frames.

And Netscape said, let us make fun of Microsoft and refer to Windows as “poorly debugged device drivers,” and Microsoft was angry. And so Microsoft made their own web browser, which they called Internet Explorer, hoping for it to be a “Netscape Killer”. And Internet Explorer supported frames, and yet was not Mozilla, and so was not given frames. And Microsoft grew impatient, and did not wish to wait for webmasters to learn of IE and begin to send it frames, and so Internet Explorer declared that it was “Mozilla compatible” and began to impersonate Netscape, and called itself Mozilla/1.22 (compatible; MSIE 2.0; Windows 95), and Internet Explorer received frames, and all of Microsoft was happy, but webmasters were confused.

And Microsoft sold IE with Windows, and made it better than Netscape, and the first browser war raged upon the face of the land. And behold, Netscape was killed, and there was much rejoicing at Microsoft. But Netscape was reborn as Mozilla, and Mozilla built Gecko, and called itself Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.1) Gecko/20020826, and Gecko was the rendering engine, and Gecko was good. And Mozilla became Firefox, and called itself Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.7.5) Gecko/20041108 Firefox/1.0, and Firefox was very good. And Gecko began to multiply, and other browsers were born that used its code, and they called themselves Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.2) Gecko/20040825 Camino/0.8.1 the one, and Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.8) Gecko/20071008 SeaMonkey/1.0 another, each pretending to be Mozilla, and all of them powered by Gecko.

And Gecko was good, and IE was not, and sniffing was reborn, and Gecko was given good web code, and other browsers were not. And the followers of Linux were much sorrowed, because they had built Konqueror, whose engine was KHTML, which they thought was as good as Gecko, but it was not Gecko, and so was not given the good pages, and so Konquerer began to pretend to be “like Gecko” to get the good pages, and called itself Mozilla/5.0 (compatible; Konqueror/3.2; FreeBSD) (KHTML, like Gecko) and there was much confusion.

Then cometh Opera and said, “surely we should allow our users to decide which browser we should impersonate,” and so Opera created a menu item, and Opera called itself Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.51, or Mozilla/5.0 (Windows NT 6.0; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.51, or Opera/9.51 (Windows NT 5.1; U; en) depending on which option the user selected.

And Apple built Safari, and used KHTML, but added many features, and forked the project, and called it WebKit, but wanted pages written for KHTML, and so Safari called itself Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5, and it got worse.

And Microsoft feared Firefox greatly, and Internet Explorer returned, and called itself Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) and it rendered good code, but only if webmasters commanded it to do so.

And then Google built Chrome, and Chrome used Webkit, and it was like Safari, and wanted pages built for Safari, and so pretended to be Safari. And thus Chrome used WebKit, and pretended to be Safari, and WebKit pretended to be KHTML, and KHTML pretended to be Gecko, and all browsers pretended to be Mozilla, and Chrome called itself Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13, and the user agent string was a complete mess, and near useless, and everyone pretended to be everyone else, and confusion abounded.

Monday, September 01, 2008

Fast server-side rejection of large image uploads using $_FILES

Recently on his blog Cormac has posted a quick little tutorial on making things a bit faster when rejecting file uploads in PHP that are just a bit too large.

Discovered today you can report to a user if the file(s) he/she is uploading is too large without having to wait for the file to finish uploading by checking $_FILES - the $_FILES array for each form input of type “file” has an element called “error” which returns an error code without actually uploading the file if the file is larger than than upload_max_filesize in php.ini or $_POST["MAX_FILE_SIZE"]. It can do this because a “Content-length” http header is sent to the server first, and the file itself is then sent in the body of the http request.

Here’s a very simple example.

The form:

form enctype="multipart/form-data"
input type="hidden" name="MAX_FILE_SIZE" value="1048576"
input type="file" name="image"
input type="submit"
/form

The php:

if ($_FILES["image"]["error"] == UPLOAD_ERR_FORM_SIZE)
{
echo "file too big!";
}

Note that you shouldn’t just use MAX_FILE_SIZE as I’ve done above, you also need to set upload_max_filesize appropriately in php.ini

Friday, January 11, 2008

Use a custom php.ini with mod_php or php as a cgi

Describes in exhaustive detail how to change configuration settings and implement a custom php.ini file for use with the Apache Web Server.

PHP run as Apache Module (mod_php)

Add this to your root .htaccess file. Say your php.ini is in folder /askapache.com/ini/

SetEnv PHPRC /askapache.com/ini

Caching Techniques for Apache .htaccess Gurus

This article shows 2 awesome ways to implement caching on your website using Apache .htaccess (httpd.conf) files on the Apache Web Server. Both methods are extremely simple to set up and will dramatically speed up your site!

Apache .htaccess caching code

# 1 YEAR

Header set Cache-Control "max-age=29030400, public"

# 1 WEEK

Header set Cache-Control "max-age=604800, public"

# 2 DAYS

Header set Cache-Control "max-age=172800, proxy-revalidate"

# 1 MIN

Header set Cache-Control "max-age=60, private, proxy-revalidate"

For fail-safe code implement this to the above


# any Expires Directives go here



# any Header directives go here

At least one of the 2 modules needs to be built into Apache; although they are included in the distribution, they are not turned on by default. To find out if the modules are enabled in your server, find the httpd binary and run httpd -l; this should print a list of the available modules. The modules we're looking for are mod_expires and mod_headers.

If they aren't available, and you have administrative access, you can recompile Apache to include them. This can be done either by uncommenting the appropriate lines in the Configuration file, or using the -enable-module=expires and -enable-module=headers arguments to configure (1.3 or greater).

Complete Article