Post vs Get

Why is this that if I make a post request without a "/" at the end of the url I can't access the params with $_POST[] in php but the param is available in the $_REQUEST. Is there something that I am doing wrong?
Here is my code 

``` python
import requests
# version1 - POST params are accessible 
payload = {"message": "my message here"}
r = requests.post("http://localhost/apps/myapp/", data=payload)
print r.text

# version2 - POST params not available
r = requests.post("http://localhost/apps/myapp", data=payload)
print r.text
```


My guess is that your PHP app redirects from the URL that doesn't have a `/` to the one that does, and when it does so it uses a status code that causes us to convert our POST to a GET.

You should check what your PHP application is up to.


@Lukasa - there is no redirection in my php code. this is what the myapp index.php file looks like 

``` php
<?php 
echo "dasdasd";
echo json_encode( $_POST );
exit();
?>
```


In both cases can you `print r.history` from your Python code?


sorry! with the  / , the history response is 

``` python
[]
```

while the other one the response is 

``` python
<Response [301]>
```


So as you can see, the second request _is_ being redirected. Your PHP application may not be doing it on purpose, but it's definitely happening.


@Lukasa realized the same thing too. Just seen a note from this link http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html that 

```
Note: When automatically redirecting a POST request after
receiving a 301 status code, some existing HTTP/1.0 user agents
will erroneously change it into a GET request.
```

The redirection might be in the server configuration if the fallback is not done in the requests lib..


Yeah, 'erroneously' is an out-of-date note. From the more recent RFC 7231:

> Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request.  If this behavior is undesired, the 307 (Temporary Redirect) status code can be used instead.


@Lukasa do you have an alternative fix for this that would force the post request to be treated as a post no matter what?? Its an app that I am building that would require developers to put their urls so that I can ping their url with post params only. 


@mutindaz so you _might_ be able to do something like

``` py
is_redirect = True
while is_redirect:
    r = requests.head(url)
    is_redirect = r.is_redirect
    url = r.headers.get('Location', url)
requests.post(url, data=payload)
```

But there are some issues with doing that.
1. The site may not react well to a `HEAD` request at that resource
2. The URI in the `Location` header may not be a URL of the form `{scheme}://{host}/{path}` but could be only parts of that and so requests will barf
3. That could loop forever if there's a redirect loop.

That would be a "simple" way of doing it (although there are things wrong with it).

The more difficult thing to do would be to handle the request/redirect cycle yourself. For that, you'll need to begin using a session object and the `Request` objects. I don't use those frequently so I can't just hammer out a rough example for you but it would look something like (this is very much pseudo-code):

``` py
session = requests.Session()
request = requests.Request(method='POST', url=url, data=payload)
prepped = session.prepare_request(request)
response = session.send(prepped)
while response.is_redirect:
    prepped, old_prepped = prepped.copy(), prepped
    # Lift some of https://github.com/kennethreitz/requests/blob/ca66267d2cf8adc67ed8857f3f57b45ffde21e01/requests/sessions.py#L119..L139
    prepped.url = to_native_string(url)
    response = session.send(prepped)
```

That assumes a few things:
1. That you have no concern for exposing data to a server that shouldn't see it (which is why on certain redirects we change the method and remove the body)
2. That you are certain that handling these redirects is what you want to do
3. That you don't care about preserving the history
4. That you're willing to follow an arbitrary and unknown (and potentially infinite) number of redirects

Personally, I think we could factor the url handling in [this section of code](https://github.com/kennethreitz/requests/blob/ca66267d2cf8adc67ed8857f3f57b45ffde21e01/requests/sessions.py#L119..L139) out into its own method like we have `prepare_request` but this is such a 2% use-case that I'm not confident it will be a worthwhile refactor.