Android Question Multipartpost problem

grafsoft

Well-Known Member
Licensed User
Longtime User
Hi,

I want to upload a list of files. The program crashes at the first file, but the file exists.

This is how I add it to the list, like the demo:

B4X:
     Dim fd As FileData
     fd.Initialize
     fd.FileName=Main.thepic
     fd.Dir=Main.outdir
     fd.KeyName = "Pic"
     fd.ContentType = "application/octet-stream"
     files.Add(fd)

This is my output:

(Intent) Intent { act=android.intent.action.MAIN flg=0x20000000 cmp=A.Tag/.main }
no extras
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Resume **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = false **
** Activity (upload) Create, isFirst = true **
18
http://www.grafsoft.at/a-tag/multipartpost.php
/storage/emulated/0/Android/data/A.Tag/files/5
15.jpg
** Activity (upload) Resume **
An error occurred:
(Line: 41) b = EOL.GetBytes("UTF8")
java.lang.NullPointerException

The code that crashes at file.copy2:

B4X:
Dim NV As Map
  NV.Initialize
  NV.Put("action", "upload")
  Dim req As HttpRequest
   Log (files.Size)
   Log (Main.hostname & "multipartpost.php")
' here it crashes
  req = MultipartPost.CreatePostRequest(Main.hostname & "multipartpost.php", NV, files)

Sub CreatePostRequest(URL As String, NameValues As Map, Files As List) As HttpRequest
   Dim boundary As String
   boundary = "---------------------------1461124740692"
   Dim stream As OutputStream
   stream.InitializeToBytesArray(20)
   Dim EOL As String
   EOL = Chr(13) & Chr(10) 'CRLF constant matches Android end of line character which is chr(10).
   Dim b() As Byte
   If NameValues <> Null AND NameValues.IsInitialized Then
     'Write the name/value pairs
     Dim key, value As String
     For i = 0 To NameValues.Size - 1
       key = NameValues.GetKeyAt(i)
       value = NameValues.GetValueAt(i)
       b = ("--" & boundary & EOL & "Content-Disposition: form-data; name=" _
         & QUOTE & key & QUOTE & EOL & EOL & value & EOL).GetBytes("UTF8")
       stream.WriteBytes(b, 0, b.Length)
     Next
   End If
   If Files <> Null AND Files.IsInitialized Then
     'write the files
     Dim FD As FileData
     For i = 0 To Files.Size - 1
       FD = Files.Get(i)
       b = ("--" & boundary & EOL & "Content-Disposition: form-data; name=" _
         & QUOTE & FD.KeyName & QUOTE & "; filename=" & QUOTE & FD.FileName & QUOTE _
         & EOL & "Content-Type: "  & FD.ContentType & EOL & EOL).GetBytes("UTF8")
       stream.WriteBytes(b, 0, b.Length)
       Dim In As InputStream
       Log (FD.Dir)
       Log (FD.FileName)
       ' crashes here
       In = File.OpenInput(FD.Dir, FD.FileName)
       File.Copy2(In, stream) 'read the file and write it to the stream
       b = EOL.GetBytes("UTF8")
       stream.WriteBytes(b, 0, b.Length)
     Next
   End If
   b = (EOL & "--" & boundary & "--" & EOL).GetBytes("UTF8")
   stream.WriteBytes(b, 0, b.Length)
   b = stream.ToBytesArray
   'msgbox(b.Length, "")
   Dim request As HttpRequest
   request.InitializePost2(URL, b)
   request.SetContentType("multipart/form-data; boundary=" & boundary)
   request.SetContentEncoding("UTF8")
   Return request
End Sub

What can I do?

Thanks

Peter
 

grafsoft

Well-Known Member
Licensed User
Longtime User
Even without filter I do not get more.


LogCat connected to: B4A-Bridge: motorola XT1032-355002058872653
--------- beginning of /dev/log/main
GC_CONCURRENT freed 1917K, 46% free 9377K/17244K, paused 7ms+2ms, total 45ms
Connected to B4A-Bridge (Wifi)
sending message to waiting queue (CallSubDelayed - UpdateStatus)
(Intent) Intent { act=android.intent.action.MAIN flg=0x20000000 cmp=A.Tag/.main }
no extras
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = false **
** Activity (upload) Create, isFirst = true **
18
http://www.grafsoft.at/a-tag/multipartpost.php
/storage/emulated/0/Android/data/A.Tag/files/5
15.jpg
** Activity (upload) Resume **
/storage/emulated/0/Android/data/A.Tag/files/5
1_1.wav
An error occurred:
(Line: 38) In = File.OpenInput(FD.Dir, FD.FileName)
java.lang.NullPointerException
PackageAdded: package:de.schildbach.oeffi
 
Upvote 0

grafsoft

Well-Known Member
Licensed User
Longtime User
Test1.zip: Does not show this error, but I also do not get the msgboxes - another problem which I an solve (you have to add some files to the project)

Test2.zip shows my problem, activity upload, but it is fairly complex and I tried to make it simpler (test1.zip), but then the error does not happen.

Sorry for being complicated ...
 

Attachments

  • test1.zip
    7.9 KB · Views: 182
  • test2.zip
    82.2 KB · Views: 195
Upvote 0

grafsoft

Well-Known Member
Licensed User
Longtime User
This is better to find the error, and ready for testing:

My code does this:

B4X:
  Dim NV As Map
  NV.Initialize
  NV.Put("action", "upload")
   
  Dim req As HttpRequest
   Log (files.Size)
   req = MultipartPost.CreatePostRequest("http://www.grafsoft.at/a-tag/multipartpost.php", NV, files)
  hc.Execute(req, 1)

The PHP-code on the other side does this:

B4X:
if (isset($_REQUEST['action'])){
  $action=trim($_REQUEST['action']);
} else {
  $action="";
}
if($action==""){
   $action = "overview";
}
echo $action;

And here

B4X:
Sub Response_StreamFinish (Success As Boolean, TaskId As Int)
  Dim another_buffer () As Byte
  another_buffer = out.ToBytesArray
  Log (BytesToString(another_buffer, 0, another_buffer.Length, "UTF8"))
   Msgbox (BytesToString(another_buffer, 0, another_buffer.Length, "UTF8"),"Finish")
   ToastMessageShow ("Done",False)
   ' goback
End Sub

I get "overview", not "upload".

I think the problem is understandable now - but I do not know how to solve it :(
 

Attachments

  • testnew.zip
    91 KB · Views: 191
Upvote 0

grafsoft

Well-Known Member
Licensed User
Longtime User
Funny. I still get "Overview".
But in your case, the JSON with the uploaded files is empty. And I have no uploads on the server.
Does it help if I add the complete PHP code?

B4X:
<?php
header("Content-type: text/plain");
#include('kernel.php');
#if (isset($_REQUEST['debug'])){$debug=intval($_REQUEST['debug']);} else {$debug=0;}
if (isset($_REQUEST['note1'])){
  $note1=trim($_REQUEST['note1']);
} else {
  $note1="";
}
if (isset($_REQUEST['note2'])){
  $note2=trim($_REQUEST['note2']);
} else {
  $note2="";
}
if (isset($_REQUEST['action'])){
  $action=trim($_REQUEST['action']);
} else {
  $action="";
}
$appresult = array();

if (isset($_REQUEST['DeviceID'])){$DeviceID=trim($_REQUEST['DeviceID']);} else {$DeviceID="";}
if (isset($_REQUEST['SimSerialNumber'])){$SimSerialNumber=trim($_REQUEST['SimSerialNumber']);} else {$SimSerialNumber="";}
if (isset($_REQUEST['SubscriberID'])){$SubscriberID=trim($_REQUEST['SubscriberID']);} else {$SubscriberID="";}

// $file_handle = fopen('./multipartpost.log', 'a+');
// pg
$file_handle = fopen('./toavi.bat', 'a+');
// fwrite($file_handle, "======================================"."\r\n");
foreach($_REQUEST as $name => $value){
   // fwrite($file_handle, date("d.m.Y H:i:s", time()).": ".$name."=".$value."\r\n");
}
// fwrite($file_handle, "======================================"."\r\n");

function GetWebname($name){
   $name=str_replace("Ä", "Ae", $name);
   $name=str_replace("Ö", "Oe", $name);
   $name=str_replace("Ü", "Ue", $name);
   $name=str_replace("ä", "ae", $name);
   $name=str_replace("ö", "oe", $name);
   $name=str_replace("ü", "ue", $name);
   $name=str_replace("ß", "ss", $name);
   $name=str_replace(" ", "_", $name);
   $name=str_replace("'", "", $name);
   $name=str_replace("´", "", $name);
   $name=str_replace("&", "and", $name);
   $name=str_replace("/", "", $name);
   $name=str_replace("\\", "", $name);
   $name=str_replace("`", "", $name);
   return strtolower($name);
}
function rand_string($lng=8) {
   mt_srand((double)microtime()*1000000);
   $charset = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ";
   $length  = strlen($charset)-1;
   $code  = '';
   for($i=0;$i < $lng;$i++) {
    $code .= $charset{mt_rand(0, $length)};
   }
   return $code;
}

#echo "Akt ST: ".$akt_spieltag."<br />";
#if (isset($_REQUEST['spieltag'])){$spieltag=intval($_REQUEST['spieltag']);} else {$spieltag=$akt_spieltag;}

if($action==""){
   $action = "overview";
}



if ($action == "overview"){
  #
}elseif($action == "upload"){
  $uploads[] = array();
  // fwrite($file_handle, "======= FILES ========================"."\r\n");
  foreach($_FILES as $name => $value){
  $uploads[$name] = $value;
  foreach($value as $fname => $fvalue){
     // fwrite($file_handle, date("d.m.Y H:i:s", time()).": ".$fname."=".$fvalue."\r\n");
  }
     // fwrite($file_handle, date("d.m.Y H:i:s", time()).": Upload of \"".$name."\"\r\n");
  if($name=="Aufnahme"){
  $uploaddir = './uploads/';
  $uploadfile = $uploaddir . basename($_FILES[$name]['name']);
     // fwrite($file_handle, date("d.m.Y H:i:s", time()).": MoveUploadedFile(".$_FILES[$name]['name'].")\r\n");
  if (move_uploaded_file($_FILES[$name]['tmp_name'], $uploadfile)) {
  $uploads[$name]["status"] = $_FILES[$name]['name']." saved successfull";
     // fwrite($file_handle, date("d.m.Y H:i:s", time()).": ->moving ".$_FILES[$name]['name']." successfull\r\n");
  #echo "Datei ist valide und wurde erfolgreich hochgeladen.\n";
      // pg
      $f = "e:\\inetpub\\wwwroot\\grafsoft\\evabachmayer\\padmin\\uploads\\" . $_FILES[$name]['name'];
      $f2=str_replace (".3gpp",".avi",$f);
      $t = "ffmpeg -y -i \"" . $f . "\" \"" . $f2 . "\"";
      fwrite($file_handle, $t . "\r\n");
       
      // pg
      /*
      $f = "e:\\inetpub\\wwwroot\\grafsoft\\evabachmayer\\padmin\\uploads\\" . $_FILES[$name]['name'];
      $f2=str_replace (".3gpp",".avi",$f);
      $t = "ffmpeg -i \"" . $f . "\" \"" . $f2 . "\"";
      safe_mode_exec_dir="c:\\programme\\ffmpeg\\bin";
      // $o=shell_exec ($t);
      echo "<pre>" . $t . "</pre>";
      fwrite($file_handle, $t . "\r\n");
      fwrite($file_handle, "o=" . $o . "\r\n");
      */
       
      // pg
       
       
  } else {
  $uploads[$name]["status"] = $_FILES[$name]['name']." failed to save!";
     // fwrite($file_handle, date("d.m.Y H:i:s", time()).":->moving ".$_FILES[$name]['name']." NOT successfull\r\n");
  #echo "Möglicherweise eine Dateiupload-Attacke!\n";
  }
  }
  if($name=="coca_cola"){
  $uploaddir = './uploads/';
  $uploadfile = $uploaddir . basename($_FILES[$name]['name']);
 
     // fwrite($file_handle, date("d.m.Y H:i:s", time()).": MoveUploadedFile(".$_FILES[$name]['name'].")\r\n");
  if (move_uploaded_file($_FILES[$name]['tmp_name'], $uploadfile)) {
  $uploads[$name]["status"] = $_FILES[$name]['name']." saved successfull";
     // fwrite($file_handle, date("d.m.Y H:i:s", time()).": ->moving ".$_FILES[$name]['name']." successfull\r\n");
  } else {
  $uploads[$name]["status"] = $_FILES[$name]['name']." failed to save!";
     // fwrite($file_handle, date("d.m.Y H:i:s", time()).":->moving ".$_FILES[$name]['name']." NOT successfull\r\n");
  }
  }
  foreach($value as $fname => $fvalue){
     // fwrite($file_handle, date("d.m.Y H:i:s", time()).": ".$fname."=".$fvalue."\r\n");
  }
  }
  // fwrite($file_handle, "======================================"."\r\n");
   #print_r($uploads);
  $appresult["uploads"] = $uploads;
 
  echo json_encode($appresult);
  #
}else{
}
fclose($file_handle);
?>
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I've changed the code to:
B4X:
  Dim thedir As String
   thedir = File.DirAssets
   Dim filelist As List
   filelist=ListFilesOnly (thedir)
   Dim i As Int
   Dim files As List
   files.initialize
     Dim fd As FileData
   fd.Initialize
   fd.FileName= "1_2.wav"
   fd.Dir=File.DirAssets
   fd.KeyName = "Pic"
   fd.ContentType = "application/octet-stream"
   files.Add(fd)
   Dim NV As Map
  NV.Initialize
  NV.Put("action", "upload")
   
  Dim req As HttpRequest
   Log (files.Size)
   req = MultipartPost.CreatePostRequest("http://www.grafsoft.at/a-tag/multipartpost.php", NV, files)
  hc.Execute(req, 1)
Output:
uploadtry to upload{"uploads":{"0":[],"Pic":{"name":"1_2.wav","type":"application\/octet-stream","tmp_name":"C:\\WINDOWS\\Temp\\php2B1.tmp","error":0,"size":95022,"status":"1_2.wav saved successfull"}}}
 
Upvote 0

grafsoft

Well-Known Member
Licensed User
Longtime User
I tried the same with 2 files:
B4X:
Dim thedir As String
  thedir = File.DirAssets
  Dim filelist As List
  filelist=ListFilesOnly (thedir)
  Dim i As Int
  Dim files As List
  files.initialize
  Dim fd As FileData
  fd.Initialize
  fd.FileName= "1_2.wav"
  fd.Dir=File.DirAssets
  fd.KeyName = "Pic"
  fd.ContentType = "application/octet-stream"
  files.Add(fd)
  Dim fd As FileData
  fd.Initialize
  fd.FileName= "1_3.wav"
  fd.Dir=File.DirAssets
  fd.KeyName = "Pic"
  fd.ContentType = "application/octet-stream"
  files.Add(fd)
  Dim NV As Map
  NV.Initialize
  NV.Put("action", "upload")
 
  Dim req As HttpRequest
  Log (files.Size)
  req = MultipartPost.CreatePostRequest("http://www.grafsoft.at/a-tag/multipartpost.php", NV, files)
  hc.Execute(req, 1)

Only 1_3.wav was uploaded.

My log-file says this:

======================================
19.05.2014 12:46:47: action=upload
======================================
Action=upload======= FILES ========================
19.05.2014 12:46:47: name=1_3.wav
19.05.2014 12:46:47: type=application/octet-stream
19.05.2014 12:46:47: tmp_name=C:\WINDOWS\Temp\php2C6.tmp
19.05.2014 12:46:47: error=0
19.05.2014 12:46:47: size=87854
19.05.2014 12:46:47: Upload of "Pic"
19.05.2014 12:46:47: ->moving 1_3.wav successfull
19.05.2014 12:46:47: name=1_3.wav
19.05.2014 12:46:47: type=application/octet-stream
19.05.2014 12:46:47: tmp_name=C:\WINDOWS\Temp\php2C6.tmp
19.05.2014 12:46:47: error=0
19.05.2014 12:46:47: size=87854

So - something is funny anyway.

Without wanting to be ungrateful for your efforts - is there another library or code snippet for uploads? I am getting out of time ...
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Lass mal das
$f = "e:\\inetpub\\wwwroot\\grafsoft\\evabachmayer\\padmin\\uploads\\" . $_FILES[$name]['name']; $f2=str_replace (".3gpp",".avi",$f);
$t = "ffmpeg -i \"" . $f . "\" \"" . $f2 . "\"";
safe_mode_exec_dir="c:\\programme\\ffmpeg\\bin";
weg in deinem PHP-Script... Das wird KEIN Hoster mitmachen da ein Video ON THE FLY zu konvertieren... Das PHP-Script wird da mit SICHERHEIT aussteigen oder spätestens nach x sekunden gekillt. Siehe hier.

Wenn Du Kontrolle über den Server hast, dann kannst du da sicherlich einen B4J-Server laufen lassen. Ein B4J-Server sollte in der Lage sein auch große Dateien zu empfangen und sie dann auch zu konvertieren. Ohne Zeitliche einschränkung.

Remove the lines
$f = "e:\\inetpub\\wwwroot\\grafsoft\\evabachmayer\\padmin\\uploads\\" . $_FILES[$name]['name']; $f2=str_replace (".3gpp",".avi",$f);
$t = "ffmpeg -i \"" . $f . "\" \"" . $f2 . "\"";
safe_mode_exec_dir="c:\\programme\\ffmpeg\\bin";
from PHP-Script... NO Webhoster will allow an php-script to convert an video ON THE FLY while calling a php-script...
The php-script will be killed to 100% from system after x seconds running... See this for more information

If you have control over the server than you could run a b4j-server on it. A b4j-server should be able to recieve big files too. And you could the audio converted with ffmpg too. WITHOUT a limited time of executing the uploadthread.

With php you are much limited! The time is running from that moment the upload to it starts...
 
Last edited:
Upvote 0
Top