RSS - Latest posts Code Category

Home » Category » Code
2Apr
2011

Top Level Cookies in Opera for Custom Domain Names

For our local development at work we all use the same fake domain – helps with setting API keys and other things across the board and isn’t hard to setup whatever system any new developer might have. It also happens to be not a “.com”: www.local.bnt – which is nice for not confusing it with real sites.

While developing cross-subdomain authentication we suddenly realised that it didn’t work on Opera. After a bit of research it turns out that it’s not the setting of the cookie path (“.local.bnt”) that is the problem, but the way Opera checks which part of the domain name is the top level domain:

“Here at Opera we went for the rule-of-thumb method: When Opera is checking a cookie whose target domain matches certain criteriea (e.g. it is not a .com domain), we do a DNS name lookup for the target domain, to see if there is an IP address for that domain. If there is an IP address for the domain (e.g. example.no) we assume that the domain is a normal company domain, not a co.uk like domain, and therefore safe. If there is no IP address we assume that the domain is co.uk-like and therefore unsafe, and only allows the cookie to be set for the server that sent the cookie.”

So that’s the problem right there and with an easy fix once you know the above… However the whole article is worth a read as it does shed some light on the multiple problems related to top level domains and cookies.

If you want to keep your random local domain name make sure your hosts file contains not only your sub domains, but the main one as well even if it is not used directly.

127.0.0.1    www.local.bnt
127.0.0.1    local.bnt

Categories:

31Mar
2011

jQuery Multiple Events Without Default Behaviour

Sometimes you trip over the little things.

With several people working on the same page while we were recreating some JS functionality from scratch I’ve noticed one of my buttons suddenly stopped working. Scratched my head a bit, and for a minute thought that maybe it’s not having a “return false;” in my jQuery live() event handler.

Turned out though that it was actually one of the other developers actually putting a “return false;” in their event handler that just happened to target the same element…

Ideally we needed to propagate the event through a variable number of events but prevent the default behaviour of a link kicking in. preventDefault() to the rescue! :)

$('#tag').live('click', function(event){
    (...)
    event.preventDefault();
});

Now, before blindly applying this piece of code I’d encourage everyone to first read up on why “return false;” is evil. ;)

And for a quick reference here’s a table featured on a related StackOverflow question:

  stop propagation prevent default action prevent “same element” event handlers
return false X X  
preventDefault   X  
stopPropagation X    
stopImmediatePropagation X   X

Categories:

30Jan
2011

Enable delayed messages in Zend_Queue

The default Zend_Queue DB implementation unfortunately does not allow you to pass a timeout value when saving a message on the queue. However not all is lost and you can easily extend the standard Zend classes to add that functionality.

All you need is your own Db adapter and Queue class.

For the adapter you only need to overwrite the send() function. The highlighted code below is the only change to the original class (2 lines affected…). You could actually apply this without extending Zend_Queue, but this way will be easier if you ever need to update your Zend library.

<?php

class TS_Queue_Adapter_Db extends Zend_Queue_Adapter_Db {

    /**
     * Send a message to the queue
     *
     * @param  string     $message Message to send to the active queue
     * @param  Zend_Queue $queue
     * @param  Timestamp $timeout
     * @return Zend_Queue_Message
     * @throws Zend_Queue_Exception - database error
     */
    public function send($message, Zend_Queue $queue = null, $timeout = null){
        if ($this->_messageRow === null) {
            $this->_messageRow = $this->_messageTable->createRow();
        }

        if ($queue === null) {
            $queue = $this->_queue;
        }

        if (is_scalar($message)) {
            $message = (string) $message;
        }
        if (is_string($message)) {
            $message = trim($message);
        }

        if (!$this->isExists($queue->getName())) {
            require_once 'Zend/Queue/Exception.php';
            throw new Zend_Queue_Exception('Queue does not exist:' . $queue->getName());
        }

        $msg = clone $this->_messageRow;
        $msg->queue_id = $this->getQueueId($queue->getName());
        $msg->created = time();
        $msg->body = $message;
        $msg->md5 = md5($message);
        $msg->timeout = $timeout;

        try {
            $msg->save();
        } catch (Exception $e) {
            require_once 'Zend/Queue/Exception.php';
            throw new Zend_Queue_Exception($e->getMessage(), $e->getCode(), $e);
        }

        $options = array(
            'queue' => $queue,
            'data' => $msg->toArray(),
        );

        $classname = $queue->getMessageClass();
        if (!class_exists($classname)) {
            require_once 'Zend/Loader.php';
            Zend_Loader::loadClass($classname);
        }
        return new $classname($options);
    }
}

Your Queue class only needs to extend the send() function again to allow you to pass the timeout through. obviously you can use this class to add other functionality too.

<?php

class TS_Queue extends Zend_Queue {

	/**
	 * Send a message to the queue
	 *
	 * @param  mixed $message message
	 * @return Zend_Queue_Message
	 * @throws Zend_Queue_Exception
	 */
	public function send($message, $timeout = null){
		return $this->getAdapter()->send($message, null, $timeout);
	}
}

Categories:

25Dec
2010

Zend Application Resource Plugin Loading Issues

Admittedly thinking while feeling feverish is slightly impaired, but it took me a little while to figure this one out… Trying to integrate ZF 1.11 with Doctrine2 to as per this article, I was trying to be a smart-ass and use TS_Resource_EntityManager instead of the ugly looking TS_Resource_Entitymanager.

Unfortunately all this got me was this very unhelpful error:

Zend_Application_Bootstrap_Exception with message Resource
matching "entityManager" not found

It turns out that although the case of the resource name in the application.ini dosn’t really matter the class name does not like mixed case. So had to settle with TS_Resource_Entitymanager as the plugin name.

Categories:

9Dec
2010

PHP_AUTH_USER and PHP_AUTH_PW is null

Ok, so you’re trying to setup password protection on your website using HTTP authentication. Unfortunately despite the request for password working your authentication keeps failing. If you check the output of your script and the password and username variables are not populated as expected it will usually be for one of two reasons.

Working code example


$username = "expectedUsername";
$password = "expectedPassword";

if (!isset($_SERVER['PHP_AUTH_USER']) || $_SERVER['PHP_AUTH_USER'] != $username || $_SERVER['PHP_AUTH_PW'] != $password) {
  header('WWW-Authenticate: Basic realm=""');
  header('HTTP/1.0 401 Unauthorized');
  echo '>h2>Authorization failed.>/h2>';
  exit;
} else if($_SERVER['PHP_AUTH_USER'] != $username & $_SERVER['PHP_AUTH_PW'] != $password){
  echo '>h2>Authorization failed.>/h2>';
  exit;
}

Most common reason for failure

Firstly if you are using an older book or website as reference you will see $PHP_AUTH_USER mentioned instead of $_SERVER['PHP_AUTH_USER']. If you are using the former then this could be the reason for not seeing your variables populated.

The reason that can take you by surprise

If your code is correct (compare against the example) and you are using the $_SERVER variable format and still getting NULL inside both $_SERVER['PHP_AUTH_USER'] and $_SERVER['PHP_AUTH_PW'] it’s time to check your server settings.

HTTP authentication does not work with the cgi version of PHP, so if your hosting allows you will need to switch to PHP as Apache module or look for an alternative solution.

Categories: