summaryrefslogblamecommitdiffstats
path: root/archives/extend/2013-April/000077.html
blob: 1bbf7ad272342a356618cb0dfc19077908a422fd (plain) (tree)




















































































































































































































                                                                                                                                                                                       
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
 <HEAD>
   <TITLE> [99s-extend] Response headers
   </TITLE>
   <LINK REL="Index" HREF="index.html" >
   <LINK REL="made" HREF="mailto:extend%40lists.ninenines.eu?Subject=Re%3A%20%5B99s-extend%5D%20Response%20headers&In-Reply-To=%3C3E75C3ED-9F52-495A-8E04-EF0A4667DB4E%40gmail.com%3E">
   <META NAME="robots" CONTENT="index,nofollow">
   <style type="text/css">
       pre {
           white-space: pre-wrap;       /* css-2.1, curent FF, Opera, Safari */
           }
   </style>
   <META http-equiv="Content-Type" content="text/html; charset=us-ascii">
   <LINK REL="Previous"  HREF="000076.html">
   <LINK REL="Next"  HREF="000078.html">
 </HEAD>
 <BODY BGCOLOR="#ffffff">
   <H1>[99s-extend] Response headers</H1>
    <B>Lee Sylvester</B> 
    <A HREF="mailto:extend%40lists.ninenines.eu?Subject=Re%3A%20%5B99s-extend%5D%20Response%20headers&In-Reply-To=%3C3E75C3ED-9F52-495A-8E04-EF0A4667DB4E%40gmail.com%3E"
       TITLE="[99s-extend] Response headers">lee.sylvester at gmail.com
       </A><BR>
    <I>Thu Apr  4 10:38:07 CEST 2013</I>
    <P><UL>
        <LI>Previous message: <A HREF="000076.html">[99s-extend] Response headers
</A></li>
        <LI>Next message: <A HREF="000078.html">[99s-extend] Bullet connection
</A></li>
         <LI> <B>Messages sorted by:</B> 
              <a href="date.html#77">[ date ]</a>
              <a href="thread.html#77">[ thread ]</a>
              <a href="subject.html#77">[ subject ]</a>
              <a href="author.html#77">[ author ]</a>
         </LI>
       </UL>
    <HR>  
<!--beginarticle-->
<PRE>Hi Christopher,

Thank you for that.  I will attempt to go through each piece today and solve the problem.  This is good advice; maybe it belongs in a blog post?  :-)

Thanks again,
Lee




On 3 Apr 2013, at 21:35, &quot;Phillips, Christopher&quot; &lt;<A HREF="https://lists.ninenines.eu/listinfo/extend">Christopher.Phillips at turner.com</A>&gt; wrote:

&gt;<i> 
</I>&gt;<i>  Sure. Right now, Cowboy doesn't parse the headers, but you can manually
</I>&gt;<i> parse them in your handler. I've got them working in my implementation
</I>&gt;<i> pretty well, I'll try and break it down a bit here.
</I>&gt;<i> 
</I>&gt;<i>  A good, basic overview of what the requests the browser will send, and
</I>&gt;<i> what your responses should look like, is here:
</I>&gt;<i> <A HREF="https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS">https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS</A>
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> HANDLING PRE-FLIGHTS -
</I>&gt;<i>  Pre-flights are the OPTION requests the browser automatically sends off
</I>&gt;<i> when you make a CORS request using a verb other than GET, or POST with one
</I>&gt;<i> of three acceptable content types. They're defined well in the above link.
</I>&gt;<i> 
</I>&gt;<i>  You can read off the requested headers the actual call wants to send in
</I>&gt;<i> the OPTIONS preflight with
</I>&gt;<i> 
</I>&gt;<i> 	{Headers, NewRequest } =
</I>&gt;<i> cowboy_req:header(&lt;&lt;&quot;access-control-request-headers&quot;&gt;&gt;, Request)
</I>&gt;<i> 
</I>&gt;<i>  Headers will either be the binary, or undefined. If the binary, you
</I>&gt;<i> either need to manually parse it and choose to allow/disallow the request
</I>&gt;<i> from continuing based on it, or, if you just want to allow all headers
</I>&gt;<i> trivially, just pipe that back into the request, a la -
</I>&gt;<i> 
</I>&gt;<i>        Request2 = 
</I>&gt;<i> cowboy_req:set_resp_header(&lt;&lt;&quot;access-control-allow-headers&quot;&gt;&gt;,
</I>&gt;<i> binary_to_list(Headers), NewRequest)
</I>&gt;<i> 
</I>&gt;<i>  (As a reminder, it can be undefined. You'll need to check for that
</I>&gt;<i> before passing it into the above. If it's undefined, you don't need to add
</I>&gt;<i> the access-control-allow-headers header).
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i>  As part of the pre-flight request, you also need to handle what methods
</I>&gt;<i> are allowed. This looks something like -
</I>&gt;<i> 
</I>&gt;<i> 	PreflightedRequest =
</I>&gt;<i> cowboy_req:set_resp_header(&lt;&lt;&quot;access-control-allow-methods&quot;&gt;&gt;, &lt;&lt;&quot;GET,
</I>&gt;<i> POST, DELETE, PUT&quot;&gt;&gt;, Request2)
</I>&gt;<i> 
</I>&gt;<i>  If I wanted to allow gets, posts, deletes, and puts. You can also choose
</I>&gt;<i> to read off the access-control-request-method header sent from the client,
</I>&gt;<i> but I don't see the point; your list of allowed methods doesn't need to
</I>&gt;<i> change based on that (the user is requesting a POST, why does that change
</I>&gt;<i> whether you allow a POST or not? But I digress).
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> FOR ALL CALLS (both pre-flights and the actual call)
</I>&gt;<i>  Respond with acceptable origin. If you want any domain to access this
</I>&gt;<i> resource (not advised, unless this is a public, readonly resource, but
</I>&gt;<i> good for testing), you can do -
</I>&gt;<i> 
</I>&gt;<i>  	NewRequest = 
</I>&gt;<i> cowboy_req:set_resp_header(&lt;&lt;&quot;access-control-allow-origin&quot;&gt;&gt;, &lt;&lt;&quot;*&quot;&gt;&gt;,
</I>&gt;<i> Request)
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i>  If you want to filter out the allowed domains, it looks like -
</I>&gt;<i> 
</I>&gt;<i> 	Origin = cowboy_req:header(&lt;&lt;&quot;origin&quot;&gt;&gt;, Request) %Get the origin that
</I>&gt;<i> the browser sent you
</I>&gt;<i> 
</I>&gt;<i>        %Do logic to check Origin, and any other data that would decide
</I>&gt;<i> whether this request is allowed; it will only apply on a CORS request from
</I>&gt;<i> another browser.
</I>&gt;<i> 
</I>&gt;<i> 	%If it passes, pass Origin back as the value for the
</I>&gt;<i> access-control-allow-origin header.
</I>&gt;<i>        NewRequest =
</I>&gt;<i> cowboy_req:set_resp_header(&lt;&lt;&quot;access-control-allow-origin&quot;&gt;&gt;, Origin,
</I>&gt;<i> Request)
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> FOR ONLY THE ACTUAL CALL
</I>&gt;<i>  If you want to send custom headers back to your Javascript client (or
</I>&gt;<i> read any standard header beyond content-type), you need to explicitly
</I>&gt;<i> allow them. This looks like (if I wanted to expose the 'server' header so
</I>&gt;<i> my client Javascript can see that it's Cowboy on the backend) -
</I>&gt;<i> 
</I>&gt;<i>  	ExposedHeaderRequest =
</I>&gt;<i> cowboy_req:set_resp_header(&lt;&lt;&quot;access-control-expose-headers&quot;&gt;&gt;,
</I>&gt;<i> &lt;&lt;&quot;server&quot;&gt;&gt;, Request)
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i>  That's basically it I believe. There is also a max age, and a allow
</I>&gt;<i> credentials header (which is really more of a require credentials);
</I>&gt;<i> they're pretty straightforwardly explained on that page I linked above,
</I>&gt;<i> but I haven't played with them personally.
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i>  Caveats I ran into were largely being aware that same domain requests do
</I>&gt;<i> NOT supply any of the CORS headers, not even the origin header (so you can
</I>&gt;<i> get undefined and have to handle those cases), as well as understanding
</I>&gt;<i> the ramifications of allowing cross domain requests. Also, if you want to
</I>&gt;<i> develop while disconnected (or if it's not easy to grab another domain),
</I>&gt;<i> use your hosts file to declare a fake domain pointed to 127.0.0.1, load
</I>&gt;<i> your page from that, explicitly define your AJAX calls to localhost. Note
</I>&gt;<i> too that there is a bug in Firefox at present when you try and get all the
</I>&gt;<i> request headers. It returns an empty list. You can get individual ones if
</I>&gt;<i> you know the name (I.e., getResponseHeader(&quot;server&quot;) will work,
</I>&gt;<i> getAllResponseHeaders() returns an empty string). This is further
</I>&gt;<i> compounded by jQuery building its own XHR that loads headers by calling
</I>&gt;<i> getAllResponseHeaders, so in Firefox, using jQuery, you can get back zero
</I>&gt;<i> headers. Don't know if that affects you, but it's an issue it took me a
</I>&gt;<i> good while to diagnose, and which we've had to bear in mind.
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> On 4/3/13 3:33 PM, &quot;Lee Sylvester&quot; &lt;<A HREF="https://lists.ninenines.eu/listinfo/extend">lee.sylvester at gmail.com</A>&gt; wrote:
</I>&gt;<i> 
</I>&gt;&gt;<i> Hi list,
</I>&gt;&gt;<i> 
</I>&gt;&gt;<i> I'd like to set up my handler to use CORS.  Can anyone tell me how I can
</I>&gt;&gt;<i> modify the headers for my handler to support this?
</I>&gt;&gt;<i> 
</I>&gt;&gt;<i> Thanks loads,
</I>&gt;&gt;<i> Lee
</I>&gt;&gt;<i> _______________________________________________
</I>&gt;&gt;<i> Extend mailing list
</I>&gt;&gt;<i> <A HREF="https://lists.ninenines.eu/listinfo/extend">Extend at lists.ninenines.eu</A>
</I>&gt;&gt;<i> <A HREF="http://lists.ninenines.eu:81/listinfo/extend">http://lists.ninenines.eu:81/listinfo/extend</A>
</I>&gt;&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> 
</I>&gt;<i> _______________________________________________
</I>&gt;<i> Extend mailing list
</I>&gt;<i> <A HREF="https://lists.ninenines.eu/listinfo/extend">Extend at lists.ninenines.eu</A>
</I>&gt;<i> <A HREF="http://lists.ninenines.eu:81/listinfo/extend">http://lists.ninenines.eu:81/listinfo/extend</A>
</I>

</PRE>

<!--endarticle-->
    <HR>
    <P><UL>
        <!--threads-->
	<LI>Previous message: <A HREF="000076.html">[99s-extend] Response headers
</A></li>
	<LI>Next message: <A HREF="000078.html">[99s-extend] Bullet connection
</A></li>
         <LI> <B>Messages sorted by:</B> 
              <a href="date.html#77">[ date ]</a>
              <a href="thread.html#77">[ thread ]</a>
              <a href="subject.html#77">[ subject ]</a>
              <a href="author.html#77">[ author ]</a>
         </LI>
       </UL>

<hr>
<a href="https://lists.ninenines.eu/listinfo/extend">More information about the Extend
mailing list</a><br>
</body></html>