$request->files->all() is always empty - php

I'm testing my API with POSTMAN and when I try to send any file the content of $request->files->all() is always empty.
$request->server->parameters["CONTENT_LENGTH"] seems to change depending on the file size. But I don't find a way to reach the file content.
Tried also with $_FILES, but the same result.
I even did a var_dump($_FILES); in my app_dev.php directly before reaching anything else from Symfony's framework.
My php.ini seems to be alright:
file_uploads: on
upload_max_filesize: more than enough
post_max_size: more than enough
In POSTMAN I tried both ways of sending a file: binary and form-data file.
A POSTMAN code example looks like this using form-data:
PUT /retain_inspecciones/web/app_dev.php/api/planningfiles/6?files=true HTTP/1.1
Host: symfony.dev
symfonytoken: Bearer my-token
Cache-Control: no-cache
Postman-Token: 9c9cd91a-99f2-57ab-a290-966074b219f3
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="fileName"; filename=""
Content-Type:
------WebKitFormBoundary7MA4YWxkTrZu0gW--
I'm not sure of why the part where the file should be is the empty string and Content-Type is empty. But it seems to be the way POSTMAN does so.
Any idea?

Finally I decided to try curl instead of Postman and it worked on first try.
I don't know how curl differs from POSTMAN when building the request but I'm happy with it.

Related

cURL default GET request isn't recognized by PHP

I'm trying to create a simple Web service that has to return various HTTP codes depending on some conditions, mainly the existence of files related to the specific resources requested via URI. However, i'm stuck on a really strange behaviour i keep getting when I try to generate a 404 header via PHP.
The first snippet, that works, is as follows:
$isNotFound = TRUE;
if ($isNotFound) header('HTTP/1.1 404 Not Found');
Using a simple command-line cURL to request the URI behind which this script runs, I get:
$ curl -LI http://www.example.com/
HTTP/1.1 404 Not Found
Date: Wed, 18 Sep 2013 20:57.25 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Vary: Accept-Encoding
Connection: clse
Content-Type: text/html
Now, the second take is like this:
$isNotFound = FALSE;
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$isNotFound = TRUE;
}
if ($isNotFound === TRUE) {
header('HTTP/1.1 404 Not Found');
}
Running cURL again, this time I get this:
$ curl -LI http://www.example.com/
HTTP/1.1 200 OK
Date: ...
The header is the same as the former, except for the code. To check the obvious, I also printed the value of $isNotFound just before the last if, and it was indeed evaluated to TRUE, so the header call with the 404 code should be executed. I also added an exit() inside the last if, and another header() at the end of the script, giving other codes in response (like 302), and the result is always that the header inside the if is ignored.
I managed to make the second script work by explicitly specifying the request method as GET in the cURL call:
$ curl -X GET -LI http://www.example.com/
HTTP/1.1 404 Not Found
Date: ...
I also had the doubt that cURL wasn't using GET as the default method, but printing the $_SERVER array showed that the request method was indeed GET.
So, what is the reason of this strange behaviour? Is cURL's fault when using the implicit GET method, or is something happening inside PHP? Or maybe i'm so tired that i'm missing something trivial?
Thank you guys, and sorry for the long post.
Next time read the manual:
-I, --head
(HTTP/FTP/FILE) Fetch the HTTP-header only! HTTP-servers feature the
command HEAD which this uses to get nothing but the header of a
document. When used on an FTP or FILE file, curl displays the
file size and last modification time only.
(or your webserver log files, or your TCP stream)

Why does XSendfile emit intermittent garbled responses when used with Symfony Components BinaryFileResponse class?

Background
Part of my application's responsibility is handling requests for static resources (CSS, JavaScript, images) in a controlled manner. Based on some application logic, it will return one from a selection of different files that might be served on that URL at different times and to different users. These are therefore static files, but delivered in a dynamic way.
The application is based on Symfony Components and the serving of these static-ish files is handled by the BinaryFileResponse class.
The bootstrap code calls the trustXSendfileTypeHeader method:
\Symfony\Component\HttpFoundation\BinaryFileResponse::trustXSendfileTypeHeader();
The application uses some internal logic based on configuration and the detection and use of apache_get_modules() to determine availability. If XSendfile is available and the configuration says to use it, it sets the X-Sendfile-Type header:
if ($useHeader === true) {
$request->headers->set('X-Sendfile-Type', $header);
}
$response = new BinaryFileResponse($filename);
Problem
When I run this with the configuration set to never use XSendfile, or through the PHP built-in web server, which obviously does not support XSendfile, everything is perfect.
When I utilise XSendfile, it also works -- most of the time.
Every so often, typically if I press the f5 key 3-4 times in quick succession, "something" wigs out and I get a garbled response. For example, this is supposed to be a JavaScript file (copied from "Response" tab under "Net" in Firebug):
hxYîãx��HTTP/1.1 200 OK Date: Tue, 05 Feb 2013 14:49:10 GMT Server:
Apache/2.2.22 (Ubuntu) X-Powered-By: PHP/5.4.6-1ubuntu1.1
Cache-Control: public Last-Modified: Tue, 29 Jan 2013 13:33:23 GMT
Accept-Ranges: bytes Content-Transfer-Encoding: binary ETag:
"10426f-9f6-0" Vary: Accept-Encoding Content-Encoding: gzip
Content-Length: 1011 Keep-Alive: timeout=5, max=98 Connection:
Keep-Alive Content-Type: application/javascript
������­VmoÛ6þ,ÿkÀ²ãIý°~q [Üt]
XÑt¶H¤#Rv¼Àÿ}w(YSÀØ2yïå¹*¾Á>¯¥¥,è) Æ^Ât¸BaÆ\éjgäjí
Î&ð*¸Åí¸tY!³Ç$Óe"jÞ![#,n®®oï®A¨þ¸þù××Þ©¼¼ôÇêÚd¹49mv°ÔrtBÖ^;WÍÓÔg´Y¥´FéôÁR9o°35Îà^º­´N=UÐè­Eµ¢XE¸íÒ%ª°¨Úò7¬KñT¾{;£ÈrTnß³étUè{QÀçÍn·:'üJëQÍÄËZeNjOàyÕÁ:#3wö~4Òét1ù$µeN)RD|
¶FTØJ·ß½¥¨¸õGç >9TyÜxzgl-J:) b«9ûAQ½KXÉ!yÐÓ]
óÆÎ#W¡?¢vún­·7j©ÿ¢ðõÖGEÁy\ºp¤÷cKxf?ï*¼Éç0^ïîÌÇ°ñDQ¸mYJ|4t¾ñæËÛ¯Å
¨6:çøp(}þÑò|LÂ;Õ(#v¹* /[¨U|xª
æ]ÍyìjµòÛ¯p?4sI¥"v÷ôp|uQ4ò4&Ï·$eÒc¸ xo%7Ôi´2ñx;TuÙj23 áÊ%ħ¿¹lÌwÀS.&ÏØß7¸}ó
ZXzå k2'Zdùè
�¦ºû-Ù[Ó²ÿU(¯¤¥=pÃjô¾ç]]Øhhô²×ÙãÚÍ4¨[!Õ}'Òþ^Ð�ûxÿ#+ÚVÞ~áÌáy?d
aíD¹·U×ÃÚ]­ õ5íÃø¨o÷ÂAvUÆmÍaày`¦ä©A?mL[-}®(ÿË
d°öò¬}Ç¢³Çp1À^6%0 hTô^ts´ÞíWô
fO¶ö¢ÎNÜæ·HîUôÔ¶±ÌCµsxh.9åçi Û·_ÈÞØ_ÄãY_Ö}G<ì°ý2wÔ¿aw8/þù\ã±þ"0C
oÂh'tE¶À¤¥7I½éßRt.s?á^d|k/Æ)wRw÷cG¿<Þ
¼´°/^ø*ʤAVZ×y¿zÅΪ¥[²Õ1ò_Vµæï_YXÁÕö ��YXÁÕö ��
Note the presence of the headers in the response body, and the rest of it which is clearly not JavaScript. There are also some spurious characters at the start, which possibly is what leads to the headers being pushed to the body. I have tried to determine if this content is the result of gzipping, but I can't confirm that yet. (See also update below)
Question
Firstly, is BinaryFileResponse even the correct class to use for serving text (non-binary) files? The documentation for the class only says "BinaryFileResponse represents an HTTP response delivering a file." This isn't very detailed but it doesn't say anything about it being exclusively for "binary" files. However the name has its own implications, why didn't Fabien just call this class FileResponse?
Secondly, and more importantly, what could be causing this? I don't believe it is a browser issue because it is repeatable in both Firefox and Chrome. Is this a bug in the XSendfile module or in the BinaryFileResponse class perhaps? (I am likely to think it is not the former because I have used it before in a more "raw" way not via Symfony Components, with no such issues).
Has anyone else experienced this? Any idea where I should even start looking to track this down? I've looked at the BinaryResponseFile source code but it doesn't really do much with XSendfile, just sets the relevant header and prevents content in the response body, from what I can see.
Update
I've just noticed a couple of things about these garbled responses:
There are no actual headers being sent at all, i.e. on the "Headers" tab in Firebug, for the garbled responses, it only lists Request headers and doesn't even show the heading for Response headers.
Even if I set some custom header on the Response in PHP, that header does not appear at all in the garbled responses (as a header or in the response body), but the custom headers appear correctly for the responses that aren't broken.
First, let me say that I don't have any experience with this Apache module, but I'll try to guide you through a general error deduction:
You should check if you can reproduce it more reliably. While a web browser might be ok to try it out, you should go for something like curl and do the request multiple times, for example using a bash for-loop.
for i in `seq 1 5`; do curl -v http://localhost/xsendfile-url; done
The fact that the Connection: Keep-Alive header is set and that there are some weird characters before the actual HTTP header lead me to believe that you won't be able to reproduce this problem with separated curl calls, because it will open a fresh connection each time. So try this to check if that gives you the weird behavior (curl has keep alive on by default):
curl -v http://localhost/xsendfile-url http://localhost/xsendfile-url http://localhost/xsendfile-url
Using this, you could go to the projects github issue page and report your findings. Most probably they will there help you in telling you why mod_xsendfile is behaving the way it is or that you have found a bug.

header not setting Content-type as expected

I have a joomla php/script that returns json but as text/html because if I return it as application/json it downloads a file instead of interpretating it.
To do this I use:
header("Content-Type: text/html; charset=utf-8",true);
flush();
echo json_encode(($imgChanging>0)?$thmbName:0);
which works fine on 2 different servers (php 5.3.3-7 + squeeze14 and php 5.4.4-2), but it doesn't work in another server with php 5.3.14, instead of returning text/html it returns application/json. Everything else works fine, and I haven't found this bug for this php version. How can I solve this?

PHP MAMP and server conflicts

I have a page that calls a php script. On MAMP everything works fine but when I upload it to a server I get the following error:
Call Request failed! Status code: 4000
Reason - Caught an HttpRequestValidationException due to some bad characters in the request. Make sure your post request is encoded as xml, preferable as UTF-8 ('Content-Type: text/xml; charset=utf-8'). Exception: A potentially dangerous Request.Form value was detected from the client (<?xml version="..."utf-8"?> <uclassify xmlns="ht...").
Has anyone seen anything like that?
you can check it yourself here just place a word like php or ios
It looks like your server is validating based on the content-type header. It seems to want text/xml, whereas you are sending application/x-www-form-urlencoded (which is the default for $.ajax).
Try explicitly setting the content type to text/xml in your $.ajax call. (reference)
try changing charset=utf-8 to charset=UTF-8

POST files uploading - multipart/form-data + UTF bug in PHP?

When I try to upload files using HTTP post with header Content-Type: multipart/form-data; boundary=-----NPRequestBoundary----- everything works as expected but trying to use Content-Type: multipart/form-data; boundary=-----NPRequestBoundary-----; charset=UTF-8 cause completely blank $_FILES array.
Is it a problem with PHP or web server? As I know this form of Content-Type is valid.
Because the Content-Type is multipart/form-data, this means it is built up from parts, and every part can have its own Content-Type. The charset parameter is only used with text/plain content-type. So it is meanless with a multipart/form-data content-type.
Bug was fixed in SVN rev. #316373 (5.3.9 release covers it).
I've found dirty workaround for this problem. For me it's ofc temporary bcs it doesn't work under litespeed (I used reverse proxy to apache to avoid this problem).
<Location "/upload.php">
RequestHeader set Content-Type "multipart/form-data; boundary=-----NPRequestBoundary-----"
</Location>
It will force webserver to replace content-type header. For now I'm sure - this is a PHP bug (someone assumed that charset will occur before boundary=)

Categories