Sending form with several fields but one field encoded in base64 using Network.request

Greetings and thanks in advance for your answers.

The case is as follows:

I am sending a form with some information, like this:

NAME: text

IMAGE1: text (result of using the function mime.b64)

MD5B64: text. MD5 hash of IMAGE1

The IMAGE1 field is the result of encoding an image in base64 (I have verified decoding it in corona and it works well)

The problem occurs when I receive the IMAGE1 field on the server. This field arrives well in length but NOT in content. The other fields arrive well.

NAME: Received OK

IMAGE1: not received OK

MD5B64: Received OK

Why IMAGE1 is not well transmitted?

The Code:

local headers = {} headers["Content-Type"] = "application/x-www-form-urlencoded" headers["Accept-Language"] = "en-US" headers["User-Agent"] = "App Corona SDK" local nombre="Peter Piedra" local body = "NAME="..nombre.."&IMAGE1="..myFoto64.."&PHONE=301-555-5555&MD5B64="..myencodedB64md5 local params = {} params.headers = headers params.body = body params.timeout = 35 url="https://-------.php" network.request( url, "POST", callback, params )

I have tried with this class: MultipartFormData:

https://github.com/benglard/Augment/blob/master/App/class_MultipartFormData.lua

And the problem with using this class is that the information does not reach the server.

Has anyone used that class successfully?

Regards,

SolCa

Are you computing the MD5 hash before you base64 encode on one platform and after on the other? Could be an easy mistake to overlook? Or is the base64 decode in the PHP script failing?

Rob

Rob, thank you for your interest. I’m sure my process is fine.

These are the results in Corona SDK

Saving to myencoded.jpg myenconded.b64 md5 1f7bf58b7f1dac7a4b2396adddb65783 649fd07c4fc4fe17362b3c5abe66a6bc

Web service response:

RESPONSE: {"Status":"ko","info":"MSG: Error Hash Invalid fb3d40fea0953ebea6d619cdf1e6cce4"}

Conclusions:

  1. b64 and unb64 in corona-sdk work well. Verified

  2. The variable coded in base 64 is not arriving correctly to the web service (hash of b64 = b3d40fea0953ebea6d619cdf1e6cce4)

  3. Taking the files manually to the server and using the command line this is the result (same as inside the Corona SDK)

    Results in Linux (CL) ====================================================== MD5 1f7bf58b7f1dac7a4b2396adddb65783 649fd07c4fc4fe17362b3c5abe66a6bc MD5 PHP 1f7bf58b7f1dac7a4b2396adddb65783 649fd07c4fc4fe17362b3c5abe66a6bc

This is the process in WS PHP when I receive the variables:

$dirTemp="/------------"; $nombreImagenJPG=$dirTemp."/myphoto.jpg"; $nombreImagenB64=$dirTemp."/myphoto.b64"; file\_put\_contents($nombreImagenB64, $image1); $image1JPG=base64\_decode($image1); file\_put\_contents($nombreImagenJPG, $image1JPG);

I’m just sending JPG images.

Shouldn’t those values be coming in to $_POST[]? If so you should have a value $_POST[“IMAGE1”] that’s a string containing the base64 encoded image.  You should be able to do:

file_put_contents($nombreImagenJPG, base64_decode( $_POST[“IMAGE1”]);

I’m also concerned to a bit by the lack of information on PHP’s file_put_contents (and fopen/fwrite) that doesn’t seem to support binary mode, but it’s probably the default. I also don’t see where you’re calculating your MD5 hash’s in your PHP code or where you’re returning the result from the script!

Rob

Hi Rob. Same Result.

$nombreImagenJPG=$dirTemp."/myphoto.jpg"; $nombreImagenB64=$dirTemp."/myphoto.b64"; file\_put\_contents($nombreImagenB64, $image1); // $image1JPG=base64\_decode($image1); $image1JPG=base64\_decode($\_POST["IMAGE1"]); file\_put\_contents($nombreImagenJPG, $image1JPG); // Validar MD5 if ( md5($\_POST["IMAGE1"]) \<\> $myencodedB64md5) { $msg="MSG: Error 1044 Hash Invalid ".md5($image1); $results=array("Status"=\>'ko',"info"=\>$msg); http\_response\_code(401); header('Content-type: application/json'); exit( json\_encode($results) ); }

Where are you computing $myencodedB64md5?

Where are you setting the value for $image1?

  1. Where are you computing $myencodedB64md5?

In corona sdk.

 

Where are you setting the value for $image1?

  1. In corona sdk

    local destDir = system.DocumentsDirectory local path = system.pathForFile( “poeta01.jpg”, destDir ) local file, errorString = io.open( path, “r” ) local myFoto ="" local originalSize=0 local codi64Size=0 local myFoto64="" local myFoto64uncoded="" local myencodedB64md5="" local myencodedJPGmd5="" if not file then print( “File error: " … errorString ) else myFoto = file:read( “*a” ) originalSize= string.len(myFoto) print (“Original Size”, originalSize) myFoto64 = mime.b64(myFoto) codi64Size = string.len( myFoto64 ) print (“Encoded 64 Size”, codi64Size) myFoto64uncoded=mime.unb64 (myFoto64) print (“and Size after Decoded”, string.len(myFoto64uncoded )) io.close( file ) print (“Saving to”,“myencoded.jpg”,” myenconded.b64") local path2 = system.pathForFile( “myencoded.jpg”, destDir ) local file2, errorString2 = io.open( path2, “w” ) if not file2 then print( "File error: " … errorString2 ) else scm = mime.unb64(myFoto64) file2:write( scm) io.close( file2 ) end – MD5 Calculation myencodedB64md5 = crypto.digest( crypto.md5, myFoto64 ) local myencodedJPGmd5 = crypto.digest( crypto.md5, myFoto64uncoded ) print ("md5 ",myencodedJPGmd5,myencodedB64md5) file = nil file2 = nil local file3, errorString3 = io.open( system.pathForFile (“myencoded.b64”, destDir),“w” ) file3:write (myFoto64) io.close( file3 ) file3 = nil end

Are you on Windows?  You may need to open the file in binary mode. I also don’t understand why you’re saving all these files and them opening them and re-reading them.  Why not simply open the binary JPEG image, read it in like you are, base64 encode the file, compute an MD5 hash of the original JPEG data, not the base64 version, send that to your server., base64 decode the string of base64 data, compute the MD5 on the decoded value and compare the two md5 hashes.  You can simplify this a lot.

Rob

Greetings and apologies for answering so far.

I’ve organized the process just to verify that the variable encodedb64 (myFoto64) is being well calculated in the Corona SDK (And that’s it, confirmed)

The point is that all the data I give to the newtwork.request is fine, and the API SERVER receives all of them, but only bad (wrong) the variable that contains the base64 string

Regards,

Solón

Maybe try doing a:

print\_r($\_POST[]);

And comparing what’s in the $_POST associative array with what you think you’re sending.

Rob

var\_dump($\_POST);

Can also be very helpful

Hi, 

In this post you can see what could be the origin of the problem and the possible solution:

https://forums.coronalabs.com/topic/73158-networkrequest-filters-the-character-when-sending-data-to-a-server/?p=384728

Regards,

Solca

I have tried with this class: MultipartFormData:

https://github.com/benglard/Augment/blob/master/App/class_MultipartFormData.lua

And the problem with using this class is that the information does not reach the server.

Has anyone used that class successfully?

Regards,

SolCa

Are you computing the MD5 hash before you base64 encode on one platform and after on the other? Could be an easy mistake to overlook? Or is the base64 decode in the PHP script failing?

Rob

Rob, thank you for your interest. I’m sure my process is fine.

These are the results in Corona SDK

Saving to myencoded.jpg myenconded.b64 md5 1f7bf58b7f1dac7a4b2396adddb65783 649fd07c4fc4fe17362b3c5abe66a6bc

Web service response:

RESPONSE: {"Status":"ko","info":"MSG: Error Hash Invalid fb3d40fea0953ebea6d619cdf1e6cce4"}

Conclusions:

  1. b64 and unb64 in corona-sdk work well. Verified

  2. The variable coded in base 64 is not arriving correctly to the web service (hash of b64 = b3d40fea0953ebea6d619cdf1e6cce4)

  3. Taking the files manually to the server and using the command line this is the result (same as inside the Corona SDK)

    Results in Linux (CL) ====================================================== MD5 1f7bf58b7f1dac7a4b2396adddb65783 649fd07c4fc4fe17362b3c5abe66a6bc MD5 PHP 1f7bf58b7f1dac7a4b2396adddb65783 649fd07c4fc4fe17362b3c5abe66a6bc

This is the process in WS PHP when I receive the variables:

$dirTemp="/------------"; $nombreImagenJPG=$dirTemp."/myphoto.jpg"; $nombreImagenB64=$dirTemp."/myphoto.b64"; file\_put\_contents($nombreImagenB64, $image1); $image1JPG=base64\_decode($image1); file\_put\_contents($nombreImagenJPG, $image1JPG);

I’m just sending JPG images.

Shouldn’t those values be coming in to $_POST[]? If so you should have a value $_POST[“IMAGE1”] that’s a string containing the base64 encoded image.  You should be able to do:

file_put_contents($nombreImagenJPG, base64_decode( $_POST[“IMAGE1”]);

I’m also concerned to a bit by the lack of information on PHP’s file_put_contents (and fopen/fwrite) that doesn’t seem to support binary mode, but it’s probably the default. I also don’t see where you’re calculating your MD5 hash’s in your PHP code or where you’re returning the result from the script!

Rob

Hi Rob. Same Result.

$nombreImagenJPG=$dirTemp."/myphoto.jpg"; $nombreImagenB64=$dirTemp."/myphoto.b64"; file\_put\_contents($nombreImagenB64, $image1); // $image1JPG=base64\_decode($image1); $image1JPG=base64\_decode($\_POST["IMAGE1"]); file\_put\_contents($nombreImagenJPG, $image1JPG); // Validar MD5 if ( md5($\_POST["IMAGE1"]) \<\> $myencodedB64md5) { $msg="MSG: Error 1044 Hash Invalid ".md5($image1); $results=array("Status"=\>'ko',"info"=\>$msg); http\_response\_code(401); header('Content-type: application/json'); exit( json\_encode($results) ); }