Файл .tgz в кодировке Base64 для использования при загрузке POST в вызове Javascript XHR - PullRequest
1 голос
/ 01 августа 2020

Я пытаюсь POST файл .tgz, используя XHR как часть загрузки файла.

Сам файл действителен, и я протестировал его с помощью ручной загрузки. Проблема, с которой я столкнулся (я думаю), заключается в том, что когда я кодирую файл в base64 и загружаю его, он поврежден и не воспринимается как действительный.

Сам файл является модулем плагина для Atmail, который я тестировал вручную, как я уже сказал.

Это моя функция загрузки с усеченным base64.

Сначала я кодирую целевой файл с помощью:

cat myfile.tgz | base64 > base64_file

и сокращение / удаление новых строк с помощью:

sed ':a;N;$!ba;s/\n/ /g' plugin.base64 > t

Мой вопрос: это правильный способ кодирования сжатого файла для использования в моем запросе POST ? И если да, то что не так с моей реализацией?

function uploadPlugin()
{
    var uri = "/index.php/admin/plugins/preinstall";
    var name = "newPlugin";
    filename = "RCE.tgz";
    // Comments and extra lines removed to reduce payload size
    // Remove new lines: sed ':a;N;$!ba;s/\n/ /g' plugin.base64 > t
    var content = "H4sIAAAAAAAAA+0aa2/bOLJfk1/BFYJaLvyIs0m6TZpss30Awe22vabXA65XqLREx2xkSSWppNlu ...";

    var formData = new FormData();
    var blob = new Blob([atob(content)],
        {
            type: "application/x-gtar-compressed"
        }
    )
    formData.append(name, blob, filename);

    var request = new XMLHttpRequest();
    request.open("POST", uri);
    request.send(formData);   
}

Это класс подключаемого модуля ATMail, который я использую.

<?php

class Atmail_Test_Plugin extends Atmail_Controller_Plugin
{
    
    protected $_pluginFullName   = 'rce';
    protected $_pluginModule = 'mail';
    
    private $_loginPage = false;

    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
    {
        $request = $this->getRequest();
        if (($request->getControllerName() == 'index' && $request->getActionName() == 'index') ||
            ($request->getControllerName() == 'auth' && $request->getActionName() == 'logout')) {
            $this->_loginPage = true;
        }
    }

    public function postDispatch(Zend_Controller_Request_Abstract $request)
    {
        if ($this->_loginPage) {
            $page = $this->getResponse()->getBody();
            $page = str_replace("</body>", "<!-- plugins working -->\n</body>", $page);
            $this->getResponse()->setBody($page);
        }
    }
    
    
    public function setup()
    {
        $db = zend_Registry::get("dbAdapter");
        $db->query("drop table if exists `TestPluginSettings`");
        $db->query("create table `TestPluginSettings` (`id` int auto_increment primary key, `keyName` varchar(12), `keyValue` text, index `keyName` (`keyName`))");
        
    }
    
    
    public function setViewRenderScript()
    {
        //return "/path/to/nothing.phtml";
    }
    
    
    public function setViewRenderAction()
    {
    }
}

1 Ответ

0 голосов
/ 02 августа 2020

В конце концов я понял, что пошло не так. Я пытался неправильно разместить двоичные данные. Ниже представлено рабочее решение.

function uploadPlugin()
{
    var uri = "/index.php/admin/plugins/preinstall";
    var name = "newPlugin";
    filename = "Upload.tgz";
    var body = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xed\x1a\x6b\x6f\xdb" +
    "\x38\xb2\x5f\x93\x5f\xc1\x15\x82\x5a\x2e\xfc\x88\xb3\x49\xba" +
    "..." +
    "...";

    var formData = new FormData();

    var payload = new Uint8Array(body.length);

    for (var i = 0; i < payload.length; i++)
    {
        payload[i] = body.charCodeAt(i);
    }

    var blob = new Blob([payload])
    formData.append(name, blob, filename);

    var xhr = new XMLHttpRequest();
    xhr.open("POST", uri);
    xhr.send(formData);   
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...