Hidden Gems in HTTP
-
Upload
ben-ramsey -
Category
Sports
-
view
7.642 -
download
2
description
Transcript of Hidden Gems in HTTP
![Page 1: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/1.jpg)
Hidden Gems in HTTPBen Ramsey ■ Code Works
![Page 2: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/2.jpg)
Why HTTP?
![Page 3: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/3.jpg)
Because you are a Web developer.
![Page 4: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/4.jpg)
HTTP is the Web.
![Page 5: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/5.jpg)
That’s all I have to say about that.
![Page 6: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/6.jpg)
Some properties of HTTP…
![Page 7: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/7.jpg)
■ A client-server architecture
■ Atomic
■ Cacheable
■ A uniform interface
■ Layered
■ Code on demand
![Page 8: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/8.jpg)
Now, what does that sound like?
![Page 9: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/9.jpg)
REST!
![Page 10: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/10.jpg)
And, that’s all I have to say about that, too.
![Page 11: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/11.jpg)
Our focus today…
![Page 12: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/12.jpg)
■ Methods you’ve never used
■ Status codes you didn’t know existed
■ Working with HTTP in PHP
![Page 13: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/13.jpg)
Methods you’ve never used…
![Page 14: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/14.jpg)
Well, not really never.
![Page 15: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/15.jpg)
■ You know GET
■ Retrieval of information
■ Transfers a representation of a resource from the server to the client
■ Safe & idempotent
GET
![Page 16: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/16.jpg)
GET /user/ramsey HTTP/1.1Host: atom.example.org
HTTP/1.1 200 OKDate: Tue, 22 Sep 2009 17:28:14 GMTServer: Apache/2.2.11 (Unix) DAV/2 PHP/5.3.0X-Powered-By: PHP/5.3.0Content-Length: 594Content-Type: application/atom+xml;type=entry
<?xml version="1.0" encoding="utf-8"?><entry xmlns="http://www.w3.org/2005/Atom" xml:base="http://atom.example.org/"> <title>ramsey</title> ...</entry>
![Page 17: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/17.jpg)
He just thinks he’s funny.
![Page 18: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/18.jpg)
Stop laughing. You’re just encouraging him.
![Page 19: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/19.jpg)
POST
■ You know POST
■ The body content should be accepted as a new subordinate of the resource
■ Append, annotate, paste after
■ Not safe or idempotent
![Page 20: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/20.jpg)
POST /user HTTP/1.1Host: atom.example.orgContent-Type: application/atom+xml;type=entryContent-Length: 474
<?xml version="1.0" encoding="utf-8"?><entry xmlns="http://www.w3.org/2005/Atom" xml:base="http://atom.example.org/"> <title>ramsey</title> ...</entry>
HTTP/1.1 201 CreatedDate: Tue, 22 Sep 2009 17:39:06 GMTServer: Apache/2.2.11 (Unix) DAV/2 PHP/5.3.0X-Powered-By: PHP/5.3.0Location: http://atom.example.org/user/ramseyContent-Length: 133Content-Type: text/html; charset=utf-8
<div> The content was created at the location <a href="/user/ramsey"> http://atom.example.org/user/ramsey </a></div>
![Page 21: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/21.jpg)
HEAD
■ Identical to GET, except…
■ Returns only the headers, not the body
■ Useful for getting details about a resource representation before retrieving the full representation
■ Safe & idempotent
![Page 22: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/22.jpg)
HEAD /content/1234.mp4 HTTP/1.1Host: atom.example.org
HTTP/1.1 200 OKDate: Tue, 22 Sep 2009 17:28:14 GMTServer: Apache/2.2.11 (Unix) DAV/2 PHP/5.3.0X-Powered-By: PHP/5.3.0Content-Length: 12334753Content-Type: application/mp4
![Page 23: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/23.jpg)
PUT
■ Opposite of GET
■ Storage of information
■ Transfers a representation of a resource from the client to the server
■ Not safe
■ Idempotent
![Page 24: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/24.jpg)
PUT /user/ramsey/ HTTP/1.1Host: atom.example.orgContent-Type: application/atom+xml;type=entryContent-Length: 594
<?xml version="1.0" encoding="utf-8"?><entry xmlns="http://www.w3.org/2005/Atom" xml:base="http://atom.example.org/"> <title>ramsey</title> ...</entry>
HTTP/1.1 200 OKDate: Tue, 22 Sep 2009 17:47:27 GMTServer: Apache/2.2.11 (Unix) DAV/2 PHP/5.3.0X-Powered-By: PHP/5.3.0Content-Length: 594Content-Type: application/atom+xml;type=entry
<?xml version="1.0" encoding="utf-8"?><entry xmlns="http://www.w3.org/2005/Atom" xml:base="http://atom.example.org/"> <title>ramsey</title> ...</entry>
![Page 25: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/25.jpg)
DELETE
■ Requests that the resource identified be removed from public access
■ Not safe
■ Idempotent
![Page 26: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/26.jpg)
DELETE /content/1234/ HTTP/1.1Host: example.org
HTTP/1.1 204 No ContentDate: Tue, 22 Sep 2009 18:06:37 GMTServer: Apache/2.2.11 (Unix) DAV/2 PHP/5.3.0X-Powered-By: PHP/5.3.0Content-Length: 0Content-Type: text/html; charset=utf-8
![Page 27: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/27.jpg)
What the hell are safe & idempotentmethods?
![Page 28: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/28.jpg)
Safe methods
■ GET & HEAD should not take action other than retrieval
■ These are considered safe
■ Allows agents to represent POST, PUT, & DELETE in a special way
![Page 29: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/29.jpg)
Idempotence
■ Side-effects of N > 0 identical requests is the same as for a single request
■ GET, HEAD, PUT and DELETE share this property
■ OPTIONS and TRACE are inherently idempotent
![Page 30: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/30.jpg)
Status codes you didn’t know existed
![Page 31: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/31.jpg)
■ Informational (1xx)
■ Successful (2xx)
■ Redirection (3xx)
■ Client error (4xx)
■ Server error (5xx)
![Page 32: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/32.jpg)
The look-before-you-leap request (LBYL)
![Page 33: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/33.jpg)
1. Client sends a request without a body and includes the Expect: 100-continue header and all other headers
2. Server determines whether it will accept the request and responds with 100 Continue (or a 4xx code on error)
3. Client sends the request again with the body and without the Expect header
![Page 34: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/34.jpg)
1
POST /content/videos HTTP/1.1Host: example.orgContent-Type: video/mp4Content-Length: 115910000Authorization: Basic bWFkZTp5b3VfbG9vaw==Expect: 100-continue
![Page 35: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/35.jpg)
2
HTTP/1.1 413 Request Entity Too LargeDate: Thu, 21 May 2009 23:05:15 GMTServer: Apache/2.2.11 (Unix) DAV/2 PHP/5.3.0X-Powered-By: PHP/5.3.0Content-Length: 0Connection: closeContent-Type: text/html
Failure state
![Page 36: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/36.jpg)
2
HTTP/1.1 100 ContinueDate: Thu, 21 May 2009 23:05:15 GMTServer: Apache/2.2.11 (Unix) DAV/2 PHP/5.3.0X-Powered-By: PHP/5.3.0Content-Length: 0Content-Type: text/html
Success state
![Page 37: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/37.jpg)
3
POST /content/videos HTTP/1.1Host: example.orgContent-Type: video/mp4Content-Length: 115910000Authorization: Basic bWFkZTp5b3VfbG9vaw==
{binary video data}
![Page 38: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/38.jpg)
4
HTTP/1.1 201 CreatedDate: Thu, 21 May 2009 23:05:34 GMTServer: Apache/2.2.11 (Unix) DAV/2 PHP/5.3.0X-Powered-By: PHP/5.3.0Content-Length: 119Content-Type: text/htmlLocation: http://example.org/content/videos/1234
<html><body><p>Video uploaded! Go <a href="http://example.org/content/videos/1234">here</a> to see it.</p></body></html>
![Page 39: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/39.jpg)
The created at another location response
![Page 40: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/40.jpg)
1
POST /content/videos HTTP/1.1Host: example.orgContent-Type: video/mp4Content-Length: 115910000Authorization: Basic bWFkZTp5b3VfbG9vaw==
{binary video data}
![Page 41: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/41.jpg)
2
HTTP/1.x 201 CreatedDate: Thu, 21 May 2009 23:05:34 GMTServer: Apache/2.2.11 (Unix) DAV/2 PHP/5.3.0X-Powered-By: PHP/5.3.0Content-Length: 120Content-Type: text/htmlLocation: http://example.org/content/videos/1234
<html><body><p>Video uploaded! Go <a href="http://example.org/content/videos/1234">here</a> to see it.</p></body></html>
![Page 42: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/42.jpg)
The “it’s not you it’s me” response
![Page 43: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/43.jpg)
i.e. I’ve accepted it but might have to do more processing
![Page 44: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/44.jpg)
2
HTTP/1.x 202 AcceptedDate: Thu, 21 May 2009 23:05:34 GMTServer: Apache/2.2.11 (Unix) DAV/2 PHP/5.3.0X-Powered-By: PHP/5.3.0Content-Length: 137Content-Type: text/htmlLocation: http://example.org/content/videos/1234/status
<html><body><p>Video processing! Check <a href="http://example.org/content/videos/1234/status">here</a> for the status.</p></body></html>
![Page 45: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/45.jpg)
The “I have nothing to say to you” response…
![Page 46: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/46.jpg)
…but you were still successful
![Page 47: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/47.jpg)
1
DELETE /content/videos/1234 HTTP/1.1Host: example.orgAuthorization: Basic bWFkZTp5b3VfbG9vaw==
![Page 48: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/48.jpg)
2
HTTP/1.x 204 No ContentDate: Thu, 21 May 2009 23:28:34 GMT
![Page 49: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/49.jpg)
The ranged request
![Page 50: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/50.jpg)
■ Used when requests are made for ranges of bytes from a resource
■ Determine whether a server supports range requests by checking for the Accept-Ranges header with HEAD
![Page 51: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/51.jpg)
1
HEAD /2390/2253727548_a413c88ab3_s.jpg HTTP/1.1Host: farm3.static.flickr.com
![Page 52: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/52.jpg)
2
HTTP/1.0 200 OKDate: Mon, 05 May 2008 00:33:14 GMTServer: Apache/2.0.52 (Red Hat)Accept-Ranges: bytesContent-Length: 3980Content-Type: image/jpeg
![Page 53: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/53.jpg)
3
GET /2390/2253727548_a413c88ab3_s.jpg HTTP/1.1Host: farm3.static.flickr.comRange: bytes=0-999
![Page 54: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/54.jpg)
4
HTTP/1.0 206 Partial ContentDate: Mon, 05 May 2008 00:36:57 GMTServer: Apache/2.0.52 (Red Hat)Accept-Ranges: bytesContent-Length: 1000Content-Range: bytes 0-999/3980Content-Type: image/jpeg
{binary data}
![Page 55: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/55.jpg)
The GET me from another location response
![Page 56: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/56.jpg)
■ 303 See Other
■ The response to your request can be found at another URL identified by the Location header
■ The client should make a GET request on that URL
■ The Location is not a substitute for this URL
![Page 57: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/57.jpg)
1
POST /contact HTTP/1.1Host: example.orgContent-Type: application/x-www-form-urlencodedContent-Length: 1234
{url-encoded form values from a contact form}
![Page 58: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/58.jpg)
2
HTTP/1.1 303 See OtherDate: Tue, 22 Sep 2009 23:41:33 GMTServer: Apache/2.2.11 (Unix) DAV/2 PHP/5.3.0X-Powered-By: PHP/5.3.0Location: http://example.org/thankyouContent-Length: 0
![Page 59: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/59.jpg)
The find me temporarily at this place response
![Page 60: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/60.jpg)
■ 307 Temporary Redirect
■ The resource resides temporarily at the URL identified by the Location
■ The Location may change, so don’t update your links
■ If the request is not GET or HEAD, then you must allow the user to confirm the action
![Page 61: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/61.jpg)
The permanent forwarding address response
![Page 62: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/62.jpg)
■ 301 Moved Permanently
■ The resource has moved permanently to the URL indicated by the Location header
■ You should update your links accordingly
■ Great for forcing search engines, etc. to index the new URL instead of this one
![Page 63: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/63.jpg)
But what about just finding the resource at another location?
![Page 64: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/64.jpg)
■ 302 Found
■ The resource has been found at another URL identified by the Location header
■ The new URL might be temporary, so the client should continue to use this URL
■ Redirections SHOULD be confirmed by the user (in practice, browsers don’t respect this)
![Page 65: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/65.jpg)
The data validation error response
![Page 66: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/66.jpg)
■ 400 Bad Request
■ Generic error message
■ The client sent malformed syntax
■ The client needs to modify the request before sending it again (to fix errors)
![Page 67: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/67.jpg)
POST /user/ HTTP/1.1Host: atom.example.orgContent-Type: application/atom+xml;type=entryContent-Length: 474
<?xml version="1.0" encoding="utf-8"?><entry xmlns="http://www.w3.org/2005/Atom" xml:base="http://atom.example.org/"> <title>r@msey</title> ...</entry>
HTTP/1.1 400 Bad RequestDate: Tue, 22 Sep 2009 23:51:00 GMTServer: Apache/2.2.11 (Unix) DAV/2 PHP/5.3.0X-Powered-By: PHP/5.3.0Content-Length: 123Connection: closeContent-Type: text/html; charset=utf-8
<div class="error"> The following errors occurred: <ul> <li>Title contained invalid characters</li> </ul></div>
![Page 68: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/68.jpg)
But wait! There’s more…
![Page 69: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/69.jpg)
Working with HTTP in PHP
![Page 70: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/70.jpg)
■ header() functionhttp://php.net/header
■ Client URL library (cURL)http://php.net/curl
■ Streamshttp://php.net/streams
■ HTTP extension (pecl/http)http://php.net/http
![Page 71: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/71.jpg)
Questions?
■ My website is benramsey.com
■ @ramsey on Twitter
■ Rate this talk at joind.in
■ Read the HTTP spec attools.ietf.org/html/rfc2616
■ My company is Schematicschematic.com
![Page 72: Hidden Gems in HTTP](https://reader033.fdocuments.us/reader033/viewer/2022042813/540d3e418d7f72927e8b4909/html5/thumbnails/72.jpg)
Hidden Gems in HTTPCopyright © Ben Ramsey. Some rights reserved.
This work is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License.
For uses not covered under this license, please contact the author.