You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by Taylor Singletary <ta...@gmail.com> on 2008/09/09 15:43:56 UTC

Shindig checks for POST body on GET REST requests

Hi all,

I'm having a small problem getting Shindig's REST support to work
reliably with vanilla Net::HTTP Ruby libraries. I believe that this
might effect other http clients as well, though I have managed to get
at least two alternate HTTP clients to interface with the REST APIs
without difficulty.

The problem appears to be that Shindig checks for a BODY in an
incoming GET request. This checking for a BODY that doesn't actually
exist results in this error:

java.lang.RuntimeException: Could not get the post data from the request
org.apache.shindig.social.opensocial.service.RestfulRequestItem.<init>(RestfulRequestItem.java:76)
org.apache.shindig.social.opensocial.service.DataServiceServlet.handleSingleRequest(DataServiceServlet.java:94)
org.apache.shindig.social.opensocial.service.DataServiceServlet.doPost(DataServiceServlet.java:79)
org.apache.shindig.social.opensocial.service.DataServiceServlet.doGet(DataServiceServlet.java:47)
javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
org.apache.shindig.social.core.oauth.AuthenticationServletFilter.doFilter(AuthenticationServletFilter.java:89)

Actual error:  the actual exception thrown by IOUtils is
"java.net.SocketTimeoutException: Read timed out"

Granted, the Net::HTTP library in some way must be indicating a Body
header but providing no content inside, but it remains that Shindig
shouldn't be checking for a body on a GET request. Is there any reason
that it is doing so?

Managed to track it down to the following code (revision 688930, but
current doesn't look to have changed much here):
Our source is rev 688930, but the last version didn't changed much in the

private void handleSingleRequest(HttpServletRequest servletRequest,
       HttpServletResponse servletResponse, SecurityToken token,
       BeanConverter converter) throws IOException {
    RestfulRequestItem requestItem = new
RestfulRequestItem(servletRequest, token, converter);
    ResponseItem responseItem = getResponseItem(handleRequestItem(requestItem));

    if (responseItem.getError() == null) {
       PrintWriter writer = servletResponse.getWriter();
       writer.write(converter.convertToString(responseItem));
    } else {
       sendError(servletResponse, responseItem);
    }
  }

Also here is more precisely the code that throws the exception, line
11, when calling IOUtils.toByteArrays(...) from our commons-io-1.4.jar
library, same version used by Shindig:

  public RestfulRequestItem(HttpServletRequest servletRequest,
SecurityToken token,
      BeanConverter converter) {
    super(getServiceFromPath(servletRequest.getPathInfo()),
        getMethod(servletRequest),
        token, converter);
    this.url = servletRequest.getPathInfo();
    this.params = createParameterMap(servletRequest);

    try {
      ServletInputStream is = servletRequest.getInputStream();
      postData = new String(IOUtils.toByteArray(is));
    } catch (IOException e) {
      throw new RuntimeException("Could not get the post data from the
request", e);
    }
  }


Would love some explanation here if anyone has the time! Is there a
compelling reason to check for a body at any time on a GET request?

Thanks,
Taylor

Re: Shindig checks for POST body on GET REST requests

Posted by Taylor Singletary <ts...@linkedin.com>.
Hello Shindig-Dev,

A colleague of mine at LinkedIn, Raul Bajales, has submitted a patch to fix
this issue. I've confirmed that the native Ruby HTTP client, Net::HTTP, and
the native PHP HTTP client (non-Curl) can now make GET requests against the
REST API without issue after this patch.

Previously, it was required to use Curl in PHP or an alternate HTTP client
in Ruby to get these GET-based requests to function properly. It may have
effected other HTTP clients that (erroneously or not) specified an empty
body header on GET requests.

We would love to see this patch make it into the official release for
Shindig.

The patch can be found attached to this JIRA issue:
https://issues.apache.org/jira/browse/SHINDIG-593

Thanks,
Taylor Singletary
Technical Evangelist
LinkedIn


On 9/11/08 11:36 AM, "Cassie" <do...@apache.org> wrote:

> that would be great.
> 
> On Wed, Sep 10, 2008 at 10:31 AM, Taylor Singletary <
> taylorsingletary@gmail.com> wrote:
> 
>> Thanks for the response, Cassie. We are looking into this now and
>> we'll get back to you.
>> 
>> Regardless of what we determine our ruby client is doing specifically,
>> would you like me to file a bug in the Shindig JIRA on this?
>> 
>> Thanks,
>> Taylor
>> 
>> On Tue, Sep 9, 2008 at 5:47 PM, Cassie <do...@apache.org> wrote:
>>> There is not a compelling reason to check the post body on a get request.
>> If
>>> you just hit the restful urls in your browser this code will not throw
>> any
>>> exceptions - so I am sure we just overlooked this fact.
>>> 
>>> In your ruby usage will the stream be null? Or will available() be false?
>> Or
>>> is there any other easy condition to check on the inputStream?
>>> I suppose we could also just catch the exception and set the postData to
>>> null. Then, if the handler needs to access that data it can handle the
>>> nullness accordingly.
>>> 
>>> - Cassie
>>> 
>>> 
>>> On Tue, Sep 9, 2008 at 6:43 AM, Taylor Singletary <
>>> taylorsingletary@gmail.com> wrote:
>>> 
>>>> Hi all,
>>>> 
>>>> I'm having a small problem getting Shindig's REST support to work
>>>> reliably with vanilla Net::HTTP Ruby libraries. I believe that this
>>>> might effect other http clients as well, though I have managed to get
>>>> at least two alternate HTTP clients to interface with the REST APIs
>>>> without difficulty.
>>>> 
>>>> The problem appears to be that Shindig checks for a BODY in an
>>>> incoming GET request. This checking for a BODY that doesn't actually
>>>> exist results in this error:
>>>> 
>>>> java.lang.RuntimeException: Could not get the post data from the request
>>>> 
>>>> 
>> org.apache.shindig.social.opensocial.service.RestfulRequestItem.<init>(Restfu
>> lRequestItem.java:76)
>>>> 
>>>> 
>> org.apache.shindig.social.opensocial.service.DataServiceServlet.handleSingleR
>> equest(DataServiceServlet.java:94)
>>>> 
>>>> 
>> org.apache.shindig.social.opensocial.service.DataServiceServlet.doPost(DataSe
>> rviceServlet.java:79)
>>>> 
>>>> 
>> org.apache.shindig.social.opensocial.service.DataServiceServlet.doGet(DataSer
>> viceServlet.java:47)
>>>> javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
>>>> javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
>>>> 
>>>> 
>> org.apache.shindig.social.core.oauth.AuthenticationServletFilter.doFilter(Aut
>> henticationServletFilter.java:89)
>>>> 
>>>> Actual error:  the actual exception thrown by IOUtils is
>>>> "java.net.SocketTimeoutException: Read timed out"
>>>> 
>>>> Granted, the Net::HTTP library in some way must be indicating a Body
>>>> header but providing no content inside, but it remains that Shindig
>>>> shouldn't be checking for a body on a GET request. Is there any reason
>>>> that it is doing so?
>>>> 
>>>> Managed to track it down to the following code (revision 688930, but
>>>> current doesn't look to have changed much here):
>>>> Our source is rev 688930, but the last version didn't changed much in
>> the
>>>> 
>>>> private void handleSingleRequest(HttpServletRequest servletRequest,
>>>>       HttpServletResponse servletResponse, SecurityToken token,
>>>>       BeanConverter converter) throws IOException {
>>>>    RestfulRequestItem requestItem = new
>>>> RestfulRequestItem(servletRequest, token, converter);
>>>>    ResponseItem responseItem =
>>>> getResponseItem(handleRequestItem(requestItem));
>>>> 
>>>>    if (responseItem.getError() == null) {
>>>>       PrintWriter writer = servletResponse.getWriter();
>>>>       writer.write(converter.convertToString(responseItem));
>>>>    } else {
>>>>       sendError(servletResponse, responseItem);
>>>>    }
>>>>  }
>>>> 
>>>> Also here is more precisely the code that throws the exception, line
>>>> 11, when calling IOUtils.toByteArrays(...) from our commons-io-1.4.jar
>>>> library, same version used by Shindig:
>>>> 
>>>>  public RestfulRequestItem(HttpServletRequest servletRequest,
>>>> SecurityToken token,
>>>>      BeanConverter converter) {
>>>>    super(getServiceFromPath(servletRequest.getPathInfo()),
>>>>        getMethod(servletRequest),
>>>>        token, converter);
>>>>    this.url = servletRequest.getPathInfo();
>>>>    this.params = createParameterMap(servletRequest);
>>>> 
>>>>    try {
>>>>      ServletInputStream is = servletRequest.getInputStream();
>>>>      postData = new String(IOUtils.toByteArray(is));
>>>>    } catch (IOException e) {
>>>>      throw new RuntimeException("Could not get the post data from the
>>>> request", e);
>>>>    }
>>>>  }
>>>> 
>>>> 
>>>> Would love some explanation here if anyone has the time! Is there a
>>>> compelling reason to check for a body at any time on a GET request?
>>>> 
>>>> Thanks,
>>>> Taylor
>>>> 
>>> 
>> 


Re: Shindig checks for POST body on GET REST requests

Posted by Cassie <do...@apache.org>.
that would be great.

On Wed, Sep 10, 2008 at 10:31 AM, Taylor Singletary <
taylorsingletary@gmail.com> wrote:

> Thanks for the response, Cassie. We are looking into this now and
> we'll get back to you.
>
> Regardless of what we determine our ruby client is doing specifically,
> would you like me to file a bug in the Shindig JIRA on this?
>
> Thanks,
> Taylor
>
> On Tue, Sep 9, 2008 at 5:47 PM, Cassie <do...@apache.org> wrote:
> > There is not a compelling reason to check the post body on a get request.
> If
> > you just hit the restful urls in your browser this code will not throw
> any
> > exceptions - so I am sure we just overlooked this fact.
> >
> > In your ruby usage will the stream be null? Or will available() be false?
> Or
> > is there any other easy condition to check on the inputStream?
> > I suppose we could also just catch the exception and set the postData to
> > null. Then, if the handler needs to access that data it can handle the
> > nullness accordingly.
> >
> > - Cassie
> >
> >
> > On Tue, Sep 9, 2008 at 6:43 AM, Taylor Singletary <
> > taylorsingletary@gmail.com> wrote:
> >
> >> Hi all,
> >>
> >> I'm having a small problem getting Shindig's REST support to work
> >> reliably with vanilla Net::HTTP Ruby libraries. I believe that this
> >> might effect other http clients as well, though I have managed to get
> >> at least two alternate HTTP clients to interface with the REST APIs
> >> without difficulty.
> >>
> >> The problem appears to be that Shindig checks for a BODY in an
> >> incoming GET request. This checking for a BODY that doesn't actually
> >> exist results in this error:
> >>
> >> java.lang.RuntimeException: Could not get the post data from the request
> >>
> >>
> org.apache.shindig.social.opensocial.service.RestfulRequestItem.<init>(RestfulRequestItem.java:76)
> >>
> >>
> org.apache.shindig.social.opensocial.service.DataServiceServlet.handleSingleRequest(DataServiceServlet.java:94)
> >>
> >>
> org.apache.shindig.social.opensocial.service.DataServiceServlet.doPost(DataServiceServlet.java:79)
> >>
> >>
> org.apache.shindig.social.opensocial.service.DataServiceServlet.doGet(DataServiceServlet.java:47)
> >> javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
> >> javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
> >>
> >>
> org.apache.shindig.social.core.oauth.AuthenticationServletFilter.doFilter(AuthenticationServletFilter.java:89)
> >>
> >> Actual error:  the actual exception thrown by IOUtils is
> >> "java.net.SocketTimeoutException: Read timed out"
> >>
> >> Granted, the Net::HTTP library in some way must be indicating a Body
> >> header but providing no content inside, but it remains that Shindig
> >> shouldn't be checking for a body on a GET request. Is there any reason
> >> that it is doing so?
> >>
> >> Managed to track it down to the following code (revision 688930, but
> >> current doesn't look to have changed much here):
> >> Our source is rev 688930, but the last version didn't changed much in
> the
> >>
> >> private void handleSingleRequest(HttpServletRequest servletRequest,
> >>       HttpServletResponse servletResponse, SecurityToken token,
> >>       BeanConverter converter) throws IOException {
> >>    RestfulRequestItem requestItem = new
> >> RestfulRequestItem(servletRequest, token, converter);
> >>    ResponseItem responseItem =
> >> getResponseItem(handleRequestItem(requestItem));
> >>
> >>    if (responseItem.getError() == null) {
> >>       PrintWriter writer = servletResponse.getWriter();
> >>       writer.write(converter.convertToString(responseItem));
> >>    } else {
> >>       sendError(servletResponse, responseItem);
> >>    }
> >>  }
> >>
> >> Also here is more precisely the code that throws the exception, line
> >> 11, when calling IOUtils.toByteArrays(...) from our commons-io-1.4.jar
> >> library, same version used by Shindig:
> >>
> >>  public RestfulRequestItem(HttpServletRequest servletRequest,
> >> SecurityToken token,
> >>      BeanConverter converter) {
> >>    super(getServiceFromPath(servletRequest.getPathInfo()),
> >>        getMethod(servletRequest),
> >>        token, converter);
> >>    this.url = servletRequest.getPathInfo();
> >>    this.params = createParameterMap(servletRequest);
> >>
> >>    try {
> >>      ServletInputStream is = servletRequest.getInputStream();
> >>      postData = new String(IOUtils.toByteArray(is));
> >>    } catch (IOException e) {
> >>      throw new RuntimeException("Could not get the post data from the
> >> request", e);
> >>    }
> >>  }
> >>
> >>
> >> Would love some explanation here if anyone has the time! Is there a
> >> compelling reason to check for a body at any time on a GET request?
> >>
> >> Thanks,
> >> Taylor
> >>
> >
>

Re: Shindig checks for POST body on GET REST requests

Posted by Taylor Singletary <ta...@gmail.com>.
Thanks for the response, Cassie. We are looking into this now and
we'll get back to you.

Regardless of what we determine our ruby client is doing specifically,
would you like me to file a bug in the Shindig JIRA on this?

Thanks,
Taylor

On Tue, Sep 9, 2008 at 5:47 PM, Cassie <do...@apache.org> wrote:
> There is not a compelling reason to check the post body on a get request. If
> you just hit the restful urls in your browser this code will not throw any
> exceptions - so I am sure we just overlooked this fact.
>
> In your ruby usage will the stream be null? Or will available() be false? Or
> is there any other easy condition to check on the inputStream?
> I suppose we could also just catch the exception and set the postData to
> null. Then, if the handler needs to access that data it can handle the
> nullness accordingly.
>
> - Cassie
>
>
> On Tue, Sep 9, 2008 at 6:43 AM, Taylor Singletary <
> taylorsingletary@gmail.com> wrote:
>
>> Hi all,
>>
>> I'm having a small problem getting Shindig's REST support to work
>> reliably with vanilla Net::HTTP Ruby libraries. I believe that this
>> might effect other http clients as well, though I have managed to get
>> at least two alternate HTTP clients to interface with the REST APIs
>> without difficulty.
>>
>> The problem appears to be that Shindig checks for a BODY in an
>> incoming GET request. This checking for a BODY that doesn't actually
>> exist results in this error:
>>
>> java.lang.RuntimeException: Could not get the post data from the request
>>
>> org.apache.shindig.social.opensocial.service.RestfulRequestItem.<init>(RestfulRequestItem.java:76)
>>
>> org.apache.shindig.social.opensocial.service.DataServiceServlet.handleSingleRequest(DataServiceServlet.java:94)
>>
>> org.apache.shindig.social.opensocial.service.DataServiceServlet.doPost(DataServiceServlet.java:79)
>>
>> org.apache.shindig.social.opensocial.service.DataServiceServlet.doGet(DataServiceServlet.java:47)
>> javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
>> javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
>>
>> org.apache.shindig.social.core.oauth.AuthenticationServletFilter.doFilter(AuthenticationServletFilter.java:89)
>>
>> Actual error:  the actual exception thrown by IOUtils is
>> "java.net.SocketTimeoutException: Read timed out"
>>
>> Granted, the Net::HTTP library in some way must be indicating a Body
>> header but providing no content inside, but it remains that Shindig
>> shouldn't be checking for a body on a GET request. Is there any reason
>> that it is doing so?
>>
>> Managed to track it down to the following code (revision 688930, but
>> current doesn't look to have changed much here):
>> Our source is rev 688930, but the last version didn't changed much in the
>>
>> private void handleSingleRequest(HttpServletRequest servletRequest,
>>       HttpServletResponse servletResponse, SecurityToken token,
>>       BeanConverter converter) throws IOException {
>>    RestfulRequestItem requestItem = new
>> RestfulRequestItem(servletRequest, token, converter);
>>    ResponseItem responseItem =
>> getResponseItem(handleRequestItem(requestItem));
>>
>>    if (responseItem.getError() == null) {
>>       PrintWriter writer = servletResponse.getWriter();
>>       writer.write(converter.convertToString(responseItem));
>>    } else {
>>       sendError(servletResponse, responseItem);
>>    }
>>  }
>>
>> Also here is more precisely the code that throws the exception, line
>> 11, when calling IOUtils.toByteArrays(...) from our commons-io-1.4.jar
>> library, same version used by Shindig:
>>
>>  public RestfulRequestItem(HttpServletRequest servletRequest,
>> SecurityToken token,
>>      BeanConverter converter) {
>>    super(getServiceFromPath(servletRequest.getPathInfo()),
>>        getMethod(servletRequest),
>>        token, converter);
>>    this.url = servletRequest.getPathInfo();
>>    this.params = createParameterMap(servletRequest);
>>
>>    try {
>>      ServletInputStream is = servletRequest.getInputStream();
>>      postData = new String(IOUtils.toByteArray(is));
>>    } catch (IOException e) {
>>      throw new RuntimeException("Could not get the post data from the
>> request", e);
>>    }
>>  }
>>
>>
>> Would love some explanation here if anyone has the time! Is there a
>> compelling reason to check for a body at any time on a GET request?
>>
>> Thanks,
>> Taylor
>>
>

Re: Shindig checks for POST body on GET REST requests

Posted by Cassie <do...@apache.org>.
There is not a compelling reason to check the post body on a get request. If
you just hit the restful urls in your browser this code will not throw any
exceptions - so I am sure we just overlooked this fact.

In your ruby usage will the stream be null? Or will available() be false? Or
is there any other easy condition to check on the inputStream?
I suppose we could also just catch the exception and set the postData to
null. Then, if the handler needs to access that data it can handle the
nullness accordingly.

- Cassie


On Tue, Sep 9, 2008 at 6:43 AM, Taylor Singletary <
taylorsingletary@gmail.com> wrote:

> Hi all,
>
> I'm having a small problem getting Shindig's REST support to work
> reliably with vanilla Net::HTTP Ruby libraries. I believe that this
> might effect other http clients as well, though I have managed to get
> at least two alternate HTTP clients to interface with the REST APIs
> without difficulty.
>
> The problem appears to be that Shindig checks for a BODY in an
> incoming GET request. This checking for a BODY that doesn't actually
> exist results in this error:
>
> java.lang.RuntimeException: Could not get the post data from the request
>
> org.apache.shindig.social.opensocial.service.RestfulRequestItem.<init>(RestfulRequestItem.java:76)
>
> org.apache.shindig.social.opensocial.service.DataServiceServlet.handleSingleRequest(DataServiceServlet.java:94)
>
> org.apache.shindig.social.opensocial.service.DataServiceServlet.doPost(DataServiceServlet.java:79)
>
> org.apache.shindig.social.opensocial.service.DataServiceServlet.doGet(DataServiceServlet.java:47)
> javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
> javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
>
> org.apache.shindig.social.core.oauth.AuthenticationServletFilter.doFilter(AuthenticationServletFilter.java:89)
>
> Actual error:  the actual exception thrown by IOUtils is
> "java.net.SocketTimeoutException: Read timed out"
>
> Granted, the Net::HTTP library in some way must be indicating a Body
> header but providing no content inside, but it remains that Shindig
> shouldn't be checking for a body on a GET request. Is there any reason
> that it is doing so?
>
> Managed to track it down to the following code (revision 688930, but
> current doesn't look to have changed much here):
> Our source is rev 688930, but the last version didn't changed much in the
>
> private void handleSingleRequest(HttpServletRequest servletRequest,
>       HttpServletResponse servletResponse, SecurityToken token,
>       BeanConverter converter) throws IOException {
>    RestfulRequestItem requestItem = new
> RestfulRequestItem(servletRequest, token, converter);
>    ResponseItem responseItem =
> getResponseItem(handleRequestItem(requestItem));
>
>    if (responseItem.getError() == null) {
>       PrintWriter writer = servletResponse.getWriter();
>       writer.write(converter.convertToString(responseItem));
>    } else {
>       sendError(servletResponse, responseItem);
>    }
>  }
>
> Also here is more precisely the code that throws the exception, line
> 11, when calling IOUtils.toByteArrays(...) from our commons-io-1.4.jar
> library, same version used by Shindig:
>
>  public RestfulRequestItem(HttpServletRequest servletRequest,
> SecurityToken token,
>      BeanConverter converter) {
>    super(getServiceFromPath(servletRequest.getPathInfo()),
>        getMethod(servletRequest),
>        token, converter);
>    this.url = servletRequest.getPathInfo();
>    this.params = createParameterMap(servletRequest);
>
>    try {
>      ServletInputStream is = servletRequest.getInputStream();
>      postData = new String(IOUtils.toByteArray(is));
>    } catch (IOException e) {
>      throw new RuntimeException("Could not get the post data from the
> request", e);
>    }
>  }
>
>
> Would love some explanation here if anyone has the time! Is there a
> compelling reason to check for a body at any time on a GET request?
>
> Thanks,
> Taylor
>