Chris,
(Apologies for the length of this message)
I discovered that using headers in makeRequest was still not working for me.
I ran a basic test this morning on my copy of the trunk. The test
submits a Get to a script that returns a bunch of headers.
here is the relevant JS in my gadget:
function request() {
var params = {};
var headers = { "X-mikey-Authorization" : "MIKEYS GADGET",
"X-Mikey": "veryhungry" };
params[gadgets.io.RequestParameters.CONTENT_TYPE] =
gadgets.io.ContentType.TEXT;
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
theurl="http://myserver:8081/gadgets/MakeRequestTestService.php";
params[gadgets.io.RequestParameters.AUTHORIZATION]
=gadgets.io.AuthorizationType.NONE;
params[gadgets.io.RequestParameters.HEADERS]= headers;
gadgets.io.makeRequest(theurl, response, params);
}
function response(obj) {
console.log(obj);
}
request();
The MakeRequestTestService.php was just a basic header echo loop so I
could see what was submitted by shindig:
$headers = apache_request_headers();
foreach ($headers as $header => $value) {
echo "$header: $value <br />\n";
}
But, the headers I wanted shindig to submit did not make it to my test script.
Here is the console.log output (the data element shows what headers my
test did receive.)
data "Host: 10.100.43.202:8081 <br
/>\nAccept: */* <br />\n"
errors [ ]
headers undefined
oauthApprovalUrl undefined
oauthError undefined
oauthErrorText undefined
rc 200
text "Host: 10.100.43.202:8081 <br
/>\nAccept: */* <br />\n"
Looking at shindig some more, I managed to trace how makeRequest is
handled, as far back as ProxyBase.
(makeRequest
call->MakeRequestServlet->MakeRequestHandler->ProxyBase->RemoteContentRequest->more,
I'm sure...)
In ProxyBase, I noticed that headers are only handled when makeRequest
submits a *Post* to the ProxyBase, thus explaining the negative result
of my Get test above.
I've made changes to my ProxyBase to support passing the headers for
both Get and Post. (which, it seems, is also sufficient to pass the
headers for Put, Delete, and Head.)
removed:
if (isset($_POST['headers'])) {
$request->setHeaders(urldecode(str_replace("&", "\n",
str_replace("=", ": ", $_POST['headers']))));
}
added
$requestHeaders = isset($_GET['headers']) ? $_GET['headers'] :
(isset($_POST['headers']) ? $_POST['headers'] : '');
if ($requestHeaders) {
$request->setHeaders(urldecode(str_replace("&", "\n",
str_replace("=", ": ", $requestHeaders))));
}
Now upon re-running my test, my little test script returned the
request headers as html, however, the response headers element was
still undefined in the Json object.
data "Host: 10.100.43.202:8081 <br
/>\nAccept: */* <br />\nX-Mikey-Authorization: MIKEYS GADGET <br
/>\nX-Mikey: veryhungry <br />\nUser-Agent: Apache Shindig <br />\n"
errors [ ]
headers undefined
oauthApprovalUrl undefined
oauthError undefined
oauthErrorText undefined
rc 200
text "Host: 10.100.43.202:8081 <br
/>\nAccept: */* <br />\nX-Mikey-Authorization: MIKEYS GADGET <br
/>\nX-Mikey: veryhungry <br />\nUser-Agent: Apache Shindig <br />\n"
So I went back into MakeRequestHandler to see why the response headers
element was empty. I noticed that when oAuth is used, the
OauthFetcher seems to fill in the oath-* metadata used in the Json
object above by calling setMetadata (in RemoteContentRequest). I was,
however, not able to pin down what fills in data,errors, headers, and
text.
My workaround was to add lines to MakeRequestHandler that would add
the response headers to the Json object by calling
getResponseHeaders(in RemoteContentRequest) if it found 'headers'
empty. (I am sure I am overlooking code somewhere that might properly
fill in headers, so I test for the presence of headers with the 'if'
statement to avoid trouble)
if (!$responseArray['headers']) {
$responseArray['headers']=$result->getResponseHeaders();
}
These fixes seem to solve my problem, in that I can now submit http
headers to my back-end via makeRequest using
gadgets.io.RequestParameters.HEADERS, and I can obtain the response
headers from the back-end using the 'headers' element contained in the
JSON response.
I can submit the changes I made to JIRA if desired (which would be my
first-ever commits to an open source project - yay!). But I don't know
if I am working at cross-purposes with the intent of the original
design.
With all that said, you mentioned in a separate thread that "it was
concluded that "headers in makeRequest was
undesirable and a security risk.. so that limits the usefulness of it
quite a bit"
I wouldn't mind hearing why headers in makeRequest was deemed
undesirable, and I am wondering if they could be used in cases where
other security measures are taken to assure secure authentication.
I've got a enterprise-specific use case where, at least so far,
headers seem to fit. I am building internal-use-only gadgets that call
a (non-OpenSocial) REST api containing business data. Access to the
business data served by this REST api has a stringent and granular
audit requirement, thus there are a number of (very un-restful) tokens
that the api requires to verify that the both the requestor and the
request is legit and is tracked, as well as tokens that provide CSRF
protection. I wanted to use http 'x-headers' in order for shindig to
pass these tokens back and forth. (I should add that we are already
protecting the transport layer using SSL with client certs; so we can
establish trust between end-users and shindig and between shindig and
the api.)
Am I way off track in thinking I could use headers to convey security
information between shindig/gadgets and our back end?
(Still want the patch?)
Thanks,
Michael
On Fri, Jul 10, 2009 at 5:11 PM, Chris Chabot <[email protected]> wrote:
>
> Ow that is some way back, but if memory serves me correctly this was fixed,
> php shindig trunk should deal with it correctly, i'll make a note to double
> check though, or if you have a moment I would love to hear if it's working
> for you!
>
> On Fri, Jul 10, 2009 at 10:06 PM, Michael Gold <[email protected]> wrote:
>
> > Chris,
> >
> > Any update on support in Shindig PHP for
> > gadgets.io.RequestParameters.HEADERS?
> >
> > thanks!
> > Michael
> > On Sat, Mar 21, 2009 at 12:52 PM, Chris Chabot <[email protected]> wrote:
> >
> > > Hey Michael,
> > >
> > > Currently PHP Shindig doesn't support
> > gadgets.io.RequestParameters.HEADERS
> > > I'm afraid, I completely overlooked that bit of the spec and your the
> > first
> > > to notice, so thanks for pointing that out so we can go fix it :)
> > >
> > > Pan Jie is digging around in the RemoteContent classes currently
> > > (refactoring & adding support for limited cache invalidation, etc), Pan
> > is
> > > this something you could easily pick up and fix while your reworking
> > those
> > > classes?
> > >
> > > -- Chris
> > >
> > > On Fri, Mar 20, 2009 at 2:04 AM, Michael Gold <[email protected]> wrote:
> > >
> > > > I was working with makeRequest and Shindig PHP, and noticed that the
> > http
> > > > request headers I sent using gadgets.io.RequestParameters.HEADERS were
> > > > being
> > > > dropped.
> > > > (My test: I pointed makeRequest at a quick and dirty script that
> > returns
> > > > the
> > > > entire contents of $_SERVER and $_REQUEST in a JSON object. No headers
> > > were
> > > > returned, plus Firebug and Fiddler reveal that, at least in the Post
> > from
> > > > browser-to-server, the 'headers' parameter is indeed being sent.)
> > > >
> > > > At first, I thought I had found a clean explanation - I was sending an
> > > > Authorization header, and I had read that certain OpenSocial containers
> > > > restrict the Authorization header (and some other headers as well) for
> > > > security reasons.
> > > >
> > > > Fair enough.
> > > >
> > > > So I created my very own X-header. (X-Mikey: foo)
> > > >
> > > > But X-Mikey didn't seem to fly either.
> > > >
> > > > This got me curious, so I fired up a debugger and stepped through the
> > > > makeRequest process.
> > > >
> > > > Here is what I discovered so far. Once the modules load, the $headers
> > > > variable does seem to make it into Shindig. It even goes so far as to
> > > > explode it into an array. But once that occurs I didn't see anything
> > > after
> > > > that except $headers = false.
> > > >
> > > > So far I found reference to $headers in:
> > > >
> > > > + src/common/sample/BasicRemoteContentFetcher.php - home of curl, also
> > > home
> > > > to the $disallowedHeaders array which does include a number of headers,
> > > but
> > > > Authorization was not there.
> > > > + src/gadgets/SigningFetcher.php - here I saw a function called
> > > sanitize()
> > > > that seems to exclude the headers from the OAuth signature calculation,
> > > but
> > > > I was unsure if sanitize() removes the headers from the request
> > > altogether
> > > >
> > > > + src/common/RemoteContentRequest.php
> > > >
> > > > + src/gadgets/MakeRequestHandler.php
> > > >
> > > > I think if I stepped through it in the debugger a couple more times I'd
> > > be
> > > > able to see more clearly and perhaps put my finger on where the
> > > disconnect
> > > > is. (That or come to the realization that the disconnect is me!)
> > > >
> > > > Since the code is already familar territory to many here I thought I'd
> > > ask:
> > > > Are the missing request headers a known issue? (Should I keep digging?)
> > > > Does Shindig not support makeRequest's
> > > > gadgets.io.RequestParameters.HEADERS ?
> > > >
> > > > Thanks in advance,
> > > > Michael
> > > >
> > >
> >