Search code examples
pythongoogle-app-enginehttp-redirectgoogle-cloud-platformgoogle-cloud-python

urlfetch_stub.py: Received a 301 to a POST. Redirecting with a GET


After upgraded to the latest SDK 1.9.17, I start to get this error when I run my project with dev_appengine.py locally

INFO     2014-12-10 09:48:33,364 myapp.py:796] Url: http://saas.examples.com/documents, payload: {'filename': u'testlink.doc', 'key': u'p1UuXhzhS4qjj2KXmFre'}
WARNING  2014-12-10 09:48:34,089 urlfetch_stub.py:451] Received a 301 to a POST. Redirecting with a GET
WARNING  2014-12-10 09:48:34,791 myapp.py:809] failed. Code: 405, error: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method is not allowed for the requested URL.</p>

My code is very simple.

        result = urlfetch.fetch(
            url=url,
            payload=json.dumps(payload),
            method=urlfetch.POST,
            headers={'Content-Type': 'application/json'})
        if result.status_code == utils.OK:
            json_result = json.loads(result.content)
        else:
            logging.warn(
                'failed. Code: %s, error: %s',
                result.status_code, result.content)

After reverting to previous version of SDK (1.9.15) the exception disappear again.

My Questions:

1) Is it a GAE bug? If so what is the proper way to report to GAE team?

2) If it is not a GAE SDK problem, how can I fix my code?


Solution

  • There was a changed made to how URLFetch handles redirect in the updated SDK.

    Long story short, basically, all redirects becomes GET method regardless of what the original method was. So if you perform a POST URLFetch and then the redirect will turn it into a GET.

    There are two ways to fix your code:

    1) Use GET Method for all URLFetch that contains redirect

    2) Do not use redirects and target the final URL directly

    From your error though, it seems like the target URL isn't accepting GET requests? If that's the case do a POST to it directly.

    See this link for details on URLFetch - https://cloud.google.com/appengine/docs/python/urlfetch/#Python_Fetching_URLs_in_Python

    See this link for details on the SDK release - https://code.google.com/p/googleappengine/wiki/SdkReleaseNotes#Version_1.9.14_-_October_21,_2014