http potpourri

75
HTTP Potpourri Kevin Hakanson Twin Cities Code Camp 12 14-15 April 2012

Upload: kevin-hakanson

Post on 10-May-2015

2.919 views

Category:

Technology


9 download

DESCRIPTION

Embracing HTTP is an important property of well constructed ReSTful and web apis. Every web developer is familiar with GET and POST, 200 and 404, Accept and Content-Type; but what about 207 and 413, OPTIONS and PROPFIND, Transfer-Encoding and X-File-Size? This session will be based on usage of various HTTP methods, headers and status codes drawn from the development of large scale, web applications. Examples will include raw HTTP, mixed in with JavaScript and ASP.NET MVC code.

TRANSCRIPT

Page 1: HTTP Potpourri

HTTP Potpourri

Kevin HakansonTwin Cities Code Camp 12

14-15 April 2012

Page 2: HTTP Potpourri

Are You In The Right Place?

● This talk:○ Embracing HTTP is an important property of well constructed ReSTful and web

apis. Every web developer is familiar with GET and POST, 200 and 404, Accept and Content-Type; but what about 207 and 413, OPTIONS and PROPFIND, Transfer-Encoding and X-File-Size? This session will be based on usage of various HTTP methods, headers and status codes drawn from the development of large scale, web applications. Examples will include raw HTTP, mixed in with JavaScript and ASP.NET MVC code.

● This speaker:○ Kevin Hakanson is an application architect for Thomson Reuters where he is

focused on highly scalable web applications. His background includes both .NET and Java, but he is most nostalgic about Lotus Notes. He has been developing professionally since 1994 and holds a Master’s degree in Software Engineering. When not staring at a computer screen, he is probably staring at another screen, either watching TV or playing video games with his family.

Page 3: HTTP Potpourri

Kevin Hakanson

@hakanson#tccc12

[email protected]

github.com/hakanson

stackoverflow.com/users/22514/kevin-hakanson

Page 4: HTTP Potpourri

What to Expect

●define:potpourri○ "A collection of various things; an assortment, mixed bag

or motley" - Wiktionary● "Based on a True Story"

○ derived from production code from large scale, web app○ combined with stackoverflow questions○ and a mix of web tutorials

● Combination of informational slides with highlights, screenshots, code samples and HTTP snippets

● Attempts at humor● Questions (OK during presentation)

Page 5: HTTP Potpourri

Tools and Technologies

● IE 10, Chrome 17, Firefox 11● Fiddler, Wireshark● curl (Git Bash)● Windows 8 Consumer Preview● Visual Studio 11 (beta)● ASP.NET MVC 4● Squid● Alt + PrtScr; Paint.NET● memegenerator.net● live co-worker audience

Page 6: HTTP Potpourri
Page 7: HTTP Potpourri

Methods

● RFC 2616, Section 9 defines these "methods" (the word "verb" does not appear in http://www.ietf.org/rfc/rfc2616.txt)○ OPTIONS, GET, HEAD, PUT, POST, DELETE, TRACE,

CONNECT● Only GET and POST work with <form method="">● Everything allowed with AJAX ● Sometimes you need X-HTTP-Method-Override

○ http://stackoverflow.com/questions/467535/is-it-possible-to-implement-x-http-method-override-in-asp-net-mvc

○ <%=Html.HttpMethodOverride(HttpVerbs.Delete) %>

○ <input name="X-HTTP-Method-Override" type="hidden" value="DELETE" />

Page 8: HTTP Potpourri

Headers

● HTTP header fields, which includehttp://www.w3.org/Protocols/rfc2616/rfc2616.html○ general-header (section 4.5)○ request-header (section 5.3)○ response-header (section 6.2)○ entity-header (section 7.1)

● Permanent Message Header Field Names○ http://www.iana.org/assignments/message-headers/perm-

headers.html

Page 9: HTTP Potpourri

Headers

● "Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is defined as a comma-separated list [i.e., #(values)]"

● The following are equivalent

Field-Name: field-valueField-Name: field-value2

Field-Name: field-value1,field-value2

Page 10: HTTP Potpourri

Headers - Browser Request Defaults

GET http://localhost:4952/ HTTP/1.1Accept: text/html, application/xhtml+xml, */*Accept-Language: en-USUser-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)Accept-Encoding: gzip, deflateConnection: Keep-AliveHost: localhost:4952

GET http://localhost:4952/ HTTP/1.1Host: localhost:4952Connection: keep-aliveUser-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Encoding: gzip,deflate, sdchAccept-Language: en-US,en;q=0.8Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

GET http://localhost:4952/ HTTP/1.1Host: localhost:4952User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: en-us,en;q=0.5Accept-Encoding: gzip, deflateConnection: keep-alive

Page 11: HTTP Potpourri

Headers - Case Insensitive

● Field names are case-insensitive. ○ http://stackoverflow.com/questions/1130297/in-ie-the-x-requested-with-

header-of-jquery-becomes-x-requested-with-lower

function doXHR() { var request = new XMLHttpRequest(); request.open('GET', '/header/header.txt'); request.setRequestHeader('x-lowercase', 'X-lowercase'); request.setRequestHeader('x-Propercase', 'X-Propercase'); request.setRequestHeader('x-CamelCase', 'X-CamelCase'); request.setRequestHeader('x-UPPERCASE', 'X-UPPERCASE'); request.onreadystatechange = function() { if (request.readyState == 4) { console.log('Received XMLHttpRequest callback: \n' + request.responseText); } }; request.send("");}

Page 12: HTTP Potpourri

Headers - Case Insensitive

User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618)

x-lowercase: X-lowercasex-camelcase: X-CamelCasex-uppercase: X-UPPERCASEx-propercase: X-Propercase

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Safari/528.17

X-Lowercase: X-lowercaseX-Uppercase: X-UPPERCASEX-Camelcase: X-CamelCaseX-Propercase: X-Propercase

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6 (.NET CLR 3.5.30729)

x-lowercase: X-lowercasex-Propercase: X-Propercasex-CamelCase: X-CamelCasex-UPPERCASE: X-UPPERCASE

Page 13: HTTP Potpourri

What's Special About These Headers?

Accept-CharsetAccept-EncodingAccess-Control-Request-HeadersAccess-Control-Request-MethodConnectionContent-LengthCookieCookie2Content-Transfer-EncodingDateExpect

HostKeep-AliveOriginProxy-*RefererSec-*TETrailerTransfer-EncodingUpgradeUser-AgentVia

Page 14: HTTP Potpourri

Can't Set with XMLHttpRequest

● Read the spec for setRequestHeader()http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader-method

● Or look at the WebKit source codehttp://trac.webkit.org/browser/trunk/Source/WebCore/xml/XMLHttpRequest.cpp?rev=105076

bool XMLHttpRequest::isAllowedHTTPHeader(const String& name){ initializeXMLHttpRequestStaticData(); return !staticData->m_forbiddenRequestHeaders.contains(name) && !name.startsWith(staticData->m_proxyHeaderPrefix, false) && !name.startsWith(staticData->m_secHeaderPrefix, false);}

Page 15: HTTP Potpourri

Encoding and Character Sets

● Accept-Encoding○ gzip, compress, deflate, identity

● Transfer-Encoding○ identity, chunked

● 19.4.5 No Content-Transfer-Encoding○ "HTTP MUST remove any non-identity CTE ("quoted-

printable" or "base64") encoding"● 3.4 Character Sets

○ Note: This use of the term "character set" is more commonly referred to as a "character encoding." However, since HTTP and MIME share the same registry, it is important that the terminology also be shared.

Page 16: HTTP Potpourri

Code

Page 18: HTTP Potpourri

Fiddler & Transfer-Encoding: gzip

Page 19: HTTP Potpourri
Page 20: HTTP Potpourri

"Flush the Buffer Early"

● Best Practices for Speeding Up Your Web Site○ http://developer.yahoo.com/performance/rules.html

● In Views\Shared\_Layout.cshtml, add Response.Flush</head>@{ Response.Buffer = true; Response.Flush();}<body>@RenderBody()</body></html>

Page 21: HTTP Potpourri

IE10 & Transfer-Encoding: chunked

Looks good to me...

Page 22: HTTP Potpourri

Fiddler & Transfer-Encoding: chunked

however,0x781 = 1921

Page 23: HTTP Potpourri

"Flush the Buffer" and .aspx

this.HttpContext.Response.Buffer = true;

</head><% HttpContext.Current.Response.Flush(); %><body>

chunkedutf-8gzip

296

a3

0

Page 24: HTTP Potpourri

IIS / ASP.NET Custom Headers

● What are these?○X-AspNetMvc-Version○X-AspNet-Version○X-SourceFiles○X-Powered-By

● How do I remove, since I "trust no one"?

Page 25: HTTP Potpourri
Page 26: HTTP Potpourri

X- Fields

● Go by various names, referred to○ as x-token in the BNF of RFC 2045○ as user-defined ("X-") in section 5 of RFC 2047○ as Experimental headers in section 4.2.2.1 of the News

Article Format drafthttp://stackoverflow.com/questions/1810915/is-safe-to-use-x-header-in-a-http-response

● Deprecating Use of the "X-" Prefix in Application Protocols (draft 03; January 27, 2012)http://tools.ietf.org/html/draft-saintandre-xdash-03 ○ "deprecates the "X-" convention for most application

protocols by making specific recommendations"

Page 27: HTTP Potpourri

X-AspNetMvc-Version: 4.0

● To remove this header, in the Application_Start() of Global.asax.cs add:

○MvcHandler.DisableMvcResponseHeader = true;

● http://stackoverflow.com/questions/3418557/how-to-remove-asp-net-mvc-default-http-headers/3418574#3418574

Page 28: HTTP Potpourri

X-AspNet-Version: 4.0.30319

● To remove this header, in Web.config, add:

<system.web> <httpRuntime enableVersionHeader="false" /></system.web>

● http://stackoverflow.com/questions/3418557/how-to-remove-asp-net-mvc-default-http-headers/3418574#3418574

Page 29: HTTP Potpourri

X-Powered-By: ASP.NET

● To remove this header, in Web.config add:

<system.webServer> <httpProtocol> <customHeaders> <remove name="X-Powered-By" /> </customHeaders> </httpProtocol></system.webServer>

Page 30: HTTP Potpourri

X-SourceFiles

● http://stackoverflow.com/questions/4851684/what-does-the-x-sourcefiles-header-do

●X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNcZGV2ZWxvcGVyXGRvY3VtZW50c1x2aXN1YWwgc3R1ZGlvIDExXFByb2plY3RzXEhlbGxvV2ViQVBJXEhlbGxvV2ViQVBJ?=

● Decodes to:○c:\users\developer\documents\visual studio 11\Projects\HelloWebAPI\HelloWebAPI

● encoded-word (http://tools.ietf.org/html/rfc1342)○ "=" "?" charset "?" encoding "?" encoded-text "?" "="○ encoding either "B" (Base64) or "Q" (Quoted Printable)

Page 31: HTTP Potpourri

Header Limits?

● IIS has several limitshttp://stackoverflow.com/questions/1097651/is-there-a-practical-http-header-length-limit

● Http.sys registry settings for IIShttp://support.microsoft.com/kb/820129 ○ MaxFieldLength is "upper limit for each header"○ MaxRequestBytes is "upper limit for the total size of the

Request line and the headers"● Header Limits <headerLimits>

http://www.iis.net/ConfigReference/system.webServer/security/requestFiltering/requestLimits/headerLimits ○ limit the length of a specific header<add header="Content-type" sizeLimit="100" />

Page 32: HTTP Potpourri

This Slide IntentionallyLeft Blank

Page 33: HTTP Potpourri

File Upload

● jQuery File Upload Plugin○ "Files can be uploaded as standard "multipart/form-data"

or file contents stream (HTTP PUT file upload)."○ https://github.com/blueimp/jQuery-File-Upload

<input id="fileupload" type="file" name="files[]" data-url="/Logo/Upload" multiple>

$('#fileupload').fileupload({});

Page 34: HTTP Potpourri

RFC 2388 multipart message

POST http://localhost:4952/Logo/Upload HTTP/1.1Host: localhost:4952Connection: keep-aliveContent-Length: 17860Origin: http://localhost:4952X-Requested-With: XMLHttpRequestUser-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryV7HK5HxBBDfYoirjAccept: application/json, text/javascript, */*; q=0.01Referer: http://localhost:4952/Accept-Encoding: gzip,deflate,sdchAccept-Language: en-US,en;q=0.8Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

------WebKitFormBoundaryV7HK5HxBBDfYoirjContent-Disposition: form-data; name="files[]"; filename="logo.png"Content-Type: image/png

�PNG���------WebKitFormBoundaryV7HK5HxBBDfYoirj--

Page 35: HTTP Potpourri

$('#id').fileupload({multipart:false})

POST http://localhost:4952/Logo/Upload HTTP/1.1Host: localhost:4952Connection: keep-aliveContent-Length: 17662Origin: http://localhost:4952X-File-Size: 17662X-Requested-With: XMLHttpRequestX-File-Name: logo.pngUser-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11Content-Type: image/pngAccept: application/json, text/javascript, */*; q=0.01X-File-Type: image/pngReferer: http://localhost:4952/Accept-Encoding: gzip,deflate,sdchAccept-Language: en-US,en;q=0.8Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

Page 36: HTTP Potpourri

Page Load

GET http://localhost:4952/Logo/Download HTTP/1.1Host: localhost:4952Connection: keep-aliveUser-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11Accept: */*Referer: http://localhost:4952/Accept-Encoding: gzip,deflate,sdchAccept-Language: en-US,en;q=0.8Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

HTTP/1.1 200 OKCache-Control: privateContent-Type: text/htmlContent-Encoding: gzipETag: dada50d251fa1ac5c4b25961f87671ddVary: Accept-EncodingServer: Microsoft-IIS/7.5Date: Fri, 06 Apr 2012 19:58:03 GMTContent-Length: 25973

Page 37: HTTP Potpourri

Etag and 304

● Use MD5 hash of data to generate Etag value● Compare MD5 hash against If-None-Match to return 304

String hash = logoInfo.Etag;if (hash.Equals(Request.Headers["If-None-Match"])) { Response.StatusCode = 304;} else { Response.ContentType = logoInfo.ContentType; Response.Headers["Etag"] = hash; logoInfo.Stream.Position = 0; logoInfo.Stream.CopyTo(Response.OutputStream);}

Page 38: HTTP Potpourri

F5 Reload

GET http://localhost:4952/Logo/Download HTTP/1.1Host: localhost:4952Connection: keep-aliveCache-Control: max-age=0User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11If-None-Match: dada50d251fa1ac5c4b25961f87671ddAccept: */*Referer: http://localhost:4952/Accept-Encoding: gzip,deflate,sdchAccept-Language: en-US,en;q=0.8Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

HTTP/1.1 304 Not ModifiedCache-Control: privateServer: Microsoft-IIS/7.5Date: Fri, 06 Apr 2012 19:58:39 GMT

Page 39: HTTP Potpourri

Ctrl + F5 Reload

GET http://localhost:4952/Logo/Download HTTP/1.1Host: localhost:4952Connection: keep-aliveCache-Control: no-cachePragma: no-cacheUser-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11Accept: */*Referer: http://localhost:4952/Accept-Encoding: gzip,deflate,sdchAccept-Language: en-US,en;q=0.8Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

HTTP/1.1 200 OKCache-Control: privateContent-Type: text/htmlContent-Encoding: gzipETag: dada50d251fa1ac5c4b25961f87671ddVary: Accept-EncodingServer: Microsoft-IIS/7.5Date: Fri, 06 Apr 2012 20:00:38 GMTContent-Length: 25973

Page 40: HTTP Potpourri

Cache Headers

● Set Cache-Control: public,max-age=X with <clientCache>http://www.iis.net/ConfigReference/system.webServer/staticContent/clientCache

● Clear Etag needs URL Rewrite Module 2.0 installedhttp://stackoverflow.com/questions/7947420/iis-7-5-remove-etag-headers-from-response

<system.webServer> <staticContent> <clientCache cacheControlCustom="public" cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" /> </staticContent>

<rewrite> <outboundRules> <rule name="Remove ETag"> <match serverVariable="RESPONSE_ETag" pattern=".+" /> <action type="Rewrite" value="" /> </rule> </outboundRules> </rewrite></system.webServer>

Page 41: HTTP Potpourri

Squid Proxy

● Squid 2.7 for Windows (http://squid.acmeconsulting.it/)

● squid.conf○http_access allow localhost

● Set proxy as localhost:3128 then see additional response headers

Proxy-Connection: keep-aliveVia: 1.1 U0038137-W8A:3128 (squid/2.7.STABLE8)X-Cache: MISS from U0038137-W8AX-Cache-Lookup: MISS from U0038137-W8A:3128

Page 42: HTTP Potpourri

PURGE

● Purge and object from Squid cache○ http://wiki.squid-cache.org/SquidFaq/OperatingSquid

● squid.conf○acl PURGE method PURGE ○http_access allow PURGE localhost○http_access deny PURGE

● squidclient -m PURGE <url>

● curl --request PURGE --proxy localhost:3128 <url>

Page 43: HTTP Potpourri

WebDAV

● "extension to the HTTP/1.1 protocol that allows clients to perform remote web content authoring operations"

● Leveraged existing HTTP Methods○ GET, HEAD, POST, DELETE, PUT

● Defined new HTTP Methods○ PROPFIND, PROPPATCH, MKCOL, COPY, MOVE,

LOCK, UNLOCK● New Status Codes

○ 102 Processing, 207 Multi-Status, 422 Unprocessable Entity, 423 Locked, 424 Failed Dependency, 507 Insufficient Storage

Page 44: HTTP Potpourri

curl - transfer a url

● Installed on Windows if you have Git Bash○ http://curl.haxx.se/docs/manpage.html

● Some options--compressed--data-binary <data>-F, --form <name=content>-H, --header <header>--limit-rate <speed>-o, --output <file>-T, --upload-file <file>-x, --proxy <[protocol://][user@password]proxyhost[:port]>-X, --request <command>

Page 45: HTTP Potpourri

WebDAV - PROPFIND Request

$ curl --proxy localhost:8888 --request PROPFIND http://localhost:4952/Logo/Download

PROPFIND http://localhost:4952/Logo/Download HTTP/1.1User-Agent: curl/7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8r zlib/1.2.3Host: localhost:4952Accept: */*Connection: Keep-Alive

Page 46: HTTP Potpourri

WebDAV - PROPFIND Response

HTTP/1.1 207 Multi-StatusCache-Control: privateContent-Type: text/xmlServer: Microsoft-IIS/7.5Date: Sat, 07 Apr 2012 20:53:01 GMTContent-Length: 532

<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:"> <D:response> <D:href>http://localhost:4952/Logo/Download</D:href> <D:propstat> <D:prop> <D:status>HTTP/1.1 200 OK</D:status> <D:getcontenttype>image/png</D:getcontenttype> <D:getlastmodfiied>Sat, 07 Apr 2012 20:45:05 GMT</D:getlastmodfiied> <D:getetag>dada50d251fa1ac5c4b25961f87671dd</D:getetag> <D:creationdate>Sat, 07 Apr 2012 20:45:05 GMT</D:creationdate> </D:prop> </D:propstat></D:response></D:multistatus>

Page 47: HTTP Potpourri

public ActionResult Propfind()

[ActionName("Download")][AcceptVerbs("PROPFIND")]public ActionResult Propfind(){ Response.StatusCode = 207; Response.ContentType = "text/xml"; Response.Charset = null;

ViewBag.ContentType = logoInfo.ContentType; ViewBag.Date = logoInfo.Date; ViewBag.Etag = logoInfo.Etag;

return PartialView("Propfind");}

Page 48: HTTP Potpourri

Propfind.cshtml

<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:"> <D:response> <D:href>@Request.Url</D:href> <D:propstat> <D:prop> <D:status>HTTP/1.1 200 OK</D:status> <D:getcontenttype>@ViewBag.ContentType</D:getcontenttype> <D:getlastmodfiied> @ViewBag.Date.ToUniversalTime().ToString("r") </D:getlastmodfiied> <D:getetag>@ViewBag.Etag</D:getetag> <D:creationdate> @ViewBag.Date.ToUniversalTime().ToString("r") </D:creationdate> </D:prop> </D:propstat></D:response></D:multistatus>

Page 49: HTTP Potpourri

Browser Security

Page 50: HTTP Potpourri

X-Frame-Options

● Combating ClickJacking With X-Frame-Options○ http://blogs.msdn.

com/b/ieinternals/archive/2010/03/30/combating-clickjacking-with-x-frame-options.aspx

● Browser Support:○ IE8+, Safari 4+, Chrome 4+, Firefox 3.6.9+○ Test at http://www.enhanceie.com/test/clickjack/

● Value may be one of○ DENY - block rendering if within a frame○ SAMEORIGIN - block rendering if top leve browsing

context is different○ ALLOW-FROM origin - block rendering origin value if

different

Page 51: HTTP Potpourri

HTTP Strict Transport Security

● Allows a site to request that it always be contacted over HTTPS.○ http://dev.chromium.org/sts

● Supported in Google Chrome, Firefox 4.● Remembers that for the given number of seconds, that the

current domain should only be contacted over HTTPS● Spec

○ http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec-06● Example Response Header

Strict-Transport-Security: max-age=15768000 ; includeSubDomains

Page 52: HTTP Potpourri

Cross-Origin Resource Sharing

● a.k.a. CORS http://www.w3.org/TR/cors/● Implementing CORS support in ASP.NET Web APIs

○ http://blogs.msdn.com/b/carlosfigueira/archive/2012/02/21/implementing-cors-support-in-asp-net-web-apis-take-2.aspx

● Request Headers○ Origin○ Access-Control-Request-Method○ Access-Control-Request-Headers

● Response Headers○ Access-Control-Allow-Origin○ Access-Control-Allow-Credentials○ Access-Control-Expose-Headers○ Access-Control-Max-Age○ Access-Control-Allow-Methods○ Access-Control-Allow-Headers

Page 53: HTTP Potpourri

CORS Preflight Request/Response

OPTIONS http://localhost:4952/api/Values/ HTTP/1.1Host: localhost:4952Connection: keep-aliveAccess-Control-Request-Method: POSTOrigin: http://localhost:7147User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11Access-Control-Request-Headers: Origin, Content-Type, AcceptAccept: */*Referer: http://localhost:7147/Accept-Encoding: gzip,deflate,sdchAccept-Language: en-US,en;q=0.8Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

HTTP/1.1 200 OKCache-Control: no-cachePragma: no-cacheExpires: -1Server: Microsoft-IIS/7.5Access-Control-Allow-Methods: POSTAccess-Control-Allow-Headers: Origin, Content-Type, AcceptAccess-Control-Allow-Origin: http://localhost:7147X-AspNet-Version: 4.0.30319X-Powered-By: ASP.NETDate: Wed, 28 Mar 2012 17:38:00 GMTContent-Length: 0

Page 54: HTTP Potpourri

Demo

http://localhost:7147/

Page 55: HTTP Potpourri
Page 56: HTTP Potpourri

Cross-Site Request Forgery (CSRF)

● How to use ASP.NET MVC anti-forgery helpers with web apis?

● Started with "Preventing CSRF with Ajax"http://haacked.com/archive/2011/10/10/preventing-csrf-with-ajax.aspx

● Used the "ASP.NET MVC 3 RTM Source Code" to peek into the inner workings of AntiForgeryhttps://aspnet.codeplex.com/releases/view/58781

Page 57: HTTP Potpourri

Modifications

● Controller code

var inputTag = AntiForgery.GetHtml(this.HttpContext, null, null, null).ToString();var tokenValue = Regex.Match(inputTag, "value=\"(.*)\"").Groups[1].Value;ViewBag.RequestVerificationToken = tokenValue;

● View code

$.ajaxPrefilter(function (options, originalOptions, jqXHR) { if (!options.headers) options.headers = {}; options.headers["__RequestVerificationToken"] = "@ViewBag.RequestVerificationToken";});

● validation not working yet, because:○ System.Web.Http.Filters.FilterAttribute != System.Web.

Mvc.FilterAttribute

Page 58: HTTP Potpourri

CSRF

GET http://localhost:4952/api/products/ HTTP/1.1__RequestVerificationToken: q592rxZ1san7NwORzH0SkHp8rpIYB9IDgosSIt+/hB4hVsKUB/xsfCfsiqdStnHZ459xX+mM8VKL+IUP1CDM8jcoKv5La1l4XszC5tz6FiIY2lVXZ+CaYytbjV2o+I0wJHyLvrpgjyzGwHHErwVv4jgDG3khJr1ibRGGJicFlWw=Accept: application/json, text/javascript, */*; q=0.01X-Requested-With: XMLHttpRequestReferer: http://localhost:4952/Accept-Language: en-usAccept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/6.0; .NET4.0E; .NET4.0C; Media Center PC 6.0; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)Host: localhost:4952Connection: Keep-AliveCookie: __RequestVerificationToken_Lw__ =WVJj4wvLfroG56QsHbZHNxhSZBxbsf3nN1FPsBp8AWgyyuKSr19voC8zxwl1wu1GfI9/uqKcdf03dtVN8Izm+JkDG6/j/zhnKFyYWw8Tiqr88URDO/mOhE8edSY93ZSuALnPYeD/VS1VftEqvKbtSA7BgWxKhRddOrm5Sc9VMjk=

Page 59: HTTP Potpourri

(Near?) Future

Page 60: HTTP Potpourri

WebSockets

● Couldn't get SignalR working with IIS 8 and WebSockets● Getting started with WebSockets in Windows 8

○ http://www.paulbatum.com/2011/09/getting-started-with-websockets-in.html

○ https://github.com/paulbatum/PushFrenzy ● Hard to peek under the covers - RFC 6455:

○ 1.7. Relationship to TCP and HTTPThe WebSocket Protocol is an independent TCP-based protocol. Its only relationship to HTTP is that its handshake is interpreted by HTTP servers as an Upgrade request.

http://tools.ietf.org/html/rfc6455

Page 61: HTTP Potpourri

WebSockets - PushFrenzy

GET http://localhost/PushFrenzy.Web/connect?nickname=IE&gamesize=2 HTTP/1.1Origin: localhostSec-WebSocket-Key: 9l4ov6WTcktNZhDxzofNsA==Connection: UpgradeUpgrade: WebsocketSec-WebSocket-Version: 13User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)Host: localhostCache-Control: no-cache

HTTP/1.1 101 Switching ProtocolsCache-Control: privateUpgrade: WebsocketServer: Microsoft-IIS/8.0X-AspNet-Version: 4.0.30319Sec-WebSocket-Accept: 2npInS6ZLafsQdJ4EPNxraKGlpY=Connection: UpgradeX-Powered-By: ASP.NETDate: Tue, 03 Apr 2012 20:40:47 GMT

Page 62: HTTP Potpourri
Page 63: HTTP Potpourri

http://websocketstest.com/

Page 64: HTTP Potpourri

WebSockets - Fiddler

● Glimpse of the future: Fiddler and HTML5 WebSockets○ http://blogs.msdn.com/b/fiddler/archive/2011/11/22/fiddler-

and-websockets.aspx ● Single Request/Response entry

● Most data appears in Log tab

● Look for these bytes in upcoming slides○81 0A 63 6F 6E 6E 65 63 74 65 64 2C

Page 65: HTTP Potpourri

WebSockets - Fiddler

GET http://ws.websocketstest.com/service HTTP/1.1Upgrade: websocketConnection: UpgradeHost: ws.websocketstest.comOrigin: http://websocketstest.comSec-WebSocket-Key: a05pbM96VhcorGnOP29sOw==Sec-WebSocket-Version: 13Cookie: __utma=245398530.78459945.1333486200.1333486200.1333486200.1; __utmb=245398530.7.10.1333486200; __utmc=245398530; __utmz=245398530.1333486200.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)

HTTP/1.1 101 Switching ProtocolsUpgrade: WebSocketConnection: UpgradeSec-WebSocket-Accept: dHDHGWWR3k2+1linxGu02hAH/00=EndTime: 16:24:34.380

Page 66: HTTP Potpourri

WebSockets - Fiddler Log Start

16:22:18:9186 Upgrading Session #29 to websocket 16:22:18:9886 [WebSocket #29] Received from server 12 bytesFlags: 10000001 Message Masking: False. Data length: 10 bytes.

81 0A 63 6F 6E 6E 65 63 74 65 64 2C �.connected,

16:22:18:9886 [WebSocket #29] Received from browser 14 bytesFlags: 10000001 Message Masking: True. Data length: 8 bytes.Masking key is: 8C 07 80 8Fversion,81 88 8C 07 80 8F FA 62 F2 FC E5 68 EE A3 �ˆŒ.€�úbòüåhî£

16:22:19:0586 [WebSocket #29] Received from server 23 bytesFlags: 10000001 Message Masking: False. Data length: 21 bytes.

81 15 76 65 72 73 69 6F 6E 2C 68 79 62 69 2D 64 72 61 66 74 2D 31 33 �.version,hybi-draft-13

Page 67: HTTP Potpourri

WebSockets - Fiddler Log End

16:24:33:5642 [WebSocket #29] Received from server 24 bytesFlags: 10000001 Message Masking: False. Data length: 22 bytes.

81 16 74 69 6D 65 2C 32 30 31 32 2F 34 2F 33 20 32 31 3A 32 32 3A 31 39 �.time,2012/4/3 21:22:19

16:24:34:3802 [WebSocket #29] OnClientReceive from browser failed; ret=0

Page 68: HTTP Potpourri

WebSockets - Wireshark Capture

● Wireshark notes that this HTTP does not seem right○ "Continuation or non-HTTP traffic"

Page 69: HTTP Potpourri

WebSockets - Wireshark Capture

16:22:18:9186 Upgrading Session #29 to websocket 16:22:18:9886 [WebSocket #29] Received from server 12 bytesFlags: 10000001 Message Masking: False. Data length: 10 bytes.

81 0A 63 6F 6E 6E 65 63 74 65 64 2C �.connected,

Page 70: HTTP Potpourri

WebSockets - Wireshark Capture

Page 71: HTTP Potpourri

SPDY

● An experimental protocol for a faster web○ http://dev.chromium.org/spdy/spdy-whitepaper ○ "application-layer protocol for transporting content over the

web, designed specifically for minimal latency"○ "TCP is the generic, reliable transport protocol, providing

guaranteed delivery, duplicate suppression, in-order delivery, flow control, congestion avoidance and other transport features."

○ "HTTP is the application level protocol providing basic request/response semantics."

○ "adds a session layer atop of SSL that allows for multiple concurrent, interleaved streams over a single TCP connection"

Page 72: HTTP Potpourri

SPDY - Request Changes

● First line of the request is unfolded into name/value pairs like other HTTP headers

● Duplicate header names are not allowed● Header names are all lowercase● The Connection and Keep-Alive headers are no longer

valid and are ignored if present● Clients assumed to support Accept-Encoding: gzip● HTTP request headers are compressed with gzip encoding● The "host" header is ignored as the host:port portion of the

HTTP URL is the definitive host●Content-length is only advisory for length (so that

progress meters can work)●Chunked encoding is no longer valid.

Page 73: HTTP Potpourri

SPDY - Response Changes

● The response status line is unfolded into name/value pairs like other HTTP headers

● All header names must be lowercase● The Connection and Keep-alive response headers are

no longer valid●Content-length is only advisory for length●Chunked encoding is no longer valid● Duplicate header names are not allowed

Page 74: HTTP Potpourri

SPDY - Tools and Debugging

● New protocol = new debugging tools○ Chrome about:net-internals

Page 75: HTTP Potpourri

Questions?

(and, please evaluate http://tccc.agilevent.com/)