ООО ЭкоЮнит
FAQПоискПользователиГруппыФайлыВходРегистрацияГлавная
Версия для печати
 
 
АвторСообщение
Sergey Пол:Муж.


Местный босс - администратор


Зарегистрирован: 06.01.2005
Показать/Спрятать

 !  Sergey @ Ср 22 Янв, 2014 20:37:
Редакция статьи, переработанной с учетом замечаний, приобретённого опыта, а также с учетом изменений в платформе 8.3.


В статье собран мой опыт по передаче данных на веб-сервер.

В ходе реализации одного проекта потребовалось организовать автоматическую передачу данных на веб-сервер посредством регламентного задания.
Покопавшись прежде всего в мануалах, синтаксис-помощнике 1С Предприятия, порыскав в Сети, с удивлением обнаружил наличие отсутствия каких-либо вменяемых материалов по теме. Вернее, материалы в Сети есть, но там больше вопросы с абстрактными ответами.

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

Для передачи данных на сервер методом POST в 1С: Предприятии 8.X применяется метод HTTPСоединение.ОтправитьДляОбработки()
По файлу-источнику и адресу ресурса:
Код:
ОтправитьДляОбработки(<Источник>, <Адрес ресурса>, <Имя выходного файла>, <ЗаголовкиHTTP>);


Для 1С: Предприятия 8.3 и платформы 8.2.18 и позднее может использоваться синтаксис по HTTP-запросу, позволяющий отказаться от формирования временных файлов отправки и ответа сервера:
Код:
ОтправитьДляОбработки(<HTTPЗапрос>, <ИмяВыходногоФайла>);

(подробнее см. СП)

Прежде всего необходимо создать файл отправки данных (собственно содержимое POST-запроса) и, при необходимости, подготовить двоичные данные.
Определяем разделитель разделов — границу boundary в POST-запросе в формате RFC (подробнее MIME: Организация данных ). В качестве границы может быть использована строка, состоящая из латинских букв и цифр.
Чтобы ничего не выдумывать, воспользуемся штатным классом 1С Предприятия УникальныйИдентификатор.

Код:
    //Подготовка переменных
    Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");

    //Определяем имя файла ответа от веб-сервера.
    ИмяФайлаОтвета = КаталогВременныхФайлов() + "answer.tmp";

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

Подготавливаем двоичные данные. В моём случае это файл архива zip, но может быть что угодно, хоть изображение.

Код:
    //Какой-то ранее созданный файл с двоичными данными.
    ИмяФайлаДляЗагрузки = "data.zip";


Передача содержимого файла
В 1С Предприятии отсутствуют средства чтения двоичных файлов в обычную строку, как в PHP или PERL.
Одним из способов получения строкового содержимого двоичного файла является кодирование с помощью штатных функций Base64Строка() или XMLСтрока(), при этом размер передаваемых данных увеличивается примерно на 30%. Декодировать содержимое файла на сервере можно при помощи функции php base64_decode() или аналогичных для используемого вами серверного ПО.
Другой способ состоит в использовании штатной функции ОбъединитьФайлы(<МассивФайлов>, <Имя результирующего файла>) (подробнее см. в СП). В этом случае формирование файла POST-запроса будет происходить немного сложнее.
Оба способа описаны ниже.

Впрочем, двоичные данные лучше закодировать, иначе при приёме на веб-сервере файл может быть повреждён или не принят вовсе, если он будет содержать URL-значащие символы. Особенно это касается XML-подобных или иных текстовых файлов.

Следует также помнить об ограничениях хостинга и контролировать размер передаваемых данных. Как правило, для php это 2Мб. (см. файл /usr/local/php5/php.ini)
; Maximum allowed size for uploaded files.
upload_max_filesize = 2M

В противном случе, на веб-сервере вы получите пустой POST-запрос.


    //Если файл кодируется
//Закодируем содержимое файла по Base64, то есть преобразуем его к URL-неактивному виду. //Base64 - специальный формат хранения данных в текстовом формате
СодержимоеФайла = Base64Строка(Новый ДвоичныеДанные(ИмяФайлаДляЗагрузки)); //Проверка размера кодированного файла. Если СтрДлина(СодержимоеФайла) > ДопустимыйРазмерФайлаВБайтах Тогда //Какие-то ваши действия, возможно Возврат; КонецЕсли; //Если файл не кодируется //Проверка размера обычного файла. Файл = Новый Файл(ИмяФайлаДляЗагрузки); Если Файл.Размер() > ДопустимыйРазмерФайлаВБайтах Тогда //Какие-то ваши действия, возможно Возврат; КонецЕсли; ИмяФайлаОтправки = КаталогВременныхФайлов() + "post.txt";


Создаём файл отправки или содержимое POST-запроса.

1. Вариант с передачей кодированного файла.

    КодироватьФайл = Истина;
    ФайлОтправки = Новый ЗаписьТекста(ИмяФайлаОтправки, КодировкаТекста.ANSI, Символы.ПС, Ложь);
    //Определяем раздел двоичных данных
    ФайлОтправки.ЗаписатьСтроку("--" + Boundary);
    //Указываем имя файла для передачи
    //На сервере оно появится в массиве $_FILES['datafile']['name']
    ФайлОтправки.ЗаписатьСтроку("Content-Disposition: form-data; name=""datafile""; filename=""" + ИмяФайлаДанных + """");
    //Указываем тип передаваемых данных.
    //С таким же успехом в Content-Type можно указать application/x-octet-stream
    ФайлОтправки.ЗаписатьСтроку("Content-Type: application/x-zip-compressed" + Символы.ПС + Символы.ПС);
    //Записываем кодированные двоичные данные
    ФайлОтправки.ЗаписатьСтроку(СодержимоеФайла);
    ФайлОтправки.ЗаписатьСтроку("--" + Boundary);

    //Определяем раздел для каких либо других POST-данных, например содержимого полей виртуальной HTML-формы.

    //Соответствует полю HTML-формы input type="submit" name="submit" value="Submit" /
    ФайлОтправки.ЗаписатьСтроку("--" + Boundary);
    ФайлОтправки.ЗаписатьСтроку("Content-disposition: form-data; name=""submit""" + Символы.ПС);
    ФайлОтправки.ЗаписатьСтроку("1");
    ФайлОтправки.ЗаписатьСтроку("--" + Boundary);

    //Соответствует полю HTML-формы input type="checkbox" name="decode" value="decode" /
    ФайлОтправки.ЗаписатьСтроку("--" + Boundary);
    ФайлОтправки.ЗаписатьСтроку("Content-disposition: form-data; name=""decode""" + Символы.ПС);
    ФайлОтправки.ЗаписатьСтроку(?(КодироватьФайл, "1", "0"));
    ФайлОтправки.ЗаписатьСтроку("--" + Boundary);

    //Соответствует полю HTML-формы input type="text" name="some_field" value="Some text" /
    ФайлОтправки.ЗаписатьСтроку("--" + Boundary);
    ФайлОтправки.ЗаписатьСтроку("Content-disposition: form-data; name=""message""" + Символы.ПС);
    ФайлОтправки.ЗаписатьСтроку("Передача файла из базы данных 1С Предприятия");

    //Завершение сообщения для сервера
    ФайлОтправки.ЗаписатьСтроку("--" + Boundary + "--");

    ФайлОтправки.Закрыть();


2. Вариант с передачей обычного файла.

    КодироватьФайл = Ложь;
    //Определяем массив для процедуры ОбъединитьФайлы
    МассивФайловДляОбъединения = Новый Массив;

    //Формируем начальный фрагмент файла POST-запроса
    ИмяФайлаОтправкиНачало = ПолучитьИмяВременногоФайла("txt");
    ФайлОтправкиНачало = Новый ЗаписьТекста(ИмяФайлаОтправкиНачало, КодировкаТекста.ANSI, Символы.ПС, Ложь);
    //Определяем раздел двоичных данных
    ФайлОтправкиНачало.ЗаписатьСтроку("--" + Boundary);
    //Указываем имя файла для передачи
    //На сервере оно появится в массиве $_FILES['datafile']['name']
    ФайлОтправкиНачало.ЗаписатьСтроку("Content-Disposition: form-data; name=""datafile""; filename=""" + ИмяФайлаДляЗагрузки + """");
    //Указываем тип передаваемых данных.
    //С таким же успехом в Content-Type можно указать application/x-octet-stream или application/x-zip-compressed
    ФайлОтправкиНачало.ЗаписатьСтроку("Content-Type: application/x-octet-stream");
    ФайлОтправкиНачало.ЗаписатьСтроку("");
    ФайлОтправкиНачало.Закрыть();

    МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиНачало);

    //Копируем файл для загрузки во временный и добавляем в массив файлов для объединения
    ИмяФайлаДляЗагрузкиВременный = ПолучитьИмяВременногоФайла("tmp");
    КопироватьФайл(ИмяФайлаДляЗагрузки, ИмяФайлаДляЗагрузкиВременный);
    МассивФайловДляОбъединения.Добавить(ИмяФайлаДляЗагрузкиВременный);

    //Формируем конечный фрагмент файла POST-запроса
    ИмяФайлаОтправкиКонец = ПолучитьИмяВременногоФайла("txt");
    ФайлОтправкиКонец = Новый ЗаписьТекста(ИмяФайлаОтправкиКонец, КодировкаТекста.ANSI, Символы.ПС, Ложь);

    //Завершение раздела двоичных данных
    ФайлОтправкиКонец.ЗаписатьСтроку("--" + Boundary);

    //Определяем раздел для каких либо других POST-данных, например содержимого полей виртуальной HTML-формы.

    //Соответствует полю HTML-формы input type="submit" name="submit" value="Submit" /
    ФайлОтправкиКонец.ЗаписатьСтроку("--" + Boundary);
    ФайлОтправкиКонец.ЗаписатьСтроку("Content-disposition: form-data; name=""submit""" + Символы.ПС);
    ФайлОтправкиКонец.ЗаписатьСтроку("1");
    ФайлОтправкиКонец.ЗаписатьСтроку("--" + Boundary);

    //Соответствует полю HTML-формы input type="checkbox" name="decode" value="decode" /
    ФайлОтправкиКонец.ЗаписатьСтроку("--" + Boundary);
    ФайлОтправкиКонец.ЗаписатьСтроку("Content-disposition: form-data; name=""decode""" + Символы.ПС);
    ФайлОтправкиКонец.ЗаписатьСтроку(?(КодироватьФайл, "1", "0"));
    ФайлОтправкиКонец.ЗаписатьСтроку("--" + Boundary);

    //Соответствует полю HTML-формы input type="text" name="some_field" value="Some text" /
    ФайлОтправкиКонец.ЗаписатьСтроку("--" + Boundary);
    ФайлОтправкиКонец.ЗаписатьСтроку("Content-disposition: form-data; name=""message""" + Символы.ПС);
    ФайлОтправкиКонец.ЗаписатьСтроку("Передача файла из базы данных 1С Предприятия");
    //Завершение сообщения для сервера
    ФайлОтправкиКонец.ЗаписатьСтроку("--" + Boundary + "--");
    ФайлОтправкиКонец.Закрыть();

    МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиКонец);

    //Теперь сформированные фрагменты сообщения для сервера объединяем в один файл POST-запроса
    ОбъединитьФайлы(МассивФайловДляОбъединения, ИмяФайлаОтправки);


Формируем заголовок POST-запроса.

    ЗаголовокHTTP = Новый Соответствие();
    //Обязательные поля заголовка

    //Укажем формат данных Content-Type
    ЗаголовокHTTP.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);

    //Укажем длину POST-запроса Content-Length
    ФайлОтправки = Новый Файл(ИмяФайлаОтправки);
    РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());
    ЗаголовокHTTP.Вставить("Content-Length", РазмерФайлаОтправки);

    //При необходимости зададим Referer, например таким образом
    СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
    СерверИсточник = НСтр(СтрокаСоединения, "Srvr") + НСтр(СтрокаСоединения, "Ref");
    ЗаголовокHTTP.Вставить("Referer", СерверИсточник);

Если вы получите ошибку сервера вида Failed sending data to the peer, попробуйте убрать параметр Referer из заголовка.

Инициализируем HTTPСоединение. При необходимости задаём параметры прокси.

    СерверПриемник = "www.some_site.ru"; //Без протокола . Естественно, следует указать свой адрес.
    Порт = "80"; //Это общепринятый порт. Возможно, для вашего сервера применяется другой. Конкретное значение уточните у хостера.

    //ИспользоватьПрокси - какая-то логическая переменная, может быть значение флажка на форме или переключатель
    Если ИспользоватьПрокси Тогда
        Прокси = Новый ИнтернетПрокси;
        Прокси.НеИспользоватьПроксиДляЛокальныхАдресов = Истина;
        Прокси.Пароль = "ПарольПрокси"; // укажите своё значение
        Прокси.Пользователь = "ПользовательПрокси"; // укажите своё значение
        НТТР = Новый HTTPСоединение(СерверПриемник, Порт, , , Прокси);
    Иначе
        НТТР = Новый HTTPСоединение(СерверПриемник, Порт);
    КонецЕсли;


Отправка данных серверу.

Здесь приведён код, общий для платформ 8.1, 8.2, 8.3.


    АдресСкрипта = "some_script.php"; //Без протокола  и имени домена. Естественно, следует указать имя своего скрипта.
    Попытка
        НТТР.ОтправитьДляОбработки(ИмяФайлаОтправки, АдресСкрипта, ИмяФайлаОтвета, ЗаголовокHTTP);
    Исключение
        //Пример обработки ошибки соединения.
        #Если Клиент Тогда
            Сообщить("Неудачная попытка соединения: " + ОписаниеОшибки());
        #Иначе
            ЗаписьЖурналаРегистрации("HTTPСоединение", УровеньЖурналаРегистрации.Ошибка, , , "Неудачная попытка соединения: " + ОписаниеОшибки());
        #КонецЕсли
        Возврат;
    КонецПопытки;

    //Удаляем файлы POST-запроса и фрагменты сообщения. Больше они не нужны
    УдалитьФайлы(ИмяФайлаОтправки);
    Если НЕ КодироватьФайл Тогда
        Для каждого ЭлементМассива Из МассивФайловДляОбъединения Цикл
            УдалитьФайлы(ЭлементМассива);
        КонецЦикла;
    КонецЕсли;


Отправили данные, анализируем ответ сервера.

    ФайлОтвета = Новый Файл(ИмяФайлаОтвета);
    Если ФайлОтвета.Существует() Тогда
        ТекстОтвета = Новый ТекстовыйДокумент();
        ТекстОтвета.Прочитать(ИмяФайлаОтвета);
        Если ТекстОтвета.КоличествоСтрок() > 0 Тогда
            ОтветСервера = ТекстОтвета.ПолучитьТекст();
            #Если Клиент Тогда
                Сообщить(ОтветСервера);
            #КонецЕсли
        Иначе
            #Если Клиент Тогда
                Сообщить("Отправка файла на сервер: Получен пустой ответ сервера.");
            #Иначе
                ЗаписьЖурналаРегистрации("HTTPСоединение", УровеньЖурналаРегистрации.Ошибка, , , "Получен пустой ответ сервера.");
            #КонецЕсли
        КонецЕсли;

        //Удалим файл ответа. Больше он нам не нужен.
        УдалитьФайлы(ИмяФайлаОтвета);
    Иначе
        #Если Клиент Тогда
            Сообщить("Отправка файла на сервер: Ответ сервера не получен.");
        #Иначе
            ЗаписьЖурналаРегистрации("HTTPСоединение", УровеньЖурналаРегистрации.Ошибка, , , "Ответ сервера не получен.");
        #КонецЕсли
КонецЕсли;


Отправка файла на сервер в стиле платформы 8.3., 8.2.18 и позднее

Попытка
    АдресСкрипта = "some_script.php"; //Без протокола  и имени домена. Естественно, следует указать имя своего скрипта.

    //Формируем HTTP запрос
    ЗапросHTTP = Новый HTTPЗапрос(АдресСкрипта, ЗаголовокHTTP);
    ЗапросHTTP.УстановитьИмяФайлаТела(ИмяФайлаОтправки);  //Устанавливает имя файла, из которого будет прочитано тело POST-запроса.

    //Ответ от сервера получим в возвращаемом значении типа HTTPОтвет
    ОтветHTTP = НТТР.ОтправитьДляОбработки(ЗапросHTTP);
Исключение
    //Реализацию процедуры УстановитьHTML смотреть в прилагаемой обработке
    УстановитьHTML("Неудачная попытка соединения с " + СерверПриемник + ": " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

//Разрушаем объект HTTP-запроса для освобождения файла POST-запроса.
//В противном случае при попытке удаления файла получим ошибку совместного доступа.
ЗапросHTTP = Неопределено;

//Удаляем файлы POST-запроса и фрагменты сообщения. Больше они не нужны.
УдалитьФайлы(ИмяФайлаОтправки);
Для каждого ЭлементМассива Из МассивФайловДляОбъединения Цикл
    УдалитьФайлы(ЭлементМассива);
КонецЦикла;


Некоторые сервера после получения и обработки POST или GET-запроса могут вернуть не результат исполнения скрипта, а переадресовать на другую страницу, то есть вернуть код 301 Moved Permanently или 302 Moved Temporarily. В этом случае следует проверить код состояния ответа. Реализацию функции ПолучитьСодержимоеВебАдреса() смотрите на странице Получение содержимого указанного адреса url (вебстраницы) для 1С: Предприятия 8.2.18 - 8.3

//Анализируем и выводим ответ сервера в виде строки
//Для начала следует на всякий случай проверить код состояния ответа сервера
Если ОтветHTTP.КодСостояния = 301 или ОтветHTTP.КодСостояния = 302 Тогда //
    //Если сервер вернул один из статусов переадресации
    //301 Moved Permanently («перемещено навсегда») или 302 Moved Temporarily («перемещено временно»)
    //В этом случае можно попытаться получить содержимое страницы, на которую переадресовал сервер
    ЗаголовкиОтвета = ОтветHTTP.Заголовки;
    Если ЗаголовкиОтвета.Количество() > 0 Тогда
        //Адрес страницы содержится в поле Location заголовка ответа
        АдресСтраницы = ЗаголовкиОтвета.Получить("Location");
        Если Найти(АдресСтраницы, СерверПриемник + "/") = 0  Тогда
            АдресСтраницы = "http://" + СерверПриемник + "/" + АдресСтраницы;
        КонецЕсли;
        Если ЗначениеЗаполнено(АдресСтраницы) Тогда
            СтрокаОтветаСервера = ПолучитьСодержимоеВебАдреса(АдресСтраницы, , ЗаголовкиОтвета);
        КонецЕсли;
    КонецЕсли;
КонецЕсли;


Анализируем и выводим ответ сервера в виде строки.
СтрокаОтветаСервера = ОтветHTTP.ПолучитьТелоКакСтроку();
Если ЗначениеЗаполнено(СтрокаОтветаСервера) Тогда
    СтрокаОтветаСервера = СтрЗаменить(СтрокаОтветаСервера, Символы.ПС, "
"
); УстановитьHTML("Ответ сервера: " + СтрокаОтветаСервера); Иначе УстановитьHTML("Отправка файла на сервер: Получен пустой ответ сервера."); КонецЕсли; УстановитьHTML("Код состояния: " + XMLСтрока(ОтветHTTP.КодСостояния ), Истина);


Получаем и выводим HTTP-заголовки ответа сервера в виде соответствия: "Название заголовка" - "Значение".
ЗаголовкиОтвета = ОтветHTTP.Заголовки;
Если ЗаголовкиОтвета.Количество() > 0 Тогда
    УстановитьHTML("Заголовки ответа:", Истина);
    Для каждого КлючИЗначение Из ЗаголовкиОтвета Цикл
        УстановитьHTML(КлючИЗначение.Ключ + ": " + КлючИЗначение.Значение, Истина);
    КонецЦикла; //Для каждого КлючИЗначение Из ЗаголовкиОтвета
КонецЕсли;


Подробную реализацию отправки файла с кодированием и без кодирования смотрите в приложенных обработках Загрузка файлов на веб-сервер.epf или Отправка данных и загрузка файлов на веб-сервер 8.3.epf.

Отправка простого POST-запроса на сервер в стиле платформы 8.3., 8.2.18 и позднее, без использования промежуточных файлов

Код:
//Тело POST-запроса
ТелоPOSTЗапроса = "";
ТелоPOSTЗапроса = ТелоPOSTЗапроса + "&param1=" + Параметр1;
ТелоPOSTЗапроса = ТелоPOSTЗапроса + "&param2=" + Параметр2;
ТелоPOSTЗапроса = ТелоPOSTЗапроса + "&param3=" + Параметр3;
ТелоPOSTЗапроса = ТелоPOSTЗапроса + "&param4=" + Параметр4;

//POST-запрос на сервер-приёмник
СерверПриемник = "www.server_name.com"; //имя сервера без протокола (http) и порта
АдресСтраницыНаСервере = "/search.cgi"; //

ЗаголовкиHTTP = Новый Соответствие;
ЗаголовкиHTTP.Вставить("Content-Type", "application/x-www-form-urlencoded");

Таймаут = 120;
SSL =  ?(ЗащищенноеСоединение, Новый ЗащищенноеСоединениеOpenSSL(), Неопределено);
НТТР = Новый HTTPСоединение(СерверПриемник, , , , , Таймаут, SSL);

Попытка
    //Формируем HTTP запрос
    ЗапросHTTP = Новый HTTPЗапрос(АдресСтраницыНаСервере, ЗаголовкиHTTP);
    ЗапросHTTP.УстановитьТелоИзСтроки(ТелоPOSTЗапроса); //Устанавливает строку, из которого будет прочитано тело POST-запроса.

    //Ответ от сервера получим в возвращаемом значении типа HTTPОтвет
    ОтветHTTP = НТТР.ОтправитьДляОбработки(ЗапросHTTP);
Исключение
    ТекстСообщения = НСтр("ru = 'Неудачная попытка соединения с '")  + СерверПриемник + ": " + ОписаниеОшибки();
    ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
    Возврат;
КонецПопытки;

ЗаголовкиHTTP = Новый Соответствие;
СтрокаОтветаСервера = "";
//Анализируем и выводим ответ сервера в виде строки
//Для начала следует на всякий случай проверить код состояния ответа сервера
Если ОтветHTTP.КодСостояния = 301 или ОтветHTTP.КодСостояния = 302 Тогда //
    //Если сервер вернул один из статусов переадресации
    //301 Moved Permanently («перемещено навсегда») или 302 Moved Temporarily («перемещено временно»)
    //В этом случае можно попытаться получить содержимое страницы, на которую переадресовал сервер
    ЗаголовкиОтвета = ОтветHTTP.Заголовки;
    Если ЗаголовкиОтвета.Количество() > 0 Тогда
        //Адрес страницы содержится в поле Location заголовка ответа
        АдресСтраницы = ЗаголовкиОтвета["Location"];
        Если Найти(АдресСтраницы, СерверПриемник + "/") = 0  Тогда
            АдресСтраницы = "http://" + СерверПриемник + "/" + АдресСтраницы;
        КонецЕсли;
        Если ЗначениеЗаполнено(АдресСтраницы) Тогда
            //Если сервер вернул cookies (http://ru.wikipedia.org/wiki/HTTP_cookie, http://www.faqs.org/rfcs/rfc6265.html?#41;,
            //вставим их в заголовки для передачи на страницу перехода
            Куки = ОтветHTTP.Заголовки["Set-Cookie"];
            Если ЗначениеЗаполнено(Куки) Тогда
                ЗаголовкиHTTP.Вставить("Cookie", Куки);
            КонецЕсли;
            СтрокаОтветаСервера = ПолучитьСодержимоеВебАдреса(АдресСтраницы, , , ЗаголовкиHTTP);
        КонецЕсли;
    КонецЕсли;
Иначе
    //Анализируем и выводим ответ сервера в виде строки
    СтрокаОтветаСервера = ОтветHTTP.ПолучитьТелоКакСтроку();
КонецЕсли;


Примерное содержимое скрипта-приёмника данных на веб-сервере "some_script.php". Скрипт вы также можете извлечь из макета обработки Загрузка файлов на веб-сервер.epf или Отправка данных и загрузка файлов на веб-сервер 8.3.epf.

Код:
<?
//Coded by Sergey aka Porutchik http://forum.aeroion.ru
//http://forum.aeroion.ru/topic446.html

//Читаем текстовые данные POST-запроса
$submit = ( isset($_POST['submit']) ) ? intval($_POST['submit']) : false;
$decode = ( isset($_POST['decode']) ) ? intval($_POST['decode']) : false;
$message = ( isset($_POST['message']) ) ? htmlspecialchars($_POST['message']) : '';

//Проверим user-agent, хотя большого толку от такой проверки нет. См. статью.
if ( $_SERVER['HTTP_USER_AGENT'] != '1C+Enterprise/8.1' )
{
    @header('HTTP/1.0 403 Forbidden');
    die('Hacking attempt');
}

if ( $submit )
{
    //Здесь работаем с содержимым переданного файла.
    $uploadFile = $_FILES['datafile'];
    $tmp_name = $uploadFile['tmp_name'];
    $data_filename = $uploadFile['name'];
    if ( !is_uploaded_file($tmp_name) ) 
    {
        die('Ошибка при загрузке файла ' . $data_filename);
    } 
    else 
    {
        //Считываем файл в строку
        $data = file_get_contents($tmp_name);

        if ($decode)
        {
            //При необходимости декодируем данные
            $data = base64_decode($data);
        }
        //Теперь нормальный файл можно сохранить на диске
        if ( !empty($data) && ($fp = @fopen($data_filename, 'wb')) )
        {
            @fwrite($fp, $data);
            @fclose($fp);
        }
        else
        {
            die('Ошибка при записи файла ' . $data_filename);
        }
        @header('HTTP/1.1 200 Ok');
        @header('Content-type: text/html; charset=windows-1251');
        $answer = "\n" . 'Файл <b>' . $data_filename . '</b> успешно загружен. ' . "\n" . 'Переданное сообщение: ' . $message;
        print ($answer);
    }
}
?>


В завершение статьи процитирую.
Обращаю ваше внимание, что указанная здесь методика освещает возможность загрузки файлов на сервер. Использование их "в чистом виде" без доработки может быть небезопасным, и является потенциальной возможностью для взлома вашего сайта. А именно, отсутствие обработки имени файла, который пришел на сервер, отсутствие авторизации, определения источника, посылающего файл, может дать злоумышленнику возможность загрузить и выполнить вредоносный код на вашем сайте. Рассмотрение способов защиты не входит в данную статью и остается на ваше усмотрение.


Список использованной литературы:

Скрытый текст:
Показать


Скачать Отправка данных и загрузка файлов на веб-сервер 8.3.epf (33.21 KB). Добавлен/обновлён Пт 06 Ноя, 2015 14:09. Скачано 391 раз(а).
Скачивание для зарегистрированных пользователей. Обработка, иллюстрирующая отправку данных, загрузку файлов на веб-сервер, скачивание файла с сервера для платформы 8.3.X, 8.2.18, 8.2.19.

Скачать Загрузка файлов на веб-сервер.epf (15.68 KB). Добавлен/обновлён Сб 02 Мар, 2013 16:23. Скачано 400 раз(а).
Скачивание для зарегистрированных пользователей. Устаревший вариант. Обработка, иллюстрирующая загрузку файлов на веб-сервер для платформы 8.1. и 8.2 до релиза 8.2.18. Для использования в 1С Предприятии 8.2. открыть в конфигураторе, согласиться на конвертацию.

Скачать ПросмотрИнфостарт.epf (11.76 KB). Добавлен/обновлён Пн 18 Май, 2009 18:10. Скачано 898 раз(а).
Скачивание для зарегистрированных пользователей. Устаревший вариант. Пример POST-запроса без файлов для платформы 8.1. и 8.2 до релиза 8.2.18. Просмотр и авторизация на сайте infostart.ru. Для использования в 1С Предприятии 8.2. открыть в конфигураторе, согласиться на конвертацию.

#
1. downloadfile.png (73.51 KB). Просмотрено 1512 раз(а).    

downloadfile.png
2. uploadfile.png (46.85 KB). Просмотрено 5693 раз(а).    

uploadfile.png

_________________
Профессионал - это тот же дилетант, только знающий где ошибется. Генератор db_update.php для phpBB2 с некоторыми удобствами.
Как ставить моды. Что такое [SQL] и с чем его едят | Как правильно задавать вопросы и получать адекватные ответы | Правила форума
Бесплатная техподдержка только на форуме! Не надо стучаться в аську, скайп, слать емайлы, пытаться писать в приват. Спасибо за понимание. Please do not PM, ICQ, Skype or email me for support help - you won't get any reply. If you have a question or issue, post it in the appropriate forum/topic. Thanks!
ВверхНа форуме нет Профиль Сайт Имя в Skype
andreyershov

Заинтересовался


Зарегистрирован: 19.02.2014
Показать/Спрятать

Добрый день!
Подскажите, пожалуйста, как правильно передавать логин и пароль в POST запрос?
Задача стоит такая:
Для передачи данных для доставки необходимо направить POST запрос на адрес:
maxipost.ru/ap.....secure=...
+ POST параметр «data», содержащий XML

Сам параметр "data" нужно передавать как строку из xml документа.
Проверял контакт через Google PostMan, там параметры вставляются прям в строку запроса, а параметр data как ключ для form-data

VH770gvMTa4.jpg

Код:
Процедура Загрузить()
    
    Логин = "24f54226a74ec88520d56f609e31c6a7";
    Пароль = "24f54226a74ec88520d56f609e31c6a7";
    Шифр = Формат(ТекущаяДата(),"ДФ=yyyy.MM.dd")+"T00:00:00&"+Пароль;
    ШифрПароль = MD5Eng(Шифр);
    
    ТекстДанных = Новый ТекстовыйДокумент;
    ТекстДанных.Прочитать(ИмяФайлаДляЗагрузки);
    Текст = ТекстДанных.ПолучитьТекст();
    
    
    Сервер = "http://www.maxipost.ru";
    Ресурс = "http://www.maxipost.ru/api/set_zakaz_to_db_test.php?account="+Логин+"&secure="+Пароль;
    HTTP =  Новый HTTPСоединение(Сервер);
    ФайлЗапроса = ПолучитьИмяВременногоФайла();
    ТекстовыйФайл = Новый ТекстовыйДокумент;
    ТекстовыйФайл.УстановитьТекст("&data=" + СокрЛП("Текст"));
    ТекстовыйФайл.Записать(ФайлЗапроса, КодировкаТекста.UTF8);
    ФайлРезультата = ПолучитьИмяВременногоФайла();
    ЗаголовокHTTP = Новый Соответствие();
    ЗаголовокHTTP.Вставить("Content-Type", "application/x-www-form-urlencoded");
    ЗаголовокHTTP.Вставить("Accept-Language", "ru");
    ЗаголовокHTTP.Вставить("Accept-Charset", "utf-8");
    ЗаголовокHTTP.Вставить("Content-Language", "ru");
    ЗаголовокHTTP.Вставить("Content-Charset", "utf-8");
    HTTP.ОтправитьДляОбработки(ФайлЗапроса, Ресурс, ФайлРезультата, ЗаголовокHTTP);
    Ответ = Новый ТекстовыйДокумент();
    Ответ.Прочитать(ФайлРезультата, КодировкаТекста.UTF8);
    ТекстОтвета = Ответ.ПолучитьТекст();
    УдалитьФайлы(ФайлЗапроса);
    УдалитьФайлы(ФайлРезультата);
КонецПроцедуры    


Такой код выдает ошибку работы с интернетом.

ВверхНа форуме нет Профиль
Sergey Пол:Муж.


Местный босс - администратор


Зарегистрирован: 06.01.2005
Показать/Спрятать

Посмотрите в синтаксис-помощнике класс HTTPЗапрос, УстановитьТелоИзСтроки(). Во-вторых, примеры обработок смотрите внимательней.
Код:
    Сервер = "www.maxipost.ru"; //указывается без http://
    Ресурс = "api/set_zakaz_to_db_test.php"; //указывается без http:// и имени домена 
ВверхНа форуме нет Профиль Сайт Имя в Skype
andreyershov

Заинтересовался


Зарегистрирован: 19.02.2014
Показать/Спрятать

А логин и пароль надо в строку ресурса вписывать или размещать в теле запроса?
Код:
Ресурс = "/api/set_zakaz_to_db_test.php?account="+Логин+"&secure="+Пароль; 

Так должно соединяться?
ВверхНа форуме нет Профиль
Sergey Пол:Муж.


Местный босс - администратор


Зарегистрирован: 06.01.2005
Показать/Спрятать

Не обязательно все параметры для передачи методом POST должны отправляться в теле запроса. Если методом GET, то надо указывать в параметрах адреса страницы.

Код:
//Получаем данные с HTTP-сервера, используя GET-запрос.

ЗапросСерверу = Новый HTTPЗапрос("some_script.php?param1=ppppp&amp;param2=xxxx");
Соединение = Новый HTTPСоединение("www.some_site.ru",,,,, Истина);
HTTPОтветСервера = Соединение.Получить(ЗапросСерверу);
ТекстОтветСервера = HTTPОтветСервера.ПолучитьТелоКакСтроку(); 


У вас написано, в общем-то верно, только можно обойтись без временного файла POST-запроса и ответа, если используется релиз 1С Предприятия 8.2.18 и позднее.

Добавлено спустя 1 час 36 минут 31 секунду:

Можно отправлять и так. В обработке это продемонстрировано.
ВверхНа форуме нет Профиль Сайт Имя в Skype
andreyershov

Заинтересовался


Зарегистрирован: 19.02.2014
Показать/Спрятать

Подскажите по методу GET, пожалуйста.
Пытаюсь получить ответ от сервера транспортной компании
Код:
    ИмяФайлаОтвета = "D:\GETotvet.xml";
    Соединение = Новый HTTPСоединение("www.maxipost.ru",,,,, Истина);
    Соединение.Получить(АдресСтраницы, ИмяФайлаОтвета);
 

На методе .Получить() выдает ошибку "Ошибка работы с Интернет: Peer certificate cannot be authenticated with known CA certificates"
Я так понимаю, что ошибка в неком сертификате. Как с этим можно бороться? Надо запрашивать сертификат в транспортной компании?
ВверхНа форуме нет Профиль
Sergey Пол:Муж.


Местный босс - администратор


Зарегистрирован: 06.01.2005
Показать/Спрятать

Сообщение Пн 24 Фев, 2014 16:02 Скачать сообщение Репутация: 88
 Защищённое соединение по протоколу https с использованием сертификатов для платформы 8.3
У них, скорее всего, поддержка защищённого соединения по протоколу HTTPS. Попробуйте как в примере (подробнее смотреть в СП)
Код:
    ssl = Новый ЗащищенноеСоединениеOpenSSL(
        Новый СертификатКлиентаWindows(СпособВыбораСертификатаWindows.Авто), Новый СертификатыУдостоверяющихЦентровWindows()
    );
    Соединение = Новый HTTPСоединение(
        "www.maxipost.ru", // хост запрашиваемого сервера
        443, // порт по умолчанию для используемого протокола https
        ,,,
        5, // таймаут в секундах
        ssl // защищенное HTTPS соединение
    );
    ИмяФайлаОтвета = "D:\GETotvet.xml";
    Соединение.Получить(АдресСтраницы, ИмяФайлаОтвета); 

Если не помогло, читаем темы
Peer certificate cannot be authenticated with known CA certificates
Включение своего сертификата в список доверенных для 1С в файл cacert.pem
Если не помогло, обратиться к админам МаксиПост за разъяснениями, что используется: OpenSSL или NSS.

_________________
Профессионал - это тот же дилетант, только знающий где ошибется. Генератор db_update.php для phpBB2 с некоторыми удобствами.
Как ставить моды. Что такое [SQL] и с чем его едят | Как правильно задавать вопросы и получать адекватные ответы | Правила форума
Бесплатная техподдержка только на форуме! Не надо стучаться в аську, скайп, слать емайлы, пытаться писать в приват. Спасибо за понимание. Please do not PM, ICQ, Skype or email me for support help - you won't get any reply. If you have a question or issue, post it in the appropriate forum/topic. Thanks!
ВверхНа форуме нет Профиль Сайт Имя в Skype
andreyershov

Заинтересовался


Зарегистрирован: 19.02.2014
Показать/Спрятать

Сообщение Пн 24 Фев, 2014 16:16 Скачать сообщение Репутация: 0
 Защищённое соединение по протоколу https для платформы 8.2.18 и позднее
Спасибо большое! Заработало!!
Использовал упрощенную версию предложенного кода:
Код:
    ssl = Новый ЗащищенноеСоединениеOpenSSL;
    Соединение = Новый HTTPСоединение(
    "www.maxipost.ru",
    443, // порт по умолчанию для используемого протокола. 
    ,,,
    5, // таймаут в секундах
    ssl // защищенное HTTPS соединение
    );
    ИмяФайлаОтвета = "D:\GETotvet.xml";
    Соединение.Получить(АдресСтраницы, ИмяФайлаОтвета);
ВверхНа форуме нет Профиль
LelPalna Пол:Жен.

Участница


Зарегистрирован: 24.03.2014
Показать/Спрятать

Добрый день!
Sergey, бьюсь и никак не могу добиться результата.. Надеюсь на Вашу помощь в следующем вопросе:
БухгалтерияПредприятия 2.0. С надстройкой, где реализовано подключение из 1С к веб-сервисам поставщиков. Веб-сервисы у всех разные, у всех свои сертификаты. :

Код:

    Попытка
        //Новый HTTPСоединение("https://sofi.aviroom.ru:30443/orawsv/SOFI_RAO/P_CRSDATA?wsdl")
        
        Если Лев(Определение, СтрДлина("https://")) = "https://" Тогда
            ПутьБезПротокола = Сред(Определение, СтрДлина("https://")+1);
            ПозСлеш = Найти(ПутьБезПротокола, "/");
            ДопСтрока = Сред(ПутьБезПротокола, ПозСлеш+1);
            АдресПорт = Лев(ПутьБезПротокола, ПозСлеш-1);
            ПозДвоеточие = Найти(АдресПорт, ":");
            Если ПозДвоеточие Тогда
                Адрес = Лев(АдресПорт, ПозДвоеточие-1);
                Порт = Сред(АдресПорт, ПозДвоеточие+1);
            Иначе
                Адрес = АдресПорт;
                Порт = "443";
            КонецЕсли;
            ИмяПользователя = "SOFI_SA";
            ПарольПользователя = "af39fsdR27";
            
            Соединение = Новый HTTPСоединение(Адрес, Число(Порт), ИмяПользователя, ПарольПользователя,, Истина);
            ВремФайл = ПолучитьИмяВременногоФайла("xml");
            Соединение.Получить(ДопСтрока, ВремФайл);
            Чтение = Новый ЧтениеТекста(ВремФайл);
            Строка = Чтение.Прочитать();
            Чтение.Закрыть();
            Строка = СтрЗаменить(Строка, "http://"+Адрес+":"+Порт, "https://"+Адрес+":"+Порт);
            Строка = СтрЗаменить(Строка, "http://"+Адрес+"/", "https://"+Адрес+"/");
            Запись = Новый ЗаписьТекста(ВремФайл);
            Запись.Записать(Строка);
            Запись.Закрыть();
            МоеОпределение = "file:///"+СтрЗаменить(ВремФайл, "\", "/");
            
            Если ПустаяСтрока(ИмяПользователя) Тогда
                WSОпределение = Новый WSОпределения(МоеОпределение);
            Иначе
                WSОпределение = Новый WSОпределения(МоеОпределение, ИмяПользователя, ПарольПользователя);
            КонецЕсли;
            
            УдалитьФайлы(ВремФайл);
        Иначе
            Если ПустаяСтрока(ИмяПользователя) Тогда
                WSОпределение = Новый WSОпределения(Определение);
            Иначе
                WSОпределение = Новый WSОпределения(Определение, ИмяПользователя, ПарольПользователя);
            КонецЕсли;
        КонецЕсли;
        
        URIПространстваИмен = WSОпределение.Сервисы[0].URIПространстваИмен;
        ИмяСервиса = WSОпределение.Сервисы[0].Имя;
        ПортСервиса = WSОпределение.Сервисы[0].ТочкиПодключения[0].Имя;
        Прокси = Новый WSПрокси(WSОпределение, URIПространстваИмен, ИмяСервиса, ПортСервиса);
        Прокси.Пользователь = ИмяПользователя;
        Прокси.Пароль= ПарольПользователя;
    Исключение
        ПодробноеОписание(ИнформацияОбОшибке());
    КонецПопытки;
    Возврат Прокси;


Все это счастье отлично работало до выхода платформы 8.2.19.80. Теперь при попытке получения HTTPСоединения у пары поставщиков при выполнении метода "Получить" вылетает с ошибкой:
Ошибка при вызове метода контекста (Получить)
[1]--> По причине: Ошибка работы с Интернет: SSL connect error

При этом при подключении к другим поставщикам, все работает как работало.Корневой сертификат установлен, ошибок при открытии ссылки в браузере нет.. В cacert.pem прописывала отдельно, хотя он итак там есть (реализовано в программе).
Можете подсказать что делать?
ВверхНа форуме нет Профиль
Sergey Пол:Муж.


Местный босс - администратор


Зарегистрирован: 06.01.2005
Показать/Спрятать

Ваша тема? Не могу подключиться к веб-сервису, начиная с платформы 8.2.19.80
Попробуйте переписать Соединение = Новый HTTPСоединение по примеру из поста Защищённое соединение по протоколу https с использованием сертификатов для платформы 8.3 или поста ниже.
Поднять платформу до последней в линии 8.2 или 8.3.

_________________
Профессионал - это тот же дилетант, только знающий где ошибется. Генератор db_update.php для phpBB2 с некоторыми удобствами.
Как ставить моды. Что такое [SQL] и с чем его едят | Как правильно задавать вопросы и получать адекватные ответы | Правила форума
Бесплатная техподдержка только на форуме! Не надо стучаться в аську, скайп, слать емайлы, пытаться писать в приват. Спасибо за понимание. Please do not PM, ICQ, Skype or email me for support help - you won't get any reply. If you have a question or issue, post it in the appropriate forum/topic. Thanks!
ВверхНа форуме нет Профиль Сайт Имя в Skype
LelPalna Пол:Жен.

Участница


Зарегистрирован: 24.03.2014
Показать/Спрятать

Моя.. Как видите, миллион ответов)
Переписывала в виде:
Код:
// адрес: https://sofi.aviroom.ru:8443/orawsv/SOFI_RAO/P_CRSDATA?wsdl
        ssl = Новый ЗащищенноеСоединениеOpenSSL;
        Попытка
            Соединение = Новый HTTPСоединение("sofi.aviroom.ru", "8443", ИмяПользователя, ПарольПользователя,,, ssl);
            ИмяФайлаОтвета = ПолучитьИмяВременногоФайла("xml");
            Соединение.Получить("orawsv/SOFI_RAO/P_CRSDATA?wsdl", ИмяФайлаОтвета); 
        Исключение
            ПодробноеОписание(ИнформацияОбОшибке());
        КонецПопытки;

Установила вчера платформу 8.2.19.90.
Все верно, но все равно выходит сообщение про Ошибка работы с Интернет: SSL connect error, хоть и СП уверяет, что ЗащищенноеСоединениеOpenSSL "предназначен для установки защищенного SSL-соединения без проверки сертификата сервера и без предоставления клиентского сертификата."
Насчет ОтправитьДляОбработки.. Запуталась с HTTPЗапросом
ВверхНа форуме нет Профиль
Sergey Пол:Муж.


Местный босс - администратор


Зарегистрирован: 06.01.2005
Показать/Спрятать

В вашем случае ОтправитьДляОбработки не нужно.
Видимо, у той несчастной пары поставщиков сервера перестали дружить с 1С платформой позднее 8.2.19.80, или платформа позднее 8.2.19.80 перестала дружить с некоторыми защёнными серверами и их сертификатами.
Или мне самому нормально браться за это дело, или вам вернуть прежнюю платформу и ждать, когда 1С исправит ошибку. Больше ничем не помогу.

_________________
Профессионал - это тот же дилетант, только знающий где ошибется. Генератор db_update.php для phpBB2 с некоторыми удобствами.
Как ставить моды. Что такое [SQL] и с чем его едят | Как правильно задавать вопросы и получать адекватные ответы | Правила форума
Бесплатная техподдержка только на форуме! Не надо стучаться в аську, скайп, слать емайлы, пытаться писать в приват. Спасибо за понимание. Please do not PM, ICQ, Skype or email me for support help - you won't get any reply. If you have a question or issue, post it in the appropriate forum/topic. Thanks!
ВверхНа форуме нет Профиль Сайт Имя в Skype
LelPalna Пол:Жен.

Участница


Зарегистрирован: 24.03.2014
Показать/Спрятать

Ясно. спасибо!
временно, конечно, вернула платформу, но это лишь временная мера.
Подскажите только, пожалуйста, в моем случае чему "равен" АдресРесурса? (свойство HTTPЗапроса). С этими танцами с бубном уже во всем начинаю сомневаться
ВверхНа форуме нет Профиль
Sergey Пол:Муж.


Местный босс - администратор


Зарегистрирован: 06.01.2005
Показать/Спрятать

АдресРесурса - Адрес страницы на сервере без протокола (http://, , etc), доменного имени сервера (хоста), порта. Выделенная часть адреса https ://sofi.aviroom.ru:8443/orawsv/SOFI_RAO/P_CRSDATA?wsdl и есть АдресРесурса
ВверхНа форуме нет Профиль Сайт Имя в Skype
LelPalna Пол:Жен.

Участница


Зарегистрирован: 24.03.2014
Показать/Спрятать

Всё так. Спасибо.
ВверхНа форуме нет Профиль
Показать сообщения:   

Общий рейтинг темы Передача / получение файлов и данных на веб-сервер средствами 1С:Предприятие 8.X методом POST / GET
Средний рейтинг: 3.45 :: Мин. рейтинг: 0 :: Макс. рейтинг: 5 :: Количество оценок: 11
Выберите вашу оценку: 1   2   3   4   5  


Похожие темы
Тема Автор Форум Ответов Посл. сообщение
Нет новых сообщений Функция. Получение содержимого адреса url (вебстраницы) методом GET для 1С: Предприятия 8.2....
взаимодействие с веб-сервером
Универсальная функция, позволяющая получить содержимое ответа HTTP-сервера. Пример использования можно посмотреть в обработке 516 из статьи Передача файлов и данных на веб-сервер средствами 1С:Предприятие 8.X методом
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 0 Вс 02 Мар, 2014 21:55 Посмотреть последнее сообщение
Sergey
Нет новых сообщений Передача параметров / значений во внешнюю печатную форму для конфигураций на БСП (1С:Предпри...
Обработка (управляемое приложение, внешняя печатная форма). Открытие диалога перед печатью
В некоторых случаях перед печатью документа требуется вручную указать какие-либо значения или параметры и передать в процедуру Печать() обработки. Для конфигураций линии УТ 10.3, БП 2.0 есть возможность передачи
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 29 Вт 11 Апр, 2017 16:24 Посмотреть последнее сообщение
Sergey
Нет новых сообщений Шифрование файлов
Хотят хранить файлы с оргиналами документов на сервере, но в шифрованном виде и чтобы 1С-ка могла расшифровать. Есть ли какие-то стандартные способы шифрования?
Михута_Сергей 1Сv8: Программирование, отчёты, обработки, статьи 1 Вт 03 Мар, 2015 16:55 Посмотреть последнее сообщение
Sergey
Нет новых сообщений Функция. Чтение значений реквизитов объекта в структуру
1С: Предприятие 8.Х
Универсальная функция, позволяющая прочитать в структуру или простую переменную значения указанных или всех реквизитов произвольного объекта ссылочного типа, в том числе системных (дата, номер, код, наименование,
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 0 Вс 25 Июл, 2010 12:17 Посмотреть последнее сообщение
Sergey
Нет новых сообщений [ Опрос ] Общий журнал документов в управляемом приложении (1С: Предприятие 8.2)
обработка (управляемое приложение)
Добрый день, коллеги! Нашел Ваш форум - очень порадовал качественный контент :) В качестве прописки предлагаю обработку Общий журнал документов Вот, ссылка :) Обработка ранее выкладывалась на инфостарте. А ещё есть
Nike.Kolpinsky 1Сv8: Программирование, отчёты, обработки, статьи 1 Пт 17 Май, 2013 22:15 Посмотреть последнее сообщение
Sergey






Часовой пояс: UTC + 3 часа
Просматривают тему:
Зарегистрированные пользователи: Нет

Перейти:   
Версия для печати
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете вкладывать файлы
Вы можете скачивать файлы
/a
Имя:

Пароль:

Запомнить
  Яндекс.Метрика
CrackerTracker © 2004 - 2017 CBACK.de