PATCH/PUT not accepting multipart/form-data file uploads? - php

Any idea why PATCH and PUT wouldn't be accepting multipart/form-data file uploads?
When I run var_dump($_FILES) it outputs array(0) { }. Any ideas why this is happening? If I POST the file, it works fine.
Below is an example of the request I am running.
Thanks in advance!
PUT /test.php HTTP/1.1
Content-Type: multipart/form-data; boundary=__X_PAW_BOUNDARY__
Host: [redacted]
Connection: close
User-Agent: Paw/2.1.1 (Macintosh; OS X/10.10.2) GCDHTTPRequest
Content-Length: 17961
--__X_PAW_BOUNDARY__
Content-Disposition: form-data; name="avatar"; filename="default.png"
Content-Type: image/png
PNG
[IMAGE DATA]
--__X_PAW_BOUNDARY__--

When uploading files using a PUT request you don't use multipart/form-data. A PUT request is almost the same as a GET request. All you should be doing is putting the contents of the file in the body of the request. After that you can retrieve the file with the following code as explained in the php docs:
http://php.net/manual/en/features.file-upload.put-method.php):
<?php
/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");
/* Open a file for writing */
$fp = fopen("myputfile.ext", "w");
/* Read the data 1 KB at a time
and write to the file */
while ($data = fread($putdata, 1024))
fwrite($fp, $data);
/* Close the streams */
fclose($fp);
fclose($putdata);
?>

Related

PHP: Receiving PDF file via POST

I use a program called Nitro PDF to design PDFs, it has an option to create forms with submit buttons that submit to a URL. I tried to make a php script that would receive the PDF file and write it to disk but I can't figure out how to make this happen because normally you have to specify a name on $_FILES to receive it like "fileToUpload". Here is what it is sending to the server and then it starts sending the actual file:
POST /pdf.php HTTP/1.1..
Accept: */*..
Content-Type: application/pdf..
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0;Windows NT 5.1)..
Host: 192.168.3.212..
Content-Length: 481677..
Connection: Keep-Alive..
Cache-Control: no-cache....
It's not being posted as a form, the PDF is being put directly into the POST data, which you can read with php://input.
<?php
copy("php://input", "filename.pdf");

HTTP PUT to unique filename in PHP

I would like to use HTTP to transfer a file to a webserver and save it with a meaningful filename. I currently have the transfer part working, I need to make the meaningful filename piece work.
If I use Curl to transfer the file, I specify which file to send:
curl -X PUT http://user:passwd#x.x.46.9/put.php --data-binary "session"
The PHP script on the webserver is as follows:
/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");
/* Open a file for writing */
$fp = fopen("myputfile.ext", "w");
/* Read the data 1 KB at a time
and write to the file */
while ($data = fread($putdata, 1024))
fwrite($fp, $data);
/* Close the streams */
fclose($fp);
fclose($putdata);
?>
Is there a way to extract the filename sent in the HTTP PUT message and use this for the filename? Or, at the very least, is there a way to save the file using the IP address of the source device?
Much obliged.
Yes, you have all that information in the $_REQUEST variable.

HTTP PUT Request: Passing Parameters with File

After numerous various tests with uploading files throught HTTP POST Request, it looks that HTTP PUT Requests are the most suitable for very large files +1GB upload.
The below listed simple code I have tested for HTTP PUT file upload request works well:
JavaScript:
var req = createRequest();
req.open("PUT", "PHP/filePutLoad.php");
req.setRequestHeader("Content-type", "text/plain");
req.onload = function (event)
{
console.log(event.target.responseText);
}
req.send(aUploadedFile.file_object);
PHP:
include 'ChromePhp.php';
require_once 'mysqlConnect.php';
ini_set('max_execution_time', 0);
ChromePHP::log( '$_PUT :' . print_r($_PUT));
/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");
/* Open a file for writing */
$fp = fopen("myputfile.ext", "w");
/* Read the data 1 KB at a time and write to the file */
while ($data = fread($putdata, 1024))
fwrite($fp, $data);
/* Close the streams */
fclose($fp);
fclose($putdata);
However, I have difficulties delivering arguments and variables with the file being uploaded from JavaScript to PHP. For example, I need to deliver upload target folder, where the new data needs to be stored, ID of the uploader, etc..
Is there a way to combine HTTP PUT Request with HTTP POST to submit arguments?
What are my options if I wish to deliver parameters from JavaScript to PHP along HTTP PUT file upload?
Thank you.
using PUT also, it works when you append the parameters in the query string. I'm also looking for another way for this. Although, this is a workaround I'm using currently
curl -X PUT "http://www.my-service.com/myservice?param1=val1" --data #file.txt

php $_Files fails to save the file when (http) post with Qt

I am posting a form with an image with Qt (which I do not think is important) and trying to same the image in the server but my php file keeps giving me the following error.
Notice: Undefined index: imagename in C:\wamp\www\fileupload.php on line 5
I used tcp monitor to detect the messages and they seem to be fine and it is as follows.
POST /fileupload.php HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: multipart/form-data; boundary=---------------------------723690991551375881941828858
Content-Length: 467204
Connection: Keep-Alive
Accept-Language: en-US,*
User-Agent: Mozilla/5.0
Host: localhost:8089
-----------------------------723690991551375881941828858
Content-Disposition: form-data; name="imagename"
1.jpg
-----------------------------723690991551375881941828858
Content-Disposition: form-data; name="message"
This is a Test Message
-----------------------------723690991551375881941828858
Content-Disposition: form-data; name="file"; filename="1.jpg"
Content-Type: image/jpg
Then to the end image content is attached. I am using following code to save the file on the server.
<?php
$userMessage = $_POST["message"];
$imagefilename = $_POST["imagename"];
echo($userMessage.":".$imagefilename);
if($_FILES['imagename']['error'] == 0){
echo("Post is ready");
move_uploaded_file($_FILES['imagename']['error'], './1.jpg');
}else{
echo("ERROR");
}
?>
I am following following documentations but I can not get this to work. I appreciate if someone can give me a hint to solve the issue. I am using PHP 5.3.18 and apache 2.22.
http://www.tizag.com/phpT/fileupload.php
http://www.saaraan.com/2012/02/post-picture-to-facebook-user-wall-php
You've not completed your multipart request. Add this:
-----------------------------723690991551375881941828858--
to end of your post.
<?php $userMessage = $_POST["message"];
echo($userMessage);
move_uploaded_file($_FILES['file']['tmp_name'], "./{$_FILES['file'] ['name']}");
?>

Why does the php fread() function sometimes prefix each line with its length?

I am using PHP to perform a POST request from a socket. Here is a code snippet:
// open a socket connection on port 80
$fp = fsockopen($host, 80);
// send the request headers:
fwrite($fp, "POST $path HTTP/1.1\r\n");
fwrite($fp, "Host: $host\r\n");
fwrite($fp, "Referer: $referer\r\n");
fwrite($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fwrite($fp, "Content-length: ". strlen($data) ."\r\n");
fwrite($fp, "Connection: close\r\n\r\n");
fwrite($fp, $data);
$result = '';
while(!feof($fp)) {
// receive the results of the request
$result .= fread($fp, 5000);
}
However, each line of the response seems to be prefixed with its length in hex. Why is that happening?
For example, a test cgi script, to which I post, returns its environment:
BASH=/bin/bash
BASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
But my PHP function ends up with this:
f
BASH=/bin/bash
69
BASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
10
BASH_ALIASES=()
You should use HTTP/1.0, because 1.1 servers typically respond with the Transfer-Encoding: chunked (= which are the parts prefixed by hex numbers).
You could try to send a request begging for identity content encoding, but chunked is required from all HTTP/1.1 clients as transfer format, so that might be unreliabe.
Its not each line, which is prefixed with its length. As mario suggested the the Server sends the data as chunked. Every chunk begins with the length of the chunk, the data and a double newline (=> empty line). The chunk itself can contain any valid (in terms of http) data, which means, that it can also contain multiple lines.
You can use this for yourself. If you receive a chunked transfer you can give fread() the length of the chunk as parameter instead of an abritrary int (here: 5000). So you will receive the whole chunk at once.

Categories