12

I'm sometimes unsure how to use webapp2.redirect.

Is there ever a time when I should use self.redirect("/blah") instead of return self.redirect("/blah")

Here is my understanding/guess of the time-line: (sometimes i'm confused about if the response object does something or if webapp2 does it)

  1. I visit my multithreaded website www.mysite.com/name/robert, chrome sends a GET request (lets assume this request is a text file)
  2. webapp2 grabs this "text file" and turns it into a webapp2.Request. webapp2 also makes a new webapp2.Response.
  3. somehow the request url is given to the router for matching (either by webapp2 or by the response). An appropriate RequestHandler is instantiated. The RequestHandler's get() method is called with appropriate arguments.
  4. throughout this time there has only been one request and one response.
  5. the get() method calls response.out.write("hello world") adding "hello world" to the response body?
  6. the get() method calls self.redirect('/foo')
  7. Stuff happens
  8. the get() method calls self.out.write("bye world")
  9. the response is sent to the client containing hello world, what food added, bye world

example of the initial get function:

def get():
    self.write('hello world')
    self.redirect('/foo')
    self.write('bye world')

What "stuff happens"? I suppose the router finds /foo/'s RequestHandler. What modifications are made to the Request and Response before foo's requestHandlers get() method is called. Is the request deleted and replaced by a new GET request? Is the response deleted and replaced by a new one? What context remains that was present in the initial request handler? does code execution return to the initial request handlers get method and if so is the context that may have existed restored?

Sorry If this is a bit of a mouthful, I've tried explaining what I want to know :)

Perhaps it would have been easier to ask for some use cases (do's and don'ts) of using redirect instead.

Rusty Rob
  • 16,489
  • 8
  • 100
  • 116

1 Answers1

11

The redirect method is really just some useful fluff around setting the response status and response Location header. Nothing really happens until the response is sent to the client which follows the redirect. You would want to return the result of calling redirect simply to avoid more code being run if there was more after the redirect that you didn't want run.

The source is quite easy to read.. http://webapp2.readthedocs.io/en/latest/_modules/webapp2.html#redirect

manRo
  • 1,455
  • 1
  • 14
  • 19
lecstor
  • 5,619
  • 21
  • 27
  • So the client gets 302 and follows the redirect. That seems inefficient (requiring two requests instead of one). If everyone is redirected to /login say, I would have thought the response would return the login form and say it was redirected all in one response, rather than two. – Rusty Rob Sep 15 '12 at 00:47
  • 1
    just to confirm, foos get() method isn't called until after the clients browser follows the redirect with a new request to the responses new location header which means foos get method could be called on a different server even. – Rusty Rob Sep 15 '12 at 00:49
  • 1
    If you want an internal redirect, you can call another handler method from your code, eg I'll update something in a post handler and return self.get() as the response. The issue, is that you're returning the content from a different resource than the server asked for. If that's ok for the situation, then, ok. If you do a redirect then the browser (or spider) knows what it's getting. As for redirecting AND providing the new response, well browsers don't work that way. to confirm: yes, and you'd lose "hello world" and "bye world" to the ether (to a browser user) – lecstor Sep 15 '12 at 05:41