Archive for June, 2009

Serving Office 2007 documents to IE Users with Apache

I encountered an issue downloading Office 2007 documents with IE. When downloaded IE would download them as ZIP files instead.

In reality, these are zip files. Our users need them to open in the correct application.

The solution was adding the new mime types to apache.
I was unaware that apache provides mime type info for each file served or that IE actually used that information.

Adding the following my apache config fixed the problem:

1
2
3
4
5
    #Types for the new office documents
    AddType application/vnd.openxmlformats-officedocument.wordprocessingml.document .docx
    AddType application/vnd.openxmlformats-officedocument.presentationml.presentation .pptx
    AddType application/vnd.openxmlformats-officedocument.spreadsheetml.sheet .xlsx
    AddType application/vnd.ms-xpsdocument .xps

References:
http://blogs.msdn.com/dmahugh/archive/2006/08/08/692600.aspx
http://httpd.apache.org/docs/2.2/mod/mod_mime.html#addtype

Send a file via POST with cURL and PHP

cURL is a great library. It can do just about anything that a normal web browser can do including send a file via a post request.

This makes it really easy to transmit files between computers. In my case, I was looking for an easy way to send images snapped by various webcam systems to a central server with php managing the images.

Here is a simple script to send a file with php/cURL via POST:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
	$target_url = 'http://127.0.0.1/accept.php';
        //This needs to be the full path to the file you want to send.
	$file_name_with_full_path = realpath('./sample.jpeg');
        /* curl will accept an array here too. 
         * Many examples I found showed a url-encoded string instead.
         * Take note that the 'key' in the array will be the key that shows up in the 
         * $_FILES array of the accept script. and the at sign '@' is required before the
         * file name.
         */
	$post = array('extra_info' => '123456','file_contents'=>'@'.$file_name_with_full_path);
 
        $ch = curl_init();
	curl_setopt($ch, CURLOPT_URL,$target_url);
	curl_setopt($ch, CURLOPT_POST,1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
	$result=curl_exec ($ch);
	curl_close ($ch);
	echo $result;
?>

And here is the corresponding script to accept the file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$uploaddir = realpath('./') . '/';
$uploadfile = $uploaddir . basename($_FILES['file_contents']['name']);
echo '<pre>';
	if (move_uploaded_file($_FILES['file_contents']['tmp_name'], $uploadfile)) {
	    echo "File is valid, and was successfully uploaded.\n";
	} else {
	    echo "Possible file upload attack!\n";
	}
	echo 'Here is some more debugging info:';
	print_r($_FILES);
	echo "\n<hr>\n";
	print_r($_POST);
print "</pr" . "e>\n";
?>

And that’s it.
Navigate to the ‘send’ script and it will transmit the file sample.jpeg to the accept script.

Note that you can include other arguments in the post along with the file. This allows you to authenticate the upload. I’m using pre-shared strings to ‘validate’ that upload came from my send script.

This works with the command line version of php too.

References:
http://us3.php.net/manual/en/function.move-uploaded-file.php
http://us3.php.net/manual/en/features.file-upload.post-method.php
http://curl.haxx.se/libcurl/php/examples/multipartpost.html
http://forums.devshed.com/php-development-5/php-curl-send-a-file-533233.html