views:

267

answers:

2

Hi,

I receive HTTP PUT requests on a server and I would like to redirect / forward these requests to an other server.

I handle the PUT request on both server with PHP.

The PUT request is using basic HTTP authentication.

Here is an example :

www.myserver.com/service/put/myfile.xml

redirect to

www.myotherserver.com/service/put/myfile.xml

How can I do this without saving the file on my first server and resending a PUT request using CURL?

Thanks!

+1  A: 

Not possible. A redirect is implicitly a GET request. You'll need to have to play for a proxy using curl.

Saving on disk is technically also not necessary, you could just pipe the reponse body directly to the request body of Curl. But since I've never done this in PHP (in Java it's a piece of cake), I can't give a more detailed answer about that.

BalusC
Thanks!Someone know how to pipe the response body with php?
benjisail
To the point: you should just write the obtained file to curl directly instead of to local file. That would already save the unnecessary step to write it to local disk file system. But PHP would implicitly save the entire file in memory or any other temp storage first. It might be configureable, but I'm not sure.
BalusC
+2  A: 

HTTP/1.1 defines status code 307 for such redirect. However, PUT is normally used by client software and you can pretty much assume no one honors 307.

The most efficient way to do this is to setup a proxy on Apache to redirect the request to the new URL.

This is how you can proxy it in PHP,

$data = file_get_contents('php://input');
$mem  = fopen('php://memory'); 
fwrite($mem, $data); 
rewind($mem);   
$ch = curl_init($new_url);                             
curl_setopt($ch, CURLOPT_PUT, true);  
curl_setopt($ch, CURLOPT_INFILE, $mem); 
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($data)); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);    
curl_exec($ch);       
curl_close($ch);  
fclose($meme);
ZZ Coder
Would that not overflow the memory in case of files > 32MB or so? +1 for the snippet regardless. Didn't think about `php://input`.
BalusC
Is there a way to do this without loading the whole file in a php variable?
benjisail
Not I know of. The problem is CURL doesn't have a way to stream the PUT body. Without reading the whole input, you don't know INFILESIZE. If memory usage is a concern, you can change "php://memory" to "php://temp".
ZZ Coder