Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   PHP, PERL, MySQL, JavaScript (https://forum.antichat.xyz/forumdisplay.php?f=37)
-   -   Автоматичная закачка файла - альтернатива FTP ? (https://forum.antichat.xyz/showthread.php?t=200568)

^_WhitE_DeMoN_^ 30.04.2010 05:13

Автоматичная закачка файла - альтернатива FTP ?
 
Таак, написал automatic remote backup tool, PHP скрипт дампит MySQL базы, записывает их локально и закачивает на удаленный FTP...

Только вот проблем...
Хост ругается: ftp_put() [function.ftp-put]: php_connect_nonb() failed: Operation now in progress (115) (2)

Саппорт отвечает: We do not allow the FTP functions to be used against remote FTP servers.

Так вот ищу простую альтернативу ftp_*, есть идея передавать имя файла (которое генерируется разное!) GET запросом удаленному скрипту, а тот скачает и запишет файл.

Но как реализовать, вообще не думается :confused:
Буду благодарен за куски кода, примеры, обяснения...

Спасибо что дочитали :D

LStr1ke 30.04.2010 06:08

Ну например так:

1 хост, который делает дамп:
PHP код:

<?php
/* 
{
Тут делаешь дамп и сораняешь файл локально
}
*/

$damp_file "db.sql"//Тут имя файл который сдампился
echo file_get_contents("http://my_server_2/saver.php?file=".$damp_file); //Тут ты передаешь хосту №2 какой файл ему скачивать
?>

Хост №2 который скачивает
PHP код:

<?php
$server_1 
"http://server_nomer_1/"//Тут адрес сервера откуда скачивать
$dump_file $_GET['file'];
$file_prefix "saved_";
if(
file_put_contents($file_prefix.$dump_file,file_get_contents($server_1.$dump_file))) {
echo 
"File_saved!";
}else echo 
"File dont saved";
?>

Ну впринципе и все. 1 скрипт напишет File_saved! если файл успешно скачен вторым сервером. На втором сервере появится файл saved_db.sql

Ну думаю схема понятна. )))

Если файл большой, то во втором скрипте скачивай "побайтово".
функция fread()
//практикуем убийство серверов?)))

^_WhitE_DeMoN_^ 30.04.2010 17:58

Ожидается что будет большой, и еще 50 штук таких... Базы phpBB3 =)
Иначе все понятно, спасибо огромное, щас в репу стукну

Няя, я не убиец =) Я наемный убиец =) ...а так, сайто строитель...

Deathdreams 30.04.2010 22:50

скрипт, который дампит (в переменной $server указать путь до скрипта, который скачивает):
Код:

<?php

/*тут дамп в переменную $dump*/

$server = 'http://fsdfdsf.ru/example.php'; //путь до второго файла

@ini_set('max_execution_time', 0);
$name = "dump".date("YmdHis").".sql";
if( @file_put_contents( $name, $dump ) )
{

        echo 'Сохранили дамп...'.PHP_EOL;
        $path = $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"].$name;
        $content = file_get_contents( $server.'?put='.urlencode($path) );
        if( $content == 'success' ) echo 'Сервер успешно сохранил наш дамп.'.PHP_EOL;
        else echo 'Серверу не удалось сохранить наш дамп.'.PHP_EOL;

} else echo 'Дамп сохранить не удалось. Проверь chmod.';

?>

скрипт для сохранения дампа:
Код:

<?php

$dir = '/dumps/'; //папка с дампами

$file = "http://".stripslashes(urldecode(trim($_GET['put'])));
if( file_put_contents( $dir."dump".date("Y-m-d+H-i-s"), file_get_contents($file) ) )
{

die('success');

} else die('false');


?>

/*писалось на скорую руку, подправьте если что не так*/

Gifts 01.05.2010 15:10

^_WhitE_DeMoN_^ если блокируются только функции ftp_*, напишите свой класс на сокетах, благо FTP - простейший протокол

Или еще проще:
PHP код:

file_put_contents("ftp://user:password@ftp.server.ru/file.txt"file_get_contents('имя_локального_файла')); 


^_WhitE_DeMoN_^ 02.05.2010 02:56

Цитата:

Сообщение от Gifts
Или еще проще:
PHP код:

file_put_contents("ftp://user:password@ftp.server.ru/file.txt"file_get_contents('имя_локального_файла')); 


Удивил, проще некуда! Но, пока сделал первый вариант... И хз че еще у хостера запрещенно ;)

^_WhitE_DeMoN_^ 09.05.2010 01:39

Цитата:

Сообщение от LStr1ke
Ну например так:

1 хост, который делает дамп:
PHP код:

<?php
/* 
{
Тут делаешь дамп и сораняешь файл локально
}
*/

$damp_file "db.sql"//Тут имя файл который сдампился
echo file_get_contents("http://my_server_2/saver.php?file=".$damp_file); //Тут ты передаешь хосту №2 какой файл ему скачивать
?>

Хост №2 который скачивает
PHP код:

<?php
$server_1 
"http://server_nomer_1/"//Тут адрес сервера откуда скачивать
$dump_file $_GET['file'];
$file_prefix "saved_";
if(
file_put_contents($file_prefix.$dump_file,file_get_contents($server_1.$dump_file))) {
echo 
"File_saved!";
}else echo 
"File dont saved";
?>

Ну впринципе и все. 1 скрипт напишет File_saved! если файл успешно скачен вторым сервером. На втором сервере появится файл saved_db.sql

Ну думаю схема понятна. )))

Если файл большой, то во втором скрипте скачивай "побайтово".
функция fread()
//практикуем убийство серверов?)))

Хост ругается:
Цитата:

file_get_contents() [function.file-get-contents]: URL file-access is disabled in the server configuration (2)
Идеи :confused:

^_WhitE_DeMoN_^ 12.05.2010 03:26

У никого ?

m0Hze 12.05.2010 08:29

Цитата:

Сообщение от ^_WhitE_DeMoN_^
У никого ?

Помоему, вот этот параметр в php.ini
allow_url_fopen=on;

^_WhitE_DeMoN_^ 12.05.2010 10:11

Нет доступа к php.ini
Ищу обход...

ghostwizard 12.05.2010 17:39

Обязательно ftp ?

1. Пробуй через сокеты, если не запрещено.
2. Напрямую через 80-й порт.

LStr1ke 12.05.2010 18:06

Цитата:

Сообщение от ^_WhitE_DeMoN_^
Нет доступа к php.ini
Ищу обход...

ini_set();
или читай через сокет

http://ru2.php.net/manual/en/function.fsockopen.php

^_WhitE_DeMoN_^ 13.05.2010 19:39

FTP - не обязательно.
Нужно только реализовать закачку файла с одного сервера на другой, а как ето уже проблем... Со сокетами не знаком, но придется доки курить...

ini_set('allow_url_fopen', 'On'); не помогло...

^_WhitE_DeMoN_^ 17.05.2010 10:47

И через сокеты не пашет - URL file-access is disabled in the server configuration (2)

Другие идеи..?

roxblnfk 17.05.2010 11:25

слать через POST, если файлы большие (или ограничение на POST), то кусками с указанием сегментов :)

вначале сделать запрос на передачу файла, в POST параметрах указать имя файла, логин/пароль, хэш всего файла, его размер.

Далее, получив согласие получателя и код сессии начинаем передавать сегменты файла:
указать только начало, конец, контрольную сумму (на всякий) обрывка; сессию на файл
Принимающий собирает по кускам, проверяет получившуюся контрольную сумму и всё.
Ну и написать проверку, что если были ранее начаты сессии с незаконченными передачами, которые не обновлялись более часа, то их стоит удалить.

куски файла можно зипировать..
а если и в base64 закодировать, то можно и GET-ом передать xD правда там на заголовки больше уйдёт трафика, но система будет работать :D

^_WhitE_DeMoN_^ 17.05.2010 22:35

Вообще не врубил...

LStr1ke 17.05.2010 23:01

Цитата:

а если и в base64 закодировать, то можно и GET-ом передать
При base64 строка увеличиться в несколько раз, а метод GET при отправки большого количества данных какбе не лучший вариант.

^_WhitE_DeMoN_^, Ты сокетами, надеюсь, отправлял заголовки?

roxblnfk 17.05.2010 23:41

Цитата:

Сообщение от LStr1ke
При base64 строка увеличиться в несколько раз, а метод GET при отправки большого количества данных какбе не лучший вариант.

^_WhitE_DeMoN_^, Ты сокетами, надеюсь, отправлял заголовки?

я об этом и говорю, что заголовки ппц будут :)


^_WhitE_DeMoN_^, написл для тебя функцию с коментами. Если не новиш в php, то дальше сам разрулишь
(функцию можешь не изучать, просто используй как надо, хотя в ней многое не учтено, но для простых запросов хватит)

PHP код:

function HTTP_request($serv='127.0.0.1'$port=80$timeout=30$host='localhost'$addr='/index.php'$post=null$cookies=null){
    
$str='';$heads='';
    if(
is_array($post))if(count($post)>0){
        
$method='POST';
        
$str.="\r\n\r";
        foreach(
$post as $k=>$v){
            
$str.='&'.$k.'='.urlencode($v);
        }
        
$str{4}="\n";
        
$heads.="\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: ".(strlen($str)-4);
    }
    if(!isset(
$method)){
        
$method='GET';
        
//$heads.="\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        
$str="\r\n\r\n";
    }
    if(
is_array($cookies))if(count($cookies)>0){
        
$cook="\r\nCookie: ";
        foreach(
$cookies as $k=>$v){$cook.=$k.'='.urlencode($v).'; ';}
        
$heads.=substr($cook,0,-2);
    }
    if(
false!=($f=@fsockopen($serv$port$errno$errstr$timeout))){
        
$ss='';
        
fputs ($f"$method $addr HTTP/1.1".$heads."\r\nHost: $host\r\nConnection: close".$str);
        while (!
feof($f)) {
            
$ss.=fgets($f512);
        }
        
fclose($f);
    }else return array(
false$errstr);
    return array(
true$ss); 
}    
// вернёт массив 0=>сокет сконнектил 1=> если не сконнектил, то текст ошибки, иначе овтет сервера

//////////////////////////
//////
$serv='127.0.0.1';    // IP или домен сервера
$port=80;            // порт
$host='localhost';    // Что передавать в заголовке HOST
$addr='/index.php';// Адрес до страницы на сайте
$timeout=30;    // таймаут соединения
$post=array();    // массив с переменными в формате ($var1 => $value1, $var2 => $value2...) {в $var# желательно использовать только латину}
$cookie=array();// cookies заполняется аналогично $post

print_r(HTTP_request($serv$port$timeout$host$addr$post$cookie)); 


|qbz| 18.05.2010 15:25

Цитата:

ini_set('allow_url_fopen', 'On'); не помогло...
kuri htaccess

^_WhitE_DeMoN_^ 20.05.2010 01:52

@LStr1ke, неа...

@roxblnfk, возвращает "1" =(

@|qbz|, и .htaccess не прокатил...

roxblnfk 20.05.2010 14:40

^_WhitE_DeMoN_^, ошибка есть, тут: $str{4}="\n";
надо $str{3}="\n";
А где возвращает 1? :)

я тут RFC протокола перечитал, увидел следующее на счёт Content-Length:
Длина тела объекта (entity-body) - это длина тела сообщения (message-body), полученного после декодирования всех кодирований передачи.
Т.е., как я понял, сюда надо вписывать не длину закодированного контента, а длину контента до кодирования. В нэте в примерах показывают обратное, т.е. указывают длину закодированного контента.
Вобщем немного переделал функцию (тут длина до кодирования):

PHP код:

function HTTP_request($serv='127.0.0.1'$port=80$timeout=30$host='localhost'$addr='/'$post=null$cookies=null){
    
$str='';$heads='';
    if(
is_array($post))if(count($post)>0){
        
$method='POST';
        
$str.="\r\n\r";
        
$Len=0;
        foreach(
$post as $k=>$v){
            
$str.='&'.$k.'='.urlencode($v);
            
$Len+=2+strlen($k)+strlen($v);
        }
        
$Len-=1;
        
$str{3}="\n";
        
$heads.="\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: ".$Len;
    }
    if(!isset(
$method)){
        
$method='GET';
        
//$heads.="\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        
$str="\r\n\r\n";
    }
    if(
is_array($cookies))if(count($cookies)>0){
        
$cook="\r\nCookie: ";
        foreach(
$cookies as $k=>$v){$cook.=$k.'='.urlencode($v).'; ';}
        
$heads.=substr($cook,0,-2);unset($cook);
    }
    if(
false!=($f=@fsockopen($serv$port$errno$errstr$timeout))){
        
$ss='';
        
fputs ($f"$method $addr HTTP/1.1".$heads."\r\nHost: $host\r\nConnection: close".$str);
        while(!
feof($f)){$ss.=fread($f512);}
        
fclose($f);
    }else return array(
false$errstr);
    return array(
true$ss); 


надеюсь в Content-Length учитываются разделители и названия переменных :)

Кстати, чтобы передавать бинарные данные, лучше использовать MIME без всякого кодирования. Этим же способом передают фотки с текстом за 1 раз. С момента прошлого поста я успел написать функцию, реализующую MIME в POST, только не закончил. В функции нет возможности аутентификации (Digest Authentication), но эти заголовки несложно дописать вручную. Если надо, могу поделиться.

^_WhitE_DeMoN_^ 21.05.2010 00:42

Цитата:

Сообщение от roxblnfk
А где возвращает 1? :)

Сдесь:
PHP код:

echo tpl_l(print_r(HTTP_request($serv$port$timeout$host$addr$post$cookie)), C_RESULT); 


Вот из за какогото [censored] и его [censored] настройки сервака, должен извращатся а не радоватся file_get_contents()
Ну никак не пашет !

LStr1ke 21.05.2010 01:35

Да сделай по изврату ) Обычно, когда делать совсем нех. пользуешься извратом )
Короче )
На сайте, где хочешь сохранить файл (куда закачивать) делаешь форму, ну обычную, типа закачать файл.
PHP код:

<?php
if($_FILES["filename"]["name"] == null) {
    echo 
"NO FILE";
    exit;


if(
copy($_FILES["filename"]["tmp_name"],
$_SERVER['DOCUMENT_ROOT']."/".$_FILES["filename"]["name"]))
   {
     echo 
"OK";
   } else {
      echo 
"ERROR";
   }
?>

А на сервере, откуда заливать файл (базу) делаешь токой скрипт:
PHP код:

<?php
$file 
"baza.sql"// Должен лежать в каталоге со скриптом
$post_data '-----------------------------01010
Content-Disposition: form-data; name="filename"; filename="'
.$file.'"

-----------------------------01010
Content-Type: application/octet-stream

'
.file_get_contents('baza.sql').'
-----------------------------01010--'
;
$ch=curl_init();
curl_setopt($chCURLOPT_URL'http://server.ru/upload.php');
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($ch,CURLOPT_HTTPHEADER,array (
        
"Content-Type: multipart/form-data; boundary=---------------------------01010",
    ));
curl_setopt($chCURLOPT_HEADER0);
curl_setopt($chCURLOPT_REFERER'http://server.ru/test.html');  
curl_setopt($chCURLOPT_POST1);  
curl_setopt($chCURLOPT_POSTFIELDS,$post_data); 
$result curl_exec($ch);
echo 
$result;
?>

И если все замечательно, то скрипт покажет OK и сохранит файл в server.ru/files/

Ну это конечно извращенно, вообщем хз, что еще посоветовать )

roxblnfk 21.05.2010 15:13

Цитата:

Сообщение от ^_WhitE_DeMoN_^
Сдесь:
PHP код:

echo tpl_l(print_r(HTTP_request($serv$port$timeout$host$addr$post$cookie)), C_RESULT); 


эм.. что за echo tpl_l();

HTTP_request() вернёт МАССИВ, где первый элемент с ключем 0 будет true или false, второй элемент с индексом 1 — текст ошибки (в случае, если первый false) или ответ сервера (если первый элемент - true, т.е. коннект удался)

присвой значение переменной и бери условие...
PHP код:

$Result=HTTP_request();
if(
$Result[0]){
   echo 
"запрос отправил, вот ответ:\r\n".$Result[1];
}else{
   echo 
"Не удалось соедениться с сервером, вот текст ошибки:\r\n".$Result[1];



gisTy 21.05.2010 21:04

Цитата:

Сообщение от LStr1ke
...

ты думаешь, что админы дурачки и отключив сокеты и урл_фопен оставили работать курл? ну-ну

roxblnfk 22.05.2010 00:16

считай, готовое решение
 
^_WhitE_DeMoN_^,
написал передачу файла по посту по кускам (ограничение размера файла - 2 гига ровно минус 1 байт)
Да и пост у меня по кускам :) собирай..

PHP код:

function pro_HTTP_($SOCKET$HEAD, &$CONTENT){
    
$SOCKETs=array(
        
'Socket-Address'=>'localhost',
        
'Socket-Port'=>80,
        
'Socket-Timeout'=>10,
        
'Socket-DownLimit'=>null    // null-без лимита
    
);
    
$HEADs=array(
        
// САМЫЕ ОСНОВНЫЕ :)
        
'Method'=>null,                // если не указано, устанавливается автоматически GET или POST [GET POST PUT OPTIONS HEAD DELETE PATCH TRACE LINK UNLINK]
        
'URI'=>'/',
        
'HTTP'=>'HTTP/1.1',
        
// ОСНОВНЫЕ            // Знак ? означает, что заголовок не фильтруется и всё, что вы через него передадите, выведется в чистом виде
                            // Формат даты (пример): Sun, 06 Nov 1994 08:49:37 GMT
        
'Cache-Control'=>null,            //?    Основные директивы для управления кэшированием.
        
'Connection'=>false,             //    Сведения о проведении соединения // false=Close;true=Keep-Alive;если число, то добавляется Keep-Alive: с этим числом
        
'Date'=>null,                     //?    Дата генерации отклика.
        
'MIME-Version'=>null,             //?    Версия протокола MIME по которому было сформировано сообщение.
        
'Pragma'=>null,                   //?    Особенные опции выполнения операции.
        
'Trailer'=>null,                  //?    Список полей, имеющих отношение к кодированию сообщения при передаче.
        
'Transfer-Encoding'=>null,        //?    Список способов кодирования, которые были применены к сообщению для передачи.
        
'Upgrade'=>null,                  //?    Список предлагаемых клиентом протоколов. Сервер указывает один протокол.
        
'Via'=>null,                      //?    Список версий протокола, названий и версий прокси-серверов через которых прошло сообщение.
        
'Warning'=>null,                //?    Код, агент, сообщение и дата если возникла критическая ситуация.
        //    ЗАПРОС
        
'Accept'=>null,                    //    Список допустимых форматов ресурса.
        
'Accept-Charset'=>null,            //?    Перечень поддерживаемых кодировок для предоставления пользователю
        
'Accept-Encoding'=>null,        //?    Перечень поддерживаемых способов кодирования содержимого сущности при передаче.[gzip,deflate],compress,x-gzip,x-compress
        
'Accept-Language'=>null,        //    Список поддерживаемых естественных языков.
/*    */    
'Authorization'=>null,            //!    Данные для авторизации.
        
'Expect'=>null,                    //?    HTTP/1.1v2     Указывает серверу что клиент ожидает от него дополнительного действия.
        
'From'=>null,                    //    Адрес электронной почты ответственного лица со стороны клиента.
        
'Host'=>true,                    //    Доменное имя и порт хоста запрашиваемого ресурса. Необходимо для поддержки виртуального хостинга на серверах.// Если true, то заполняется из сокета
        
'If-Match'=>null,                //?    Список тегов версий сущности. Выполнять метод если они существуют.
        
'If-Modified-Since'=>null,        //?    Дата. Выполнять метод если сущность изменилась с указанного момента. Используется только для метода обработки GET
        
'If-None-Match'=>null,            //?    Список тегов версий сущности. Выполнять метод если ни одного из них не существует.
        
'If-Range'=>null,                //?    Список тегов версий сущности или дата для определённого фрагмента сущности.
        
'If-Unmodified-Since'=>null,    //?    Дата. Выполнять метод если сущность не изменилась с указанной даты.
        
'Max-Forwards'=>null,            //?    Максимально допустимое количество переходов через прокси.
/*    */    
'Proxy-Authorization'=>null,    //!    Информация для авторизации на прокси-сервере.
        
'Range'=>null,                    //    Байтовые диапазоны для запроса фрагментов ресурса. Подробности: Частичные GET.    [bytes=64397516-80496894]
        
'Referer'=>null,                  //    URI ресурса, после которого клиент сделал текущий запрос.// если true, то берётся из адреса
        
'TE'=>null,                       //?    HTTP/1.1v2     Список расширенных способов кодирования при передаче.
        
'User-Agent'=>null,                //?    Список названий и версий клиента и его компонентов с комментариями.
        // СОДЕРЖИМОЕ (СУЩНОСТИ) CONTENT
        
'Content-Disposition'=>null,      //?    Способ распределения сущностей в сообщении при передачи нескольких фрагментов.
        
'Content-Encoding'=>null,         //?    Способ кодирования содержимого сущности при передаче.
        
'Content-Language'=>null,         //    Один или несколько естественных языков содержимого сущности
        
'Content-Length'=>null,           //    Размер содержимого сущности в байтах.    // если передаётся в $CONTENT, то будет заполнено автоматически, лучше не трогать
        
'Content-Location'=>null,         //?    Альтернативное расположение содержимого сущности.
        
'Content-MD5'=>null,              //?!MD5-хэш сущности для проверки целостности.    // для автоматического заполнения перевести в ture
        
'Content-Range'=>null,            //?    Байтовые диапазоны передаваемой сущности если возвращается фрагмент. Подробности: Частичные GET.
        
'Content-Type'=>null,            //    Формат и способ представления сущности.
        
'Content-Version'=>null,          //?    Информация о текущей версии сущности.
        
'Derived-From'=>null,             //?    Информация о текущей версии сущности.
        
'Last-Modified'=>null,            //?    Дата последней модификации сущности.
        
'Link'=>null,                     //?    Указывает на логически связный с сущностью ресурс аналогично тегу <LINK>  в HTML.
        
'Title'=>null                    //?    Заголовок сущности.
    
);
    foreach(
$SOCKETs as $k=>$v){ if(isset($SOCKET[$k])) $SOCKETs[$k]=$SOCKET[$k]; }
    
$keys=array_keys($HEADs);
    
$lim=count($keys);
    for(
$i=0;$i<$lim;$i++){
        
$Head=$keys[$i];
        
$Value=$HEADs[$Head];
        if(isset(
$HEAD[$Head])){ if($HEAD[$Head]!==''$HEADs[$Head]=$HEAD[$Head]; }
        elseif(
is_null($Value)) unset($HEADs[$Head]);
    }
    if((string)
$HEADs['URI']=='')    $HEADs['URI'] ='/';            else $HEADs['URI'] =(string)$HEADs['URI'];
    if((string)
$HEADs['HTTP']=='')    $HEADs['HTTP']='HTTP/1.1';    else $HEADs['HTTP']=(string)$HEADs['HTTP'];
    if(
$HEADs['Connection']){
        if(
is_numeric($HEADs['Connection'])) $HEADs['Keep-Alive']=intval($HEADs['Connection']);
        
$HEADs['Connection']='Keep-Alive';
    }else 
$HEADs['Connection']='Close';
    if(isset(
$HEADs['Host'])){ if($HEADs['Host']===true || strlen($HEADs['Host'])==0)$HEADs['Host']=$SOCKETs['Socket-Address']; }
    if(isset(
$HEADs['Referer'])) if($HEADs['Referer']===true$HEADs['Referer']=$HEADs['URI'];
    
$Content='';
    if(isset(
$CONTENT)) if(is_array($CONTENT)){
        if(isset(
$CONTENT)) if(isset($CONTENT['POST'])) if(is_array($CONTENT['POST'])) if(count($CONTENT['POST'])>0){
            
$HEADs['Method']='POST';$MIME=false;
            
$keys=array_keys($CONTENT['POST']);$lim=count($keys);
            for(
$i=0;$i<$lim;$i++){ if(is_array($CONTENT['POST'][$keys[$i]])){    $MIME=true; break; } }
            
$Length=0;
            if(
$MIME){
                
$boundarysubstr(sha1(md5(mktime())), 4, -4);
                
$boundary$boundary.strtoupper(md5($boundary)); $boundary{10}='+'$boundary{12}='_'//получение более-менее уникальной границы
                
$HEADs['Content-Type']='multipart/form-data; boundary="'.$boundary.'"';
                foreach(
$CONTENT['POST'] as $Keyko=>$Postec){
                    if(
is_array($Postec)){
                        
$Content.="--$boundary\r\nContent-Disposition: form-data";
                        if(isset(
$Postec['name'])) $Content.='; name="'.$Postec['name'].'"'; else $Content.='; name="'.$Keyko.'"';
                        if(isset(
$Postec['filename']))$Content.='; filename="'.$Postec['name'].'"';
                        
$Content.="\r\n";
                        foreach(
$Postec as $K=>$V){ if($K!='' && $K!='name' && $K!='Content-Disposition'$Content.="$K$V\r\n"; }
                        
$Content.="\r\n".@$Postec['']."\r\n";
                    }else 
$Content.="--$boundary\r\nContent-Disposition: form-data; name=\"$Keyko\"\r\n\r\n$Postec\r\n";
                }
                
$Content.="--$boundary--";
                
$Length=strlen($Content);
            }else{
                foreach(
$CONTENT['POST'] as $k=>$v){
                    
$Content.=trim($k).'='.urlencode($v).'&'
                    
$Length+=2+strlen(trim($k))+strlen($v);
                }
                
$Length-=1;
                
$Content=substr($Content,0,-1);
                
$HEADs['Content-Type']='application/x-www-form-urlencoded';
            }
            if(isset(
$HEADs['Content-Length'])) if($HEADs['Content-Length']===true$HEADs['Content-Length']=$Length;
            if(isset(
$HEADs['Content-MD5'])) if($HEADs['Content-MD5']===true$HEADs['Content-MD5']=md5($Content);
        }
        
// cookie
        
if(isset($CONTENT)) if(isset($CONTENT['Cookie'])) if(is_array($CONTENT['Cookie'])) if(count($CONTENT['Cookie'])>0){
            
$HEADs['Cookie']='';
            foreach(
$CONTENT['Cookie'] as $k=>$v){ $HEADs['Cookie'].=(string)$k.'='.urlencode($v).'; '; }
            
$HEADs['Cookie']=substr($HEADs['Cookie'],0,-2);
        }
        if(isset(
$CONTENT)) if(isset($CONTENT['Authorization'])) if(is_array($CONTENT['Authorization'])){
            if(isset(
$CONTENT['Authorization']['userid']) && isset($CONTENT['Authorization']['password']))
                
$HEADs['Authorization'] = 'Basic '.base64_encode(str_replace(':'''$CONTENT['Authorization']['userid']).':'.$CONTENT['Authorization']['password']);
        }
    }
    if(isset(
$HEADs['Content-MD5'])) if($HEADs['Content-MD5']===true) unset($HEADs['Content-MD5']);
    if(!
in_array(@$HEADs['Method'],array('GET''POST''PUT''OPTIONS''HEAD''DELETE''PATCH''TRACE''LINK''UNLINK')))$HEADs['Method']='GET';
    
$Send=$HEADs['Method'].' '.$HEADs['URI'].' '.$HEADs['HTTP'];unset($HEADs['Method'], $HEADs['URI'], $HEADs['HTTP']);
    
$keys=array_keys($HEADs);$lim=count($keys);
    for(
$i=0;$i<$lim;$i++){
        
$Head=$keys[$i];
        
$Value=$HEADs[$Head];
        
$Send.="\r\n$Head$Value";
    }
    
$Send.="\r\n\r\n".$Content;
    if(
false!=($f=@fsockopen($SOCKETs['Socket-Address'], $SOCKETs['Socket-Port'], $errno$errstr$SOCKETs['Socket-Timeout']))){
        if(!isset(
$SOCKETs['Socket-DownLimit'])) $ByteLimit=-1;
        elseif (
intval($SOCKETs['Socket-DownLimit'])>=0$ByteLimit=intval($SOCKETs['Socket-DownLimit']);
        else 
$ByteLimit=-1;
        
fputs ($f$Send);
        
$Str='';
        if(
$ByteLimit>0){
            
$Downed=0;
            
set_time_limit(5);
            while(!
feof($f) && $Downed<$ByteLimit){
                
$Str.=fread($f$ByteLimit-$Downed);
                
$Downed=strlen($Str);
            }
        }elseif(
$ByteLimit<0){ while(!feof($f)){ $Str.=fgets($f512); } }
        
fclose($f);
    }else return array(
false$errstr$Send);
    return array(
true$Str$Send);


Вот функция, её добавить в ниже указанный код

roxblnfk 22.05.2010 00:17

Код скрипта, отправляющего файл: (форум может поставить пробелы где не надо, но я старался делить длинные строки)
<?
PHP код:

/* Ф У Н К Ц И Ю    В С Т А В И Т Ь    С Ю Д А
ОПИСАНИЕ:::::::ФУНКЦИИ
Возвращает array ($Connected{true,false}, $Str{string}, $Send{string}(отправленный запрос))
    Если $Connected==true, то $Str - ответ сервера, иначе $Str - текст ошибки сокета
В функцию передаются 3 массива
$SOCKET доолжен содержать значения:
    'Socket-Address'=>    адрес сервера (ip или домен)
    'Socket-Port'=>        удалённый порт (обычно 80)
    'Socket-Timeout'=>    максимальное время ожидания соединения
    'Socket-DownLimit'=>ограничение на длину ответа (Байт). null - без ограничения, функция закачает и выдаст полный ответ сервера
$HEAD
    Смотрите описание заголовков в функции
    Все неуказанные заголовки либо берутся автоматически (важные), либо игнорируются (второстепенные)
$CONTENT
    Указывайте тут POST данные, куки, логины и пароли для доступа
        'Cookie'=>array('name'=>'ROX','session'=>'asagjreht89pqypgr7w5e4p',...)                // передавайте в ассоциативном массиве Имя=>Значение
        'POST'=>array(),
            // Пост запрос можно организовать двумя способами:
            1. Если нужно послать текстовые переменные, заполняйте массив как в случает с COOKIE (значения подвергаются urlencode)
            2. Если нужно передать файлы и тексты, воспользуйтесь передачей множественного содержимого (см. MIME)
                В этом случае массив примет вид:
                $CONTENT['POST']=array(
                    array(
                        'name'=>'Это имя переменной (формы)',     // если не указано, то берётся ключ этого суб-массива (0) 
                                                                // 'name' соответствует атрибуту name в HTML-тегах <INPUT>  и <TEXTAREA>
                        'filename'=>'image.jpg',    //    Если передаете файл, укажите имя файла
                        'Content-Type'=>'image/jpeg',    // при передаче файла укажите формат файла
                        'Content-Transfer-Encoding'=>'binari',    // бинарный файл, содержимое не закодировано
                        ''=>'Собственно, само содержимое. Практически тут может быть всё что угодно',    // не подвергается кодированию // ключ элемента - пустая строка
                    ),
                    array(
                        ''=>'текст' // здесь name=>1
                    ),
                    'ololo'=>array(
                        ''=>'тело объекта' // здесь name=>'ololo'
                    )
                );
                Заголовок каждого содержимого постоянен =>>> Content-Disposition: form-data
        'Authorization'=>array(Login, Password),        // Авторизация на сайте
        1 Базовая схема установления подлинности (Basic Authentication Scheme)
            'Authorization'=>array(
                'userid'=>'User'        //    идентификатор клиента
                'password'=>'123'        //    пароль
            )
    [x]    2 Обзорная схема установления подлинности (Digest Authentication Scheme); Обзорное установление подлинности для HTTP определяется в RFC 2069 [32] 2617 oO. // НЕ РЕАЛИЗОВАНО
    [x]    'Proxy-Authorization'=>array(Login, Password),    // Авторизация на HTTP прокси // НЕ РЕАЛИЗОВАНО
*/

$File='./de_baghdad2.rar';
$SizeLimit=512*1024;//500KB
$ReSend=5;

$SOCKET=array('Socket-Address'=>'127.0.0.1''Socket-Port'=>80'Socket-Timeout'=>10'Socket-DownLimit'=>null);
$CONTENT=array( 'Authorization' => array('userid'=>'User''password'=>'123'));
$HEAD=array(
        
'URI'=>'/get_file.php',
        
'Connection'=>false,
        
'Host'=>true,
        
'Content-Length'=>true,           //    Размер содержимого сущности в байтах.    // если передаётся в $CONTENT, то будет заполнено автоматически, лучше не трогать
        
'Content-MD5'=>true,              //    MD5-хэш сущности для проверки целостности.    // для автоматического заполнения перевести в ture
    
);
if(
is_file($File))if(is_readable($File)){
    
$Size=filesize($File);
    
$For=ceil($Size/$SizeLimit);
    if(
$For>0) if(false!==($FP=fopen($File,'r'))){
        
flock($FP,LOCK_SH);
        
$Sendet=0;
        
$MD5File=md5_file($File);
        for(
$i=0$i<$For$i++){
            
fseek($FP, ($i*$SizeLimit) ,SEEK_SET);
            
$Segment=fread($FP$SizeLimit);
            
$CONTENT['POST']=array(
                array(
                    
'name'=>'md5file',
                    
''=>$MD5File
                
),
                array(
                    
'name'=>'fullsize',
                    
''=>$Size
                
),
                array(
                    
'name'=>'start',
                    
''=>($i*$SizeLimit)
                ),
                array(
                    
'name'=>'end',
                    
''=>min(($i*$SizeLimit+$SizeLimit),$Size)
                ),
                array(
                    
'name'=>'md5segment',
                    
''=>md5($Segment)
                ),
                array(
                    
'name'=>'filename',
                    
''=>substr(strrchr(str_replace("\\",'/',$File),'/'),1)
                ),
                array(
                    
'name'=>'segmentname',
                    
''=>'segment'
                
),
                array(
                    
'name'=>'segment',
                    
'filename'=>'segment',
                    
'Content-Transfer-Encoding'=>'binari',
                    
''=>$Segment
                
)
            );
            
$Sendet=false;
            
$j=0;
            while(!
$Sendet && $j<$ReSend){
                
$j++;
                
$Result=pro_HTTP_($SOCKET$HEAD$CONTENT);
                
$Sendet=$Result[0];
                
$Text=$Result[1];
            }
            if(!
$Sendet){echo 'Файл не удалось отправить. Возникла ошибка на '.$i.' сегменте: '.$Text; break;}
            echo 
strval($i+1)."-й пошёл!\r\n";
            echo 
$Result[1]."\r\n\r\n<br>\r\n\r\n";
            
//echo strlen($Segment);
            //print_r($CONTENT);
        
}
        
flock($FP,LOCK_UN);
        
fclose($FP);
    }else echo 
'Не удалось открыть файл';
    else echo 
'Файл нулевого размера.';


?>

roxblnfk 22.05.2010 00:18

зы: функция pro_HTTP_() ещё не доделана, но в заданном условии работает как надо. Надо ещё сделать прокси и Digest (который всё-равно не сделаю, намудрили в спецификации, да и апач не поддерживает полностью)

Скрипт, принимающий файл: (там попутно указаны некоторые опции типа логина и пароля, имени файла... лучше изучить)

<?
PHP код:

$MessageA 'Authorise, please';
$MessageB 'Bad password or login';
function 
q_auth($Inp){
    
header('WWW-Authenticate: Basic realm="'.$Inp.'"');
    
header('HTTP/1.0 401 Unauthorized');
}
if (!isset(
$_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])){
    
q_auth($MessageA);
}else{
    
$User=(string)$_SERVER['PHP_AUTH_USER'];
    
$Password=(string)$_SERVER['PHP_AUTH_PW'];
        
// контроль передачи данных для отладки
        // ob_start();
        // print_r($_FILES);
        // print_r($_POST);
        // $To=ob_get_contents();
        // ob_end_flush ();
        // $fp = fopen ('./sending file oO.txt','a');
        // flock ($fp,LOCK_EX);
        // fputs($fp,$To);
        // flock ($fp,LOCK_UN);
        // fclose($fp);
        
if($User!=='User' || $Password!=='123'){
            
q_auth($MessageB);
        }else{
            
// Сохраняем по кускам файл
            
echo "ПОГНАЛИ!\r\n";
            if(isset(
$_POST['md5file']) && isset($_POST['start']) && isset($_POST['end']) && isset($_POST['fullsize']) 
                        && isset(
$_POST['md5segment']) && isset($_POST['filename']) && isset($_POST['segmentname'])){
                
$SegmentName=$_POST['segmentname'];
                
$Start=intval($_POST['start']);
                
$End=intval($_POST['end']);
                
$Size=$End-$Start;
                
$FullSize=$_POST['fullsize'];
                
$md5file=$_POST['md5file'];
                
$md5segment=$_POST['md5segment'];
                echo 
"ПОСТ ПРИШЁЛ! Size=$Size\r\n";
                if(
$Size>0){
                    echo 
"РАЗМЕРЧИК НЕ ДЕРЬМО!\r\n";
                    if(isset(
$_FILES[$SegmentName])){
                        echo 
"СЕГМЕНТ ДЕТЕКТЕД!\r\n";
                        if(
$_FILES[$SegmentName]['size']==$Size && md5_file ($_FILES[$SegmentName]['tmp_name']) === strtolower($md5segment)){
                            
//$CustomFileName=$_POST['filename'];// ненадёжно, нужны фильтры и проверки
                            
$CustomFileName='./NotFileName.rar';
                            
$fp fopen ($CustomFileName,'a+');
                            
flock($fp,LOCK_EX);
                            
fseek($fp$StartSEEK_SET);
                            
fputs($fpfile_get_contents ($_FILES[$SegmentName]['tmp_name']));
                            
flock($fp,LOCK_UN);
                            
fclose($fp);
                            if(
$End==$FullSize) if(md5_file($CustomFileName) === strtolower($md5file)) echo 'ФАЙЛ ЗАПИСАН КАК НАДО И ПОЛНОСТЬЮ! УРА! xD';
                            else echo 
'ПИПЕЦ!';
                            else echo 
'СЕГМЕНТ ЗАПИСАН!';
                        }else echo 
"НАЕ*А! size=".($_FILES[$SegmentName]['size'])."? если да, то md5 не тот\r\n";
                    }else echo 
'А ФАЙЛ ТО ЗАБЫЛ ПЕРЕДАТЬ?';
                }else echo 
'ПОПУТАЛ РАЗМЕРЧИК! ';
            }else echo 
'ПОСТ ПЕРЕДАН НЕ ВЕСЬ!';
        }


?>

В ходе теста файл отлично передался, вот мой результат

Цитата:

1-й пошёл!
HTTP/1.1 200 OK
Date: Fri, 21 May 2010 19:59:48 GMT
Server: Apache/2.2.14 (Win32) PHP/5.3.1
X-Powered-By: PHP/5.3.1
Content-Length: 77
Connection: close
Content-Type: text/html

ПОГНАЛИ!
ПОСТ ПРИШЁЛ! Size=524288
РАЗМЕРЧИК НЕ ДЕРЬМО!
СЕГМЕНТ ДЕТЕКТЕД!


<br>

2-й пошёл!
HTTP/1.1 200 OK
Date: Fri, 21 May 2010 19:59:48 GMT
Server: Apache/2.2.14 (Win32) PHP/5.3.1
X-Powered-By: PHP/5.3.1
Content-Length: 77
Connection: close
Content-Type: text/html

ПОГНАЛИ!
ПОСТ ПРИШЁЛ! Size=524288
РАЗМЕРЧИК НЕ ДЕРЬМО!
СЕГМЕНТ ДЕТЕКТЕД!


<br>

3-й пошёл!
HTTP/1.1 200 OK
Date: Fri, 21 May 2010 19:59:48 GMT
Server: Apache/2.2.14 (Win32) PHP/5.3.1
X-Powered-By: PHP/5.3.1
Content-Length: 119
Connection: close
Content-Type: text/html

ПОГНАЛИ!
ПОСТ ПРИШЁЛ! Size=459218
РАЗМЕРЧИК НЕ ДЕРЬМО!
СЕГМЕНТ ДЕТЕКТЕД!
ФАЙЛ ЗАПИСАН КАК НАДО И ПОЛНОСТЬЮ! УРА! xD

<br>

жаль за работу денег на платят :(

roxblnfk 23.05.2010 23:24

ТС уже забил на тему? :(

^_WhitE_DeMoN_^ 24.05.2010 01:05

Цитата:

Сообщение от roxblnfk
ТС уже забил на тему? :(

Да не, просто времени нету тестить - работы пох...
Скоро активизируюсь.

echo tpl_l() - выводит результат в теплейте (оформлен)

^_WhitE_DeMoN_^ 24.05.2010 01:18

Цитата:

Сообщение от gisTy
ты думаешь, что админы дурачки и отключив сокеты и урл_фопен оставили работать курл? ну-ну

Очевидно дурачки :D
Еще не тестил, но из форума хоста понел что курл наш :)

^_WhitE_DeMoN_^ 24.05.2010 01:50

Цитата:

Сообщение от roxblnfk
HTTP_request() вернёт МАССИВ, где первый элемент с ключем 0 будет true или false, второй элемент с индексом 1 — текст ошибки (в случае, если первый false) или ответ сервера (если первый элемент - true, т.е. коннект удался)

присвой значение переменной и бери условие...
PHP код:

$Result=HTTP_request();
if(
$Result[0]){
   echo 
"запрос отправил, вот ответ:\r\n".$Result[1];
}else{
   echo 
"Не удалось соедениться с сервером, вот текст ошибки:\r\n".$Result[1];



Такой вот фрагмент - не выводит ничего ! :confused:
PHP код:

$timeout=30;    // таймаут соединения 
            
$post=array('b' => $this->filename);    // массив с переменными в формате ($var1 => $value1, $var2 => $value2...) {в $var# желательно использовать только латину} 
            
$cookie=array();// cookies заполняется аналогично $post 
            
$rezult HTTP_request($serv$port$timeout$host$addr$post$cookie);
            echo 
tpl_l($rezult[0].' --- '.$rezult[1], C_RESULT);
            if(
$rezult[0]){ 
   echo 
tpl_l("запрос отправил, вот ответ:\r\n".$rezult[1], C_RESULT);
}else{ 
   echo 
tpl_l("Не удалось соедениться с сервером, вот текст ошибки:\r\n".$rezult[1], C_RESULT); 


roxblnfk 24.05.2010 10:42

Цитата:

Сообщение от ^_WhitE_DeMoN_^
Такой вот фрагмент - не выводит ничего ! :confused:
PHP код:

$timeout=30;    // таймаут соединения 
            
$post=array('b' => $this->filename);    // массив с переменными в формате ($var1 => $value1, $var2 => $value2...) {в $var# желательно использовать только латину} 
            
$cookie=array();// cookies заполняется аналогично $post 
            
$rezult HTTP_request($serv$port$timeout$host$addr$post$cookie);
            echo 
tpl_l($rezult[0].' --- '.$rezult[1], C_RESULT);
            if(
$rezult[0]){ 
   echo 
tpl_l("запрос отправил, вот ответ:\r\n".$rezult[1], C_RESULT);
}else{ 
   echo 
tpl_l("Не удалось соедениться с сервером, вот текст ошибки:\r\n".$rezult[1], C_RESULT); 


если убрать твой tpl_l то всё нормально выводит :) (либо текст ошибки, либо контент страницы)
а вобще, в трёх своих предыдущих постах текущей темы я всю твою задачу решил... (там уже другая функция)

^_WhitE_DeMoN_^ 25.05.2010 01:32

Цитата:

Сообщение от roxblnfk
если убрать твой tpl_l то всё нормально выводит :) (либо текст ошибки, либо контент страницы)
а вобще, в трёх своих предыдущих постах текущей темы я всю твою задачу решил... (там уже другая функция)

Логики нет. Посмотрим...

Но я никуда не спешу (уже...), все протестирую (что как заработает) и репу колотить буду, спасиб ;)


Время: 18:07