My problem is simple. I need to upload a file directly to the correct server (which has currently low workload).
Therefore I do:
<?php
$server = file_get_contents('http://my-api.com/upload-server.php'); // returns url
?>
then i print my form like
<form method="post" action="<?php echo $server; ?>"...
Now I would like to shift this step to when the upload starts, like so:
<form method="post" action="http://my-api.com/upload-gateway.php"...
this url should do a redirect to the "real" server.
So that the upload page doesn't slow down loading and I have static html code that I can cache, embed etc...
Problem is that this works perfetly fine with get requests but not with post requests.
The request seems like to get transformed into a get request when redirecting using the location header. All post data is lost.
Is this impossible or am I doing it wrong? And yes, I considered a remote dynamic javascript that prints the html code with the correct server in the first place. I would rather like not to do that...
any ideas? Maby alternative uplod techniques?
edit:
this is the exact html code i use:
<form method='post' enctype='multipart/form-data' action='http://storage.ivana.2x.to/rest.php?action=target'>
<input type=hidden name=testfield value="test">
File to upload: <input type=file name=upfile><br>
Notes about the file: <input type=text name=note><br>
<br>
<input type=submit value=Press> to upload the file!
</form>
this is the redirect code i use:
if($_GET["action"] == "target") {
header("Location: http://storage.ivana.2x.to/rest.php?action=test");
}
this is the output code i use to see the results:
if($_GET["action"] == "test") {
echo "<pre>";
var_dump($_POST);
var_dump($_GET);
var_dump($_FILES);
}
the result when uploading a small file looks like:
array(0) {
}
array(1) {
["action"]=>
string(4) "test"
}
array(0) {
}
If you really want to load balance through the code while potentially caching the page with the upload form, first select the default download server (url); then, onSubmit call the server and find the best upload target and adjust the action attribute accordingly.
With this method, users who do not activate JS still get what they want, users with JS enabled get the better upload target, and you can still cache. Additionally, the timing of the cache request could potentially be more opportunistic, since the URL request will occur very shortly before the actual upload.
The only hitch will be the call to get the URL, which you can more easily performance tune (I imagine) than the process you are describing above. Uploading a file twice through a header directive and/or cURL call don't seem like a good tradeoff for caching a single html file, IMO. But I don't know what you're up against, either.
If you don't want to heavily administer the server environment and introduce load balancing, this is the option I would suggest.
Note, also, I am not a server administrator by trade.
You could try returning a code 302 (temporary moved), not 100% that would let your browser post the data to the changed url though, but it's worth something to check out.
[Edit]
According to this wikipedia article, the POST data would be converted to GET, which probably won't work for a file upload.
This is not a good solution. The file will be uploaded in it's entirety before the PHP script is even started. This means that if you succeed with what you're trying to do the client will have to upload the file twice!
I recommend that you try to figure out which server to send the request to when you're creating the form, so the action attribute in the form tag will point directly to the lesser loaded machine.
Or even better: use a serverside loadbalancer and make your HTTP infrastructure transparent to the browser. This is essentially a sysadmin problem.
i might be wrong but.. your form's action points to ?action=target
and in your rest.php you do a header to "?action=test"
well of course you wont find your $POST nor your $FILES!... a header()
does not send those variables..
if you want to send your post and your file to a differente location you'll need to use the cUrl library.. but it wont be easy :)
Good Luck