- Home /
$_FILES is empty when I send a file from WWWForm
Hi, I'm trying to send a file to a server using WWWForm, but I have a problem of $_FILES receiving it, it doesn't receive any data, I checked that both (the $_FILES["name"] and filed name) are the same.
I've been reading that maybe is because the form is sent with application/x-www-form-urlenconded, but I tried to put in the headers the Content-Type as "multipart/form-data" and it results in a error "400 Bad Request".
Also I tried to use UnityWebRequest and FormMultipartFileSection instead of WWW and WWWForm, but I'm getting a error code 400 with "Generic/Unknown HTTP error"
Any clues of what is happening? (I'll post my cs and php codes below)
Regards
IEnumerator UploadFileCo(string localFileName, string uploadURL)
{
WWW localFile = new WWW("file:///data/user/0/com.HeXentic.IldemaroApp/cache/PickedImage.jpg");
Debug.Log("IMAGE PATH TRYING TO LOAD IS: " + localFile.url);
yield return new WaitUntil(() => localFile.isDone);
if (localFile.error == null)
Debug.Log("Loaded file successfully");
else
{
Debug.Log("Open file error: " + localFile.error);
yield break; // stop the coroutine here
}
Texture2D tex = new Texture2D(163, 224, TextureFormat.RGBA32, false);
WWW w = new WWW("file:///data/user/0/com.HeXentic.IldemaroApp/cache/PickedImage.jpg");
yield return new WaitUntil(() => w.isDone);
//tex = texture;
if (w.bytesDownloaded > 0 && w.error == null)
{
w.LoadImageIntoTexture(tex);
for (int i = 0; i <= profilesImages.Length - 1; i++)
{
profilesImages[i].GetComponent<RawImage>().texture = tex;
}
//byte[] imageBytes = tex.EncodeToJPG();
//FileStream fileSave;
//fileSave = new FileStream(Application.persistentDataPath + "/Save/picture.jpg", FileMode.Create);
//BinaryWriter binary;
//binary = new BinaryWriter(fileSave);
//binary.Write(imageBytes);
//fileSave.Close();
/* for (int i = 0; i <= imageBytes.Length - 1; i++)
{
Debug.LogWarning("IMAGE BYTES INDEX: " + i + " VALUE = " + imageBytes.GetValue(i));
}*/
//WWWForm postForm = new WWWForm();
// version 1
//postForm.AddBinaryData("theFile",localFile.bytes);
// version 2
//postForm.AddBinaryData("archivo-a-subir", w.bytes , "demo.jpg" + ".jpg", "image/jpeg");
//Dictionary<string, string> headers = postForm.headers;
//headers.Add("enctype", "multipart/form-data");
//postForm.AddField("test","test");
Debug.Log("Trying to upload the file: " + tex.GetRawTextureData());
Debug.Log("In the URL: " + uploadURL);
Debug.Log("With the name of: " + UserAccountInfo.instance.email.Replace(".", "_") + ".png");
//WWW upload = new WWW(uploadURL, postForm.data, headers);
//////////////////////////////////////////////
/// CON UNITY WEB REQUEST
//////////////////////////////////////////////
/*
List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
formData.Add(new MultipartFormFileSection("archivo-a-subir",tex.EncodeToPNG(), UserAccountInfo.instance.email.Replace(".","_") + ".png","image/png"));
//WWWForm postForm = new WWWForm();
//postForm.AddBinaryData("archivo-a-subir", tex.EncodeToPNG(), UserAccountInfo.instance.email.Replace(".", "_") + ".png", "image/png");
//Dictionary<string, string> headers = postForm.headers;
//headers["Content-Type"] = "multipart/form-data";
//byte[] formData = postForm.data;
UnityWebRequest upload = UnityWebRequest.Post(uploadURL, formData);
upload.SetRequestHeader("Content-Type", "multipart/form-data");
upload.SetRequestHeader("Content-Disposition","form-data");
yield return upload.SendWebRequest();
*/
//////////////////////////////////////////////
/// CON WWW
//////////////////////////////////////////////
WWWForm postForm = new WWWForm();
Dictionary<string, string> headers = new Dictionary<string, string>();
headers.Add("Content-Type", "multipart/form-data");
foreach (KeyValuePair<string, string> kvp in headers)
{
//textBox3.Text += ("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
Debug.Log("Key = " + kvp.Key + ", Value = "+ kvp.Value + " ");
}
//headers["Content-Disposition"] = "form-data";
//postForm.AddBinaryData("archivo-a-subir", w.bytes , UserAccountInfo.instance.email.Replace(".", "_") + ".jpg", "image/jpeg");
postForm.AddBinaryData("archivo-a-subir", tex.EncodeToPNG(), UserAccountInfo.instance.email.Replace(".", "_") + ".png", "file");
//postForm.AddField("test","test");
WWW upload = new WWW(uploadURL, postForm.data, headers ); // test 1
//WWW upload = new WWW(uploadURL, postForm.data); // Test 2
yield return upload;
yield return new WaitUntil(() => upload.isDone);
if (upload.error == null)
{
Debug.Log("upload done");
//Debug.Log("ECHO OF RESPONSE: " + upload.downloadHandler.text);
Debug.Log("ECHO OF RESPONSE: " + upload.text);
}
else
{
//Debug.Log("Error during upload: " + upload.responseCode + ": " + upload.error);
Debug.Log("Error during upload: " + upload.error);
}
}
else
{
Debug.LogError("ERROR EN OBTENER LA TEXTURA DE LA UBICACION EN EL TELEFONO");
}
}
subir-archivos.php (in the server)
<?php
$target_path = "upload/";
$target_path = $target_path . basename( $_FILES['archivo-a-subir']['name']);
echo "\nTarget Path set as " . $targetPath;
echo "\ntrying to move it";
echo "\ngetting name property" . $_FILES['archivo-a-subir']['name'];
echo "\ngetting temp_name property" . $_FILES['archivo-a-subir']['tmp_name'];
if(move_uploaded_file($_FILES['archivo-a-subir']['tmp_name'], $target_path))
{
echo "\nEl archivo ". basename( $_FILES['archivo-a-subir']['name'])." ha sido subido exitosamente!";
}
else
{
echo "Hubo un error al subir tu archivo! Por favor intenta de nuevo.";
}
?>
Hi!
I have the same problem !
Did you make it work ?
Best regards !
"400 Bad Request" could be any number of things. Is that the most verbose thing you're getting from the response?
@Skylabs Hi, I didn't solve the problem and unfortunatelly because of that I had to stop that project... I saw somewhere else that this is kind of Unity Bug from 5.1 (which is supposed to be fixed in the 5.1.3). Even at some point I though that the problem was the server (even if we know that this is a 400 error) and I moved my files to other server but the problem still happening, probably is because the data that I was trying to upload... some other ppl tried without the image upload and works fine
Answer by Bunny83 · Sep 05, 2018 at 09:12 PM
You don't seem to have the slightest idea how multipart content works since you completely ignore the headers that the WWWForm is providing and you create your own headers the wrong way.
For multipart posts the Content-Type header needs a boundary that is used to seperate the multiple parts from another. This is usually just a random string of characters. The WWWForm class does generate a boundary which is actually used in the data it composes. However this boundary needs to be announced in the header. The multipart format is roughly explained here.
However you don't really have to care about that as the WWWForm does all this for you. Usually you don't have to tinker with the headers so you can simply pass the WWWForm directly to the WWW constructor. However if you want to add additional headers you should first setup your WWWForm with all parts, after that get the headers from the WWWForm, add your own headers and then pass the custom headers dict to the WWW constructor.
Though do not overwrite the Content-Type header as it actually contains the boundary that the WWWForm uses.
edit
I just realised another quite important error which will make any server to reject the posted data. As mentioned below you passed "file" as mime type to AddBinaryData. This of course is not a valid mime type. Either remove the last parameter completele (Unity has an overload without the mimetype) or provide the correct mimetype yourself.
You have a lot of commented out code fragments where some are slightly more correct than the current code. Though my original answer still applies: Do not try to overwrite the Content-Type request header. Also note that the "Content-Disposition" header(s) can not be added to the headers dictionary as they apply to the actual multipart request body. Each section has it's own headers which can't be manipulated with the WWWForm. The assembly of the post body is done by the WWWForm class. The Content-Disposition is always "form-data" and the name is set to the provided name. Just have a look here
Yea I created those because when I tried to do without the headers it gives me the Uknown HTTP Error and for the other side it gives me the "Bad request"... one way or another and I had the same problem (Unfortunatelly since we threw the project I deleted the files in the server so I can't really check if the problem still happening)
I did use multipart WWW posts something like 5 years ago and didn't have any issues with them. If i run into any issues i would use wireshark to figure out any issues. The WWWForm does nothing really special, just have a look yourself.
There are countless of things you can setup the wrong way in your PHP config. However setting up a webserver is out of scope of UnityAnswers.
Answer by Skylabs · Sep 06, 2018 at 06:43 AM
HI @HeXenticSpA
I finally managed to do it working :-)
So first, the png encoding ImageConversion.EncodeToPng never worked for me but ImageConversion.EncodeToJPG(tex) without setting the quality seems to work.
Secondly i changed the mime type.
Here is my request :
List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
formData.Add(new MultipartFormDataSection("id", s.id.ToString()));
formData.Add(new MultipartFormDataSection("x", s.x.ToString()));
formData.Add(new MultipartFormDataSection("y", s.y.ToString()));
formData.Add(new MultipartFormDataSection("id_vv", s.main_id.ToString()));
formData.Add(new MultipartFormDataSection("eye", s.eye));
**formData.Add(new MultipartFormFileSection("equi", *ImageConversion.EncodeToJPG(s.tex)*, "tile.jpg", "*image/jpeg*"));**
UnityWebRequest www = UnityWebRequest.Post(Const.serverURL + "/api/vv/tile", formData);
Before the mimetype on the add of the jpg file was ""image/jpg", i changed for "image/jpeg" and magically it worked :-)
I don't know if it's that or ImageConversion.EncodeToJPG(tex) (and no ImageConversion.EncodeToJPG(tex, quality).
So try to change the mime type to "image/jpeg" and the encoding to jpg :-D
Well, it's no wonder why it didn't work with "image/jpg" as this is not a valid mime type. See this SO question for more details.
The WWWForm will (when not provided with a mimetype) use "image/png" if it detects the "png magic" header, otherwise it will use the generic "application/octet-stream" mime type for everything else. If your server does not accept this mimetype you have to provide the mime type yourself. The most up-to-date mime type list can be found here
I just realised that the OP actually passed "file" as mime type which of course is not a valid mimetype. So he didn't paid attention to the parameter names. Just removing the "file" at the end should work.
$$anonymous$$eep in $$anonymous$$d that this question is not your question and answers should focus on the question. You had a similar problem but this is not your question.