iOS Question postmultipart and store as base64 in sql database

Gubi

Member
Licensed User
Hello,

I use the below code to upload files:

B4X:
    Dim FileUploadSQL As HttpJob
    Dim fd As MultipartFileData

    FileUploadSQL.Initialize("ProfilePictureUpload", Me)

    fd.Initialize
    fd.Dir = File.DirDocuments
    fd.FileName = "profile_pic.jpg"
    fd.KeyName = "file"
    fd.ContentType = "multipart/form-data"

    FileUploadSQL.PostMultipart(strHTTP & ServerIP & "/BQE/bqe_file_upload.php", CreateMap("action": "ProfilePictureUpload", "MitgliedsID": ActualProfile(0).MitgliedsID), Array(fd))

and on php site I use below code:

PHP:
$action = $_POST["action"];
switch ($action)
{
    Case "ProfilePictureUpload":
    $MitgliedsID = $_POST["MitgliedsID"];
     $name = $_FILES['file']['name'];

    // here you can detect if save it to directory
     $target_dir = "upload/";
     $target_file = $target_dir . basename($_FILES["file"]["name"]);

     // Select file type
     $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));

     // Valid file extensions
     $extensions_arr = array("jpg","jpeg","png","gif");

     // Check extension
     if(in_array($imageFileType,$extensions_arr) ){
 
          // Convert to base64
          $image_base64 = base64_encode(file_get_contents($_FILES['file']['tmp_name']));
          $image = 'data:image/'.$imageFileType.';base64,'.$image_base64;

          // Insert record
         //$q = mysqli_query($con,"INSERT INTO images (image) VALUES ('$image')");
         $q = mysqli_query($con,"UPDATE mitglieder SET ProfilBild = '$image' WHERE MitgliedsID = '$MitgliedsID'");
          print json_encode("Upload erfolgrich");

          // Upload file if needed
        //  move_uploaded_file($_FILES['file']['tmp_name'],$target_dir.$name);
     }
    print json_encode("Profilbild aktualisiert");
    break;
}

If I upload image with b4a it will be stored correct in sql database ("data:image/jpg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD...")
If I try to upload image with b4i it seems that no data will be arrived at database site, because only the header information "data:image/jpg;base64," will be stored in database.

TY
 

Gubi

Member
Licensed User
If you upload a file via multipartfiledata it will be stored as temp-file, that is correct. Note that the same code works with b4a but not with b4i.
 
Upvote 0

Brandsum

Well-Known Member
Licensed User
First convert it to base64 in b4i then post as string. And yes php is vulnerable to sql injections. You should use mysqli_prepare statement.
 
Upvote 0

Gubi

Member
Licensed User
Thank you for the work around, but I think it could be a bug in library iHttpUtils2 because the php error file says the uploaded filename is empty.

Part of error file: "... PHP Warning: file_get_contents(): Filename cannot be empty ..."

Again the note: the code and php script works in b4a without problems, so I think the same code should work also in b4i.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I've tested it with B4J server. The file is uploaded properly.

The handler code:
B4X:
Sub Handle(req As ServletRequest, resp As ServletResponse)
   mreq = req
   mresp = resp
   If req.ContentType.StartsWith("multipart/form-data") Then
       'parse the multipart data
       Dim parts As Map = req.GetMultipartData(File.DirApp & "/www", 10000000)
       For Each name As String In parts.Keys
           Dim p As Part = parts.Get(name)
           Log("Name: " & name)
           Log(p.TempFile & ": " & File.Size("", p.TempFile))
           Log(p.SubmittedFilename)
       Next
   End If
End Sub

The client code:
B4X:
Dim j As HttpJob
j.Initialize("", Me)
Dim fd As MultipartFileData
fd.Initialize
fd.Dir = File.DirAssets
fd.FileName = "logo.png"
fd.KeyName = "file"
fd.ContentType = "multipart/form-data"
j.PostMultipart("http://192.168.0.104:51042/FileUpload", Null, Array(fd))
Wait For (j) JobDone(j As HttpJob)

Why aren't you using B4J to implement the server? It will be simpler, more powerful and more secure.
 
Upvote 0

Gubi

Member
Licensed User
Hi Erel,

thank you for your answer but the sql database already exists longer and it is already accessed via the web browser and android app.

Are you tested the client code on b4i?
 
Upvote 0

Gubi

Member
Licensed User
I have localized the problem at other location:
In my app, first I crop a image from camera save it on my iphone to File.DirDocuments (it exists after saved).
then the saved file will be displayed in a imageview (works also correct), but if I want to upload this new image file (code see above) the server error file says:
"... PHP Warning: file_get_contents(): Filename cannot be empty ..."

If I upload a existing image file from File.DirAssets it will be uploaded without problems.
I also tried first to copy the existing image file from File.DirAssets to File.DirDocuments and then upload it. This works also fine.


Could it be that I have no access rights to the saved image file?
 
Upvote 0

Gubi

Member
Licensed User
This is my code:

B4X:
Sub InitCamera
    cam.Initialize("cam", page1)
End Sub

Sub Cam_Complete (Success As Boolean, Image As Bitmap, VideoPath As String)
    If Success Then
        If Image.IsInitialized Then
            SaveImage(Image)
        End If
    End If
End Sub

Sub SaveImage(ImageToSave As Bitmap)
    Dim out As OutputStream
    
    out = File.OpenOutput(File.DirDocuments, "image.jpg", False)
    ImageToSave.WriteToStream(out, 100, "JPEG")
    out.Close
End Sub
 
Upvote 0

Gubi

Member
Licensed User
It is the same. I have already replaced the file name

Now I found the problem:

The Quality of "100" is too high and so the filesize is about 8MB. That is too much to store in database at server side.

Thank you all
 
Upvote 0
Top