Sat, 24 May 2008 2:08 UTC
So, my first conference of this year’s conference “season” has come to a close, and as a wrap-up post for the conference, I’d like to do something a bit different. I’m not going to discuss the sessions I attended or talk about the keynotes. Instead, I’d like to approach this post from the community aspect.
As a speaker at conferences, what often interests me most is in meeting with people, making new friends, and catching up with those I only get to see a few times a year (if that many) at conferences. I’m fortunate to have played a small role in helping to start and keeping alive the PHP Community project through the #phpc IRC channel on Freenode, and it is the members of the Community that I’m so proud to see attending conferences, taking initiative in organizing impromptu extra-curricular events at conferences, and even welcoming in new faces and new ideas. The Community ranges from end-users of PHP to core developers who take part in making decisions regarding the future of our beloved language.
At this year’s php|tek, I saw the Community come together in an exciting way, and, really, I think they provided a lot of the energy and enthusiasm that took us through the whole week, getting even the other attendees excited about the things going on at the conference and in the greater PHP community. From Christian Flickinger’s homemade buttons to Damien Seguy’s new batch of PHP and Oracle elePHPants to the #phptek channel on Freenode to tons and tons of Twitter updates to nightly trips to Shoeless Joe’s (and even the conference meme of changing the name of the bar on each new tweet), the Community played a large part in providing the conference with a fun and exciting atmosphere, and I commend Marco, Sean, Paul, and Arbi at php|architect for allowing and even encouraging the Community to involve themselves in this way. You guys truly rock!
The Community members who attend are really the unsung heroes of the conference, in my opinion. They aren’t necessarily speakers (though some are). They aren’t the PHP thought leaders (again, some are). Their companies don’t often pay their way to conferences. They make do however they can by organizing road trips, sharing rooms, etc. so that they can attend the conferences. I think this creates even more camaraderie and a closer bond between Community members. Without their presence, the conference dynamic would be terribly lacking.
So, while I’m now back home with my family, who I dearly missed while away, I raise my glass to the PHP Community members and to the organizers of php|tek. You know who you are. You all made this conference truly memorable for me.
Thank you, and I hope to see you again soon at another conference.
8 Comments »
Permalink
Tags: php-community, phpc, phpcommunity, phptek, tek08
Wed, 7 May 2008 2:08 UTC
The 200 range of HTTP status codes represents successful requests. I’ve already covered 201 Created and 202 Accepted and 206 Partial Content. Today, I’ll wrap up my discussion of the 200 range by talking about 204 No Content and 205 Reset Content. The 200 OK response is probably the status with which most are familiar, and I’ll discuss it later when covering the HTTP verbs.
The 204 No Content response is useful in a web service when you want to return a success message but do not want to return a message in the body or do not have a body to return. In my personal experience, I use this when DELETE requests are sent to an Atom web service. If the resource is successfully deleted, the service returns a 204 No Content status message. This tells the client that the deletion was successful, and that’s really all the client needs to know. There’s nothing to return because it was deleted.
However, even outside of the web services realm, the 204 No Content status actually means something to a user agent (browser). The HTTP specification (RFC 2616) states the following about the 204 No Content status code:
If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is primarily intended to allow input for actions to take place without causing a change to the user agent’s active document view, although any new or updated metainformation SHOULD be applied to the document currently in the user agent’s active view.
This means that, if I have an HTML form and submit it, then, if the server returns a 204 status code, the browser should not refresh the form or take me to another page. The document view does not change, and I remain at the form. All of the data I entered remains unchanged. All browsers I tested support this, but, in practice, it is not very useful since there’s no indication to a user that anything happened on the server side.
However, consider the use of 204 No Content in an Ajax application. If the Ajax library used simply looks for a success message of 204 in response to the requests it sends, then it can present a success message to the user without changing any of the UI elements, as this response intends. This is also useful because the service doesn’t need to send back any data; it needs only tell the client that the request was successful.
On the other hand, with a 205 Reset Content response, the intent is to tell the client to clear the content from the form or to refresh the UI. That is, I could fill out a form, click the submit button, and the form I am currently working on would refresh to its default values if the client receives a 205 response. According to the HTTP spec, a 205 response means:
The server has fulfilled the request and the user agent SHOULD reset the document view which caused the request to be sent. This response is primarily intended to allow input for actions to take place via user input, followed by a clearing of the form in which the input is given so that the user can easily initiate another input action.
The problem is that I have not found a browser yet that supports this behavior. Browsers either treat a 205 like it’s a 204, or they simply treat it as a 200. This does not mean, though, that Ajax applications cannot properly respect a 205 response. In an Ajax application, if the client receives a 205 response (instead of a 204 response), then the UI elements should change back to their default state.
In RESTful Web Services, Richardson and Ruby make this distinction between 204 and 204:
In data entry terms: 204 is good for making a series of edits to a single record; 205 is good for entering a series of records in succession.
In my simple browser test to see what browsers supported 204 and 205 on forms (without using any Ajax), here’s what I found:
Firefox 2.0.0.14
- 204 - supported
- 205 - treated like 204
Safari 3.1.1
- 204 - supported
- 205 - treated like 200
Opera 9.27
- 204 - supported
- 205 - treated like 200
Internet Explorer 7 (7.0.5730.13)
- 204 - supported
- 205 - treated like 200
Internet Explorer 8 beta 1 (8.0.6001.17184)
- 204 - supported
- 205 - treated like 200
Firefox 3 beta 5
- 204 - supported
- 205 - treated like 204
Since I know I’ll be asked this question, to send back a 204 or 205 response with PHP, see the PHP manual on the use of the header() function.
3 Comments »
Permalink
Tags: http, rest, rfc2616, standards
Mon, 5 May 2008 2:17 UTC
Akki commented on my 100 Continue post, asking:
I was wondering if there was a response status to allow a large file to be “served” in parts and in just one response?
While I’ve never done this myself, I did some research to see how it might be done, and I’ve come up with a solution that I wish I could call clever, innovative, and many other words that make me sound like I came up with a smart solution, but the reality of it is that HTTP was made to support this behavior, so I’ll just tell you how to do it with standard HTTP.
First of all, let’s create a scenario. Say I want to request a very large file from a service, but before I do so, I want to find out exactly how large it is and whether the service supports “range requests.” To do this, I make a HEAD request to the large resource I want to retrieve. The HEAD method is a standard HTTP method that acts as if I’ve made a GET request, but it returns only the headers and not the body. This allows me to find out some information about the resource without actually taking the time or using the bandwidth to download it. For example, I can read the Content-Length header and determine the size of the resource.
Another header of great importance is the Accept-Ranges header. If it’s present, it may contain a value of “bytes.” If so, I know that I can make a GET request and request a byte range to retrieve only those bytes. This is the first important key component:
If you are building a service that accepts byte range requests, let clients know by providing the Accept-Ranges header in response to GET and HEAD requests.
So, now, I know I can make a range request to the service, which I do by sending a standard GET request including a Range header that specifies the range of bytes I’m requesting, like so: Range: bytes=0-999. The service should then respond with with a 206 Partial Content status code, a Content-Range header, and the requested range of bytes. This is the second key component:
If a client makes a request of your service with a Range header, return a 206 Partial Content response containing a Content-Range header and the requested range of bytes for the resource in the body. The Content-Length value should be the length of what is actually returned and not the full length of the resource.
From then on, it’s a matter of the client continuing to make requests until it has retrieved all of the bytes it wishes to get from the resource. If the client makes a range request that is out of bounds—that is, none of the range values overlap the extent of the resource—the service should respond with a 416 Requested Range Not Satisfiable status.
I should note that the service cannot force the client to make a range request. It is entirely up to the client to make such requests, so the service should honor all standard GET requests that do not contain a Range header by sending back the full representation of the requested resource. If your service allows range requests, it is to your benefit to tell the client with an Accept-Ranges header. If you want to explicitly tell the client that you do not allow range requests, send a value of “none” back with the Accept-Ranges header.
Since I learn best by looking at real-life examples, I’ll provide one for you. Here’s a real example making range requests with Flickr. I’ve removed some of the headers for simplicity and clarity.
HEAD /2390/2253727548_a413c88ab3_s.jpg HTTP/1.1
Host: farm3.static.flickr.com
HTTP/1.0 200 OK
Date: Mon, 05 May 2008 00:33:14 GMT
Server: Apache/2.0.52 (Red Hat)
Accept-Ranges: bytes
Content-Length: 3980
Content-Type: image/jpeg
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GET /2390/2253727548_a413c88ab3_s.jpg HTTP/1.1
Host: farm3.static.flickr.com
Range: bytes=0-999
HTTP/1.0 206 Partial Content
Date: Mon, 05 May 2008 00:36:57 GMT
Server: Apache/2.0.52 (Red Hat)
Accept-Ranges: bytes
Content-Length: 1000
Content-Range: bytes 0-999/3980
Content-Type: image/jpeg
{binary data}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GET /2390/2253727548_a413c88ab3_s.jpg HTTP/1.1
Host: farm3.static.flickr.com
Range: bytes=1000-
HTTP/1.0 206 Partial Content
Date: Mon, 05 May 2008 00:37:54 GMT
Server: Apache/2.0.52 (Red Hat)
Accept-Ranges: bytes
Content-Length: 2980
Content-Range: bytes 1000-3979/3980
Content-Type: image/jpeg
{binary data}
3 Comments »
Permalink
Tags: http, rest, rfc2616, standards