Q: Trouble rewriting urls I'm using nginx as a reverse proxy for a service running on port 8080 of the local machine. Additionally I need to prefix paths sent to the upstream with /vp. This is simple and I have a working location block for it:
location ~ ^/(.*?)$ {
    proxy_pass $scheme://127.0.0.1:8080/vp/$1;
    proxy_set_header Host $host;
    proxy_redirect $scheme://$host/vp/ $scheme://$host/;
}

So the above would support a url like example.com/resource and work perfectly.
However, I also want to support urls like example.com/vp/resource. For this I have to write another location block or else it would passed to the upstream as /vp/vp/resource which doesn't work.
location ~ ^/vp/(.*?)$ {
    rewrite /vp(.*?)$ /$1;
}

The above works and now I have support for urls like example.com/vp/resource. 
But I have one last thing I'd like to fix. When a user would access example.com/vp/resource I want the url in the browser to be rewritten to just example.com/resource. My above configuration does not do this and I do not know how to modify it so that it does. I thought the point of rewrite was to rewrite urls seen in the browser but that doesn't seem to be the case. 

A: First I tried change this:
location ~ ^/vp/(.*?)$ {
    rewrite /vp(.*?)$ /$1;
}

to this:
location ~ ^/vp/(.*?)$ {
    return /$1;
}

And this mostly worked. All URIs starting with /vp would be redirected to ones without which would change the url in the browser. However, this had the side effect of making POST requests not work. This is because the POST request never actually makes it to the upstream server. Instead the POST returns the 301 redirect immediately, without a proxy pass. The browser then GETS the redirect Location and that's the end.
So I needed to selectively return a true 301 only when the request was NOT a POST and when it was I needed to proxy_pass it. After reading the If is Evil I learned I can't use a proxy_pass inside of an if (inside of a location), only return and rewrite. Doing reading on rewrite, I learned that it rewrites the URI of a request but doesn't send it back to the client immediately. Instead it runs the newly rewritten URI against all the location blocks and executes whichever one matches. So in my case I just needed to use a rewrite to execute my original location block.
My final config ended up looking like this:
location ~ ^/vp/(.*?)$ {
    if ($request_method = POST ) {
      rewrite /vp(.*?)$ /$1;
    }

    if ($request_method != POST) {
      return 301 /$1;
    }
}

location ~ ^/(.*?)$ {
  proxy_pass  http://127.0.0.1:8080/vp/$1;
  proxy_set_header Host $host;
  proxy_redirect $scheme://$host/vp/ $scheme://$host/;
}

