CakePHP and HTTP/1.1

Most probably didn’t even know that Cake internally switched from HTTP/1.0 (cake1.x) to HTTP/1.1 (cake2.x).
While most changes regarding the new specification are great, they can also break existing functionality, of course.

New features

With the new protocol there are a few new features that can be used now in Cake:

Caching improvements

Conditional view rendering is one of the new features possible with HTTP/1.1 and a few new headers available now.

New status codes

Interesting is the new code 410 (Gone) which can be "used when a resource has been removed permanently from a server, and to aid in the deletion of any links to the resource".

Of course, it has a lot of other improvements over the old protocol, as well. You can read about them here.

file_get_contents() issues

In an external php file we need to get some data. This script is quite old and simply gets some serialized data from the main server:

$content = file_get_contents('http://mainserverurl.com/some/action/');

Now, with the upgrade to 2.x those scripts suddently take 15 seconds. We wondered what could be the cause of the issue – discovering that in HTTP/1.1 "all connections are considered persistent unless declared otherwise".

Client-side solution

According to this question and its answer here it is possible to still use file_get_contents:

$context = stream_context_create(array('http' => array('header' => 'Connection: close\r\n')));
$content = file_get_contents('http://mainserverurl.com/some/action/', false, $context);

You manually tell the server to close the connection after the retrieval.

Server-side solution

In our case, and since the script was also used by servers we do not directly control, we had to make our cake app send the appropriate header:

// inside our action:
$this->response->header('Connection: close');

You manually tell the client to close the connection after the retrieval.

So what do we learn from that?

Better don’t use unintelligent php methods in favor of curl or other approaches. But sometimes you are outside CakePHP (and therefore not able to use the HttpResponse class) and maybe not even able to use curl. Then it helps if you know how can get it working again, after all.

But even inside CakePHP there are classes and methods that don’t handle it – as they weren’t intended to be used for it. E.g. the File class also does not use the above approach, thus is probably not suitable for external files.
The Tools.HttpSocketLib, though, if "php" is used instead of "curl" or "cake" would handle it gracefully.

2 Comments

  1. How to use file_get_contents, where my function is protected by ACL adn access by http is denied.

    For example i have pdf documents mydomain.com/documents/info/1.pdf

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.