Tag: PHP
Hacking CakePHP’s request_handler.php to accept Compressed XML
by someguy on Apr.03, 2009, under Uncategorized
Disclaimer: There are undoubtedly cleaner ways of accomplishing this task, which is why I didn’t consider submitting this code back to CakePHP. Feel free to take my problem and come up with your own better solution — this worked for me, and certainly there are others who could benefit from it.
I was having a rough time trying to figure out how I was going to get CakePHP to handle compressed input. In my case, it was from the OCS Inventory Agent, which outputs zlib compressed XML server inventory reports to the host of your choosing. I was essentially doing some REST work between the OCS client and CakePHP — and CakePHP was handing off the request to request_handler properly thanks to the very simple suggested Routes configuration. The problem was that request handler didn’t know what to do with the mime-type “application/x-compress” (i.e. zlib compression), never mind detect the xml inside it and then magically do what it does with plan text XML.
Patch is here. request_handler looks for the “application/x-compress” Content-Type, decompresses the input (POST), then uses simplexml_load_string to determine if the contents are XML since the other check is simply checking for an xml Content-Type. Then the content is turned into an instance of CakePHP’s Xml object, which is then assigned to the $data property of the controller automagically.
Thanks to this post for assistance with handling CRC’s since not all zlib compressed POSTs are created equally. Also thanks to the people who wrote wireshark, which saved me as I debugged HTTP headers in this endeavor.
PHP’s apache_note: Oft-overlooked gem
by someguy on May.09, 2006, under Uncategorized
Problem: You need to log cookies and you want to be able to tie your users to the sites they came from.
Solution: PHP’s apache_note and a little apache config tweak.
It goes something like this. Cookies are generally served when a user first visits a website. They can be used for all kinds of things, yes, even some of them evil. Typically, though, they allow a webmaster/sysadmin/etc. to do better user tracking than IP tracking alone. IP tracking is riddled with inherent problems - like proxies, IP Changes between sessions, etc.. Cookies have their own set of challenges, but modern browsers support them because they are an important web technology - especially when it comes to personalization. Back to the problem.
When a browser holds a cookie for a domain, it sends the value of that cookie with a web request. When the browser makes its first ever request to a new website, it has not yet been cookied. So, let’s say that you are the webmaster, and you wanted to see which parts of your site are being trafficked by people from a certain site that links to you. Well, even though you are uniquely cookieing users, it isn’t until the second request that you will get the cookie back, so even if you are logging the cookies that are coming in with requests — you can’t pull the lines in your logfile by cookie to see where users came from — because when the browser made the first request with all that valuable referrer information in it, it didn’t have a cookie!! Well hold on - here comes the magic (ok no magic, just someone’s good old fashioned open source kick-ass code to the rescue, Rasmus Lerdorf’s, I think). Enter PHP’s apache_note function.
“apache_note() is an Apache-specific function which gets and sets values in a request’s notes table.” What does this mean to you? You can write things to the apache logs on a per-request basis — like the cookie value you are setting. The code might look like this:
<?php
// tag every new visitor with a unique ID
$domain = ".mydomain.com";
if (isset($_COOKIE['ID'])) {
// add error handling here for evil cookie values - don’t ever trust user input!
apache_note(”CID”, $_COOKIE['ID']);
} else {
$randval = rand();
$id = md5($randval . time() . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']);
setcookie(”ID”, $id, time()+60*60*24*365*20, “/”, $domain, 0);
apache_note(”SENT_ID”, $id);
}
?>
And the matching apache config lines might look like:
LogFormat “%h %l %u %t “%r” %>s %b “%{Referer}i”
“%{User-Agent}i” %{CID}n %{SENT_ID}n” combined_with_cookies
CustomLog logs/www.mydomain.com-access_log
combined_with_cookies
Restart apache and now you’ll see you are capturing outgoing cookie id’s and the incoming id’s. No more referrers lost in the shuffle - you can confidently tell where users from site X are going on your site.