File Transfer

LibLinphone handle file transfer following the Rich Communications Services recommendations : http://www.gsma.com/network2020/wp-content/uploads/2015/03/RCS5.3_UNI.zip RCC.07 v6.0.pdf section 3.5.4.8 File Transfer via HTTP.

Files are sent to a server handling them, default server/script is https://www.linphone.org:444/lft.php

<!--
    Flexisip, a flexible SIP proxy server with media capabilities.
    Copyright (C) 2015  Belledonne Communications SARL.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-->

function custom_log($message) {
 $now = getdate();
 $month = sprintf("%02d", $now["mon"]);
 $day = sprintf("%02d", $now["mday"]);
 $hours = sprintf("%02d", $now["hours"]);
 $minutes = sprintf("%02d", $now["minutes"]);
 $seconds = sprintf("%02d", $now["seconds"]);

 error_log("[" . $day . "/" .  $month . "/" . $now["year"] . " " . $hours . ":" . $minutes . ":" . $seconds . "] " . $message . "\r\n", 3, "/var/log/trace_file_sharing.log");
}

function upload_error_message($error) {
 $message = 'Error uploading file';
        switch($error) {
            case UPLOAD_ERR_OK:
                $message = false;;
                break;
            case UPLOAD_ERR_INI_SIZE:
            case UPLOAD_ERR_FORM_SIZE:
                $message .= ' - file too large (limit of '.get_max_upload().' bytes).';
                break;
            case UPLOAD_ERR_PARTIAL:
                $message .= ' - file upload was not completed.';
                break;
            case UPLOAD_ERR_NO_FILE:
                $message .= ' - zero-length file uploaded.';
                break;
            default:
                $message .= ' - internal error #'. $error;
                break;
        }
 return $message;
}

function file_too_large() {
 if (!function_exists('http_response_code')) {
                $protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');
                header($protocol . ' 400 Bad Request');
                $GLOBALS['http_response_code'] = 400;
        } else {
                http_response_code(400);
        }
}

date_default_timezone_set("UTC");
if (count($_FILES) != 0) {
 $uploaddir = dirname(__FILE__).'/tmp/';
 $rcvname=$_FILES['File']['name'];
 $ext= strtolower(pathinfo($rcvname, PATHINFO_EXTENSION));
 //$allowed_ext = array("jpg", "txt", "zip", "zlib", "gz");
 //if (!in_array($ext, $allowed_ext)) $ext="jpg";
 $tmpfile=$_FILES['File']['tmp_name'];
 if (strlen($tmpfile) <= 0) {
  custom_log(upload_error_message($_FILES['File']['error']));
 }

 if ($_FILES['File']['error'] === UPLOAD_ERR_INI_SIZE) {
  //File too large
                custom_log(upload_error_message($_FILES['File']['error']));
  file_too_large();
 } else {
  custom_log('Uploaded '.$rcvname.' to '.$tmpfile);
  //$uploadfile = $uploaddir.time().md5_file($tmpfile).".".$ext;
  $uploadfile = $uploaddir.uniqid()."_".bin2hex(openssl_random_pseudo_bytes(10)).".$ext";

  if (move_uploaded_file($tmpfile, $uploadfile)) {
          custom_log('Moved to '.$uploadfile);
          $ipport = $_SERVER['HTTP_HOST'];
          $prefix= (isset($_SERVER["HTTPS"]) && strtolower($_SERVER["HTTPS"])=="on")?"https":"http";
          $start= $prefix."://".$ipport.dirname($_SERVER['REQUEST_URI']);
          $http_url = $start."/tmp/".basename($uploadfile);

   // validity time is one week ahead from now
   $until = date("Y-m-d\TH:i:s\Z",time()+7*24*60*60);
   echo '<file xmlns="urn:gsma:params:xml:ns:rcs:rcs:fthttp">
<file-info type="file">
<file-size>'.$_FILES['File']['size'].'</file-size>
<file-name>'.$_FILES['File']['name'].'</file-name>
<content-type>'.$_FILES['File']['type'].'</content-type>
<data url = "'.$http_url.'" until = "'.$until.'"/>
</file-info>
</file>';
  }
 }
}

if (isset($_SERVER['CONTENT_LENGTH']) && (int) $_SERVER['CONTENT_LENGTH'] > (1024*1024*(int) ini_get('post_max_size'))) {
 // File too large
 file_too_large();
} else if ((count($_POST) == 0) && (count($_FILES) == 0)) {
 if (!function_exists('http_response_code')) {
  $protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');
                header($protocol . ' 204 No Content');
  $GLOBALS['http_response_code'] = 204;
 } else {
  http_response_code(204);
 }
}
?>
If you use your own server, make sure to have the directory storing the uploaded file unable to serve php or any other script language files and/or filter on file extension.
Created by SandrineAvakian on 2017/01/11 16:21