Что такое код xmlrpc_set_type

Содержание

xmlrpc_set_type

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_set_type — Устанавливает тип XML-RPC, base64 или datetime для значения строки PHP

Описание

Устанавливает XML-RPC тип, base64 или datetime для значения строки PHP.

Эта функция является ЭКСПЕРИМЕНТАЛЬНОЙ. Поведение этой функции, ее имя и относящаяся к ней документация могут измениться в последующих версиях PHP без уведомления. Используйте эту функцию на свой страх и риск.

Список параметров

Значение для установки типа.

‘base64’ или ‘datetime’

Возвращаемые значения

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки. В случае успеха, value конвертируется в объект.

Примеры

Пример #1 Пример использования xmlrpc_set_type()

= date ( «Ymd\TH:i:s» , time ());
xmlrpc_set_type ( $params , ‘datetime’ );
echo xmlrpc_encode ( $params );

Результатом выполнения данного примера будет что-то подобное:

Ошибки

Выдает сообщение E_WARNING для не поддерживаемых типов XMLRPC.

xmlrpc_set_type

(PHP 4 >= 4.1.0, PHP 5)

xmlrpc_set_type — Sets xmlrpc type, base64 or datetime, for a PHP string value

Описание

Sets xmlrpc type, base64 or datetime, for a PHP string value.

Эта функция является ЭКСПЕРИМЕНТАЛЬНОЙ. Поведение этой функции, ее имя и относящаяся к ней документация могут измениться в последующих версиях PHP без уведомления. Используйте эту функцию на свой страх и риск.

Список параметров

Value to set the type

‘base64’ or ‘datetime’

Возвращаемые значения

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки. If successful, value is converted to an object.

Примеры

Пример #1 A xmlrpc_set_type() example

= date ( «Ymd\TH:i:s» , time ());
xmlrpc_set_type ( $params , ‘datetime’ );
echo xmlrpc_encode ( $params );

Результатом выполнения данного примера будет что-то подобное:

Ошибки

Issues E_WARNING with type unsupported by XMLRPC.

Серверные классы XML-RPC и XML-RPCS

Класы XML-RPC CodeIgniter позволяет отправлять запросы на другой сервер, или создать свой собственный XML-RPC сервер чтобы получать запросы.

Что такое XML-RPC?

Довольно простой способ обмена данными между двумя компьютерами через интернет — использование XML. Компьютер, который отправляет XML-RPC запрос на другой компьютер, называется клиент. Принимающий запрос компьютер — сервер. Как только сервер получает и обрабатывает запрос, он отсылает назад ответ клиенту.

Например, с помощью MetaWeblog API, XML-RPC Клиент (обычно инструмент для публикаций) будет отправлять запрос на XML-RPC Сервер запущенный на вашем сайте. Этот запрос может являться новой записью блога, отправленной для публикации или это может быть запрос на редактирование существующующей записи. Когда XML-RPC Сервер получает этот запрос, он изучает его, чтобы определить, какие класс/метод должны быть вызваны для обработки запроса. После обработки сервер отправит обратно сообщение с ответом.

Подробные технические характеристики, вы можете изучить на XML-RPC сайте.

Использование XML-RPC класса

Инициализация класса

Как и большинство других классов CodeIgniter, классы XML-RPC и XML-RPCS инициализируется в вашем контроллере, используя функцию $this->load->library:

To load the XML-RPC class you will use:

После загрузки, xml-rpc библиотека объектов будет доступна через: $this->xmlrpc

Для загрузки класса XML-RPC Сервера следует использовать:

После загрузки, xml-rpcs библиотека объектов будет доступна через: $this->xmlrpcs

При использовании класса XML-RPC Сервера, следует загружать ОБА класса XML-RPC и the XML-RPC Сервер.

Отправка XML-RPC запросов

Для отправки запроса XML-RPC серверу необходимо указать следующую информацию:

  • URL сервера
  • Метод на сервере, который вы хотите использовать
  • Данные запроса (объяснение ниже).

Вот простой пример, который отправляет простой Weblogs.com пинг на Ping-o-Matic

Объяснение

Код выше инициализирует XML-RPC класс, с указанными URL сервера и методом для вызова (weblogUpdates.ping). Запрос (в нашем случае, заголовок и URL сайта) помещается в массив для отправки и компилируется функцией request(). Наконец, сформированный запрос будет отправлен. Если метод send_request() возвращает FALSE мы будет показано сообщение об ошибке отправленное XML-RPC Сервером.

Анатомия запроса

XML-RPC запрос — просто данные для передачи XML-RPC серверу. Каждая часть данных в запросе упоминается как параметр запроса. Пример выше имеет два параметра: URL и заголовок вашего сайта. Когда XML-RPC сервер получает ваш запрос, он ищет параметры в нем.

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

Вот простой пример массива с тремя параметрами:

При использовании типов данных отличных от строк или если у вас есть несколько различных типов данных, следует создать массив для каждого параметра с указанным типом данных на второй позиции:

В разделе ниже, предоставлены все типы данных.

Создание XML-RPC сервера

XML-RPC Сервер действует как «гаишник», ожидает входящие запросы и перенаправляет их в соответствующие функции для обработки.

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

Вот пример для иллюстрации:

Пример выше содержит массив определяющий два метода запроса допустимые на сервере. Допустимые методы находятся в левой части массива. Когда любой из них будет получен, они будут сопоставлены классу и методам в правой части массива.

Ключ ‘object’ это специальный ключ, который вы передаете в объект класса, который необходим при выполнении сопоставления метода и он не является частью CodeIgniter супер объекта.

Другими словами, если XML-RPC Клиент отправляет запрос в new_post метод, ваш сервер загрузит класс My_blog и вызовет new_entry функцию. Если запрос в update_post метод, ваш сервер загрузит класс My_blog и вызовет метод update_entry() .

Имена функции в примере выше являются произвольными. Вы сами решите как они должны называться на вашем сервере или если вы используете стандартизированный API, такие как Blogger или MetaWeblog API, вы будете использовать их имена функций.

Есть два дополнительных ключа для настройки, которые вы можете использовать при инициализации класса сервера: debug может быть установлен в TRUE для того, чтобы включить отладку и xss_clean может быть установлен в FALSE чтобы предотвратить отправку данных через метод xss_clean() библиотеки безопасности.

Обработка запросов сервером

Когда XML-RPC Сервер получает запрос и загружает класс/метод для обработки, он передаст объект в метод содержащий данные отправленные клиентом.

В примере выше, если предлагается метод new_post, сервер будет ожидать существование класса с этим прототипом:

Переменная $request — это объект, составленный сервером, который содержит данные, отправляемые XML-RPC клиентом. Используя этот объект, вы будете иметь доступ к параметрам запроса позволяющим обработать запрос. Когда все обработаете — будете отправлять ответ обратно клиенту.

Ниже приведен реальный пример Blogger API. Один из методов в Blogger API являеся getUserInfo() . С помощью этого метода XML-RPC клиент может послать серверу имя пользователя и пароль, а в ответ сервер отправляет обратно информацию о конкретном пользователь (nickname, user ID, email и т.д.). Вот как может выглядеть функция обработки:

Примечания:

Метод output_parameters() возвращает индексированный массив соответствующий параметрам запроса отправленного клиентом. В приведенном выше примере параметрами вывода будут логин и пароль.

Если имя пользователя и пароль отправленные клиентом являются недействительными, возвращается сообщение об ошибке используя метод send_error_message() .

Если операция была успешной, клиенту будет обратно отправлен массив содержащий информацию о пользователе.

Формат ответа

Аналогично Запросам, Ответы должен быть в виде массива. Однако, в отличие от запросов, ответ это массив который содержит один элемент. Этот элемент может быть массивом с несколькими дополнительными массивами, но там может быть только один индекс первичного массива. Иными словами, прототип этого:

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

Обратите внимание, что массив форматируется как строгий. Это наиболее распространенный тип данных для ответов.

Как и запрос, ответ может быть одним из семи типов данных, перечисленных в разделе Типы Данных.

Отправляем ответ ошибки

Если вам нужно отправить клиенту сообщение об ошибке, следует использовать следующие:

Первый параметр — номер ошибки, в то время как второй параметр — сообщение об ошибке.

Создание своих Клиента (Client) и Сервера (Server)

Чтобы помочь вам понять все, что мы рассмотрели до сих пор, давайте создадим пару контроллеров, которые действуют как XML-RPC Клиент и Сервер. Вы будете использовать клиент для отправки запроса на сервер и получите ответ.

Клиент (Client)

Используя текстовый редактор, создайте контроллер c названием Xmlrpc_client.php. Поместите в него этот код и сохраните этот файл в application/controllers/ каталоге:

В приведенном выше коде мы используем “url хелпер”. Вы можете найти больше информации на странице функции хелперов (помощников).

Сервер (Server)

Используя текстовый редактор, создайте контроллер c названием Xmlrpc_server.php. Поместите в него этот код и сохраните этот файл в application/controllers/ каталоге:

Пробуем!

Теперь посетите ваш сайт используя URL похожий на этот:

Теперь вы должны увидеть сообщение, которое вы отправили на сервер, и его ответ.

Созданный вами клиент отправляет сообщение (“How’s is going?”) на сервер, в “Greetings” метод. Сервер получает запрос и сопоставляет его с process() методом, где отправляется ответ.

Использование ассоциативных массивов параметром запроса

Если вы хотите использовать ассоциативный массив в параметрах метода вам нужно будет использовать тип данных struct:

Можно получить ассоциативный массив при обработке запроса на сервере.

Типы данных

Согласно XML-RPC spec существует семь типов значений, которые вы можете отправить через XML-RPC:

Справка класса

>CI_Xmlrpc initialize( [ $config = array() ] )

Параметры:
  • $config (массив) – Данные конфигурации
Возвращаемый тип:

Инициализирует XML-RPC библиотеку. Принимает ассоциативный массив содержащий параметры.

server($url [ , $port = 80 [ , $proxy = FALSE [ , $proxy_port = 8080 ] ] ] )

Устанавливает URL и номер порта сервера куда будет отправлен запрос:

Основная HTTP проверка подлинности также поддерживается, просто добавьте её в URL сервера:

timeout($seconds = 5)

Параметры:
  • $url (строка) – URL XML-RPC сервера
  • $port (число) – Порт сервера
  • $proxy (строка) – Дополнительный прокси-сервер
  • $proxy_port (число) – Прослушиваемый порт прокси-сервера
Возвращаемый тип:
Параметры:
  • $seconds (число) – Время ожидания в секундах
Возвращаемый тип:

Устанавливает время ожидания (в секундах), по истечении которого запрос будет отменен:

method($function)

Параметры:
  • $function (строка) – Имя метода
Возвращаемый тип:

Устанавливает метод, который будет запрошен у XML-RPC сервера:

Где method — имя метода.

request($incoming)

Принимает массив данных и строит запрос для отправки XML-RPC серверу:

send_request()

Параметры:
  • $incoming (массив) – Данные запроса
Возвращаемый тип:
Возвращает: TRUE при удаче, FALSE при неудаче
Возвращаемый тип: булево

Метод отправки запроса. Возвращает логическое значение TRUE или FALSE на основе успеха для неудачи, что позволяет использовать условно.

display_error()

Возвращает: Строку сообщения об ошибке
Возвращаемый тип: строка

Возвращает сообщение об ошибке в виде строки, если ваш запрос не удалось выполнить по каким то причинам.

display_response()

Возвращает: Ответ
Возвращаемый тип: смешанный

Возвращает ответ от удаленного сервера, как только получен запрос. Ответом обычно является ассоциативный массив.

send_error_message($number, $message)

Этот способ позволяет отправить сообщение об ошибке от сервера к клиенту. Первый параметр — номер ошибки, а второй параметр — сообщение об ошибке.

© Copyright 2014 — 2020, British Columbia Institute of Technology. Последнее обновление 22 Апреля 2020.

Что такое XML-RPC и как остановить атаку на WordPress

Главное меню » Блог-платформа wordpress » Что такое XML-RPC и как остановить атаку на WordPress

Включен ли XML-RPC на вашем веб-сайте на WordPress?

Быстрый способ проверить, является ли ваш сайт уязвимым, – это посетить следующий URL-адрес из браузера:

Если он включен, вы должны получить ответ, в котором говорится, что «сервер XML-RPC принимает только запросы POST».

Опасности и преимущества XML-RPC

В сообществе безопасности WordPress было много вопросов о XML-RPC. В основном есть две проблемы:

  1. XML-RPC можно использовать для DDoS-атаки
  2. Его можно использовать для повторного использования комбинаций имени пользователя и пароля

По крайней мере, это было возможно. С тех пор WordPress подключил лазейки (https://core.trac.wordpress.org/ticket/34336) , которые позволили людям одновременно попробовать сотни имен пользователей и паролей. Начиная с версии 4.4, она была улучшена. Теперь WordPress будет молча выполнять все последующие попытки входа в систему, как только один вызов XML-RPC завершился неудачно. Большой!

Тем не менее, есть те, кто по-прежнему обеспокоен легкостью, в то время как удаленные вызовы процедур, подобные этому, могут быть сделаны. Итак, вот несколько способов защитить ваш сайт от XML-RPC – начиная с самого легкого способа, до самого тяжелого.

Метод 1: Отключение Pingbacks

Это процесс, который использует ваш сервер в качестве невольного участника в атаке на другой сервер. В основном, кто-то говорит вашему сайту «Эй, этот URL-адрес, связанный с вашим блогом!», А затем ваш сайт отвечает «pingback» на этот URL. Кроме того, нет никакой проверки, что URL на самом деле сделал ссылку на вас. Сделайте это с сотнями уязвимых сайтов WordPress, и у вас есть DDoS-атака на ваших руках! Самый простой способ запретить использование вашего сайта таким образом – добавить следующий код в функции functions.php вашей темы:

Способ 2. Предотвращение всех запросов на аутентификацию через XML-RPC

Этот второй метод определяет, хотите ли вы разрешать методы XML-RPC, которые аутентифицируют пользователей. Возьмем, к примеру, публикацию блога по электронной почте. Сайт получит ваше электронное письмо, проверит вас через XML-RPC, а затем опубликует его, если совпадают учетные данные.

Многим людям неудобно, когда XML-RPC может просто принимать случайные вызовы, подобные этому. Это привело к попыткам сотен или тысяч попыток аутентификации. Несмотря на то, что WordPress с тех пор обращался к этой конкретной форме взлома, есть те, кто рекомендует просто отключить ее.

Для этого введите этот код в functions.php:

Важно отметить, что это не то же самое, что и первый метод. Этот код только отключает методы проверки подлинности и оставляет все остальные нетронутыми – например, pingbacks.

Способ 3: Отключить доступ к xmlrpc.php

Это самый экстремальный метод, который полностью отключает все функции XML-RPC. Он требует, чтобы вы редактировали файл .htaccess в корневом каталоге вашего WordPress. Добавьте следующий код вверху:

Теперь, когда действуют выше правила отказа, попытка доступа к xmlrpc.php будет выполняться со следующей страницей:

И это все, что нужно. Вы успешно отключили XML-RPC на своем сайте WordPress.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

xmlrpc_set_type

xmlrpc_set_type — устанавливает xmlrpc-тип, base64 или datetime, для строкового значения PHP.

Описание

bool xmlrpc_set_type (string value, string type)

Параметры:
  • $number (число) – Номер ошибки
  • $message (строка) – Сообщение ошибки
Возвращает:
Возвращаемый тип:

Эта функция — ЭКСПЕРИМЕНТАЛЬНАЯ. Поведение, имя и всё остальное, что задокументировано для данной функции может быть изменено в будущих релизах РНР без предупреждения. Вы можете использовать эту функцию только на свой страх и риск.

Предупреждение!

Эта функция в настоящее время ещё не задокументирована; имеется только список аргументов.

Как отключить XML-RPC в WordPress

Для тех, кто не знает, что такое XML-RPC — это WordPress API, позволяющий (удалённо) выводить, создавать, редактировать и удалять:

  • посты,
  • таксономии (рубрики, метки и прочее),
  • медиафайлы,
  • комментарии,
  • пользователей.

А также получать доступ к настройкам и изменять их.

Именно благодаря этому API работают различные приложения для iPhone, iPad и устройств на Android.

Так вот, в предыдущих версиях WordPress была вот такая штука в настройках:

Как известно, от «атома» WordPress отказался полностью, а протокол XML-RPC теперь установлен включенным по умолчанию.

Дело в том, что раньше протокол содержал некоторые уязвимости, а теперь их все залатали.

Для параноиков (я и сам такой) — чтобы отключить XML-RPC, вставляем этот код в functions.php :

Мне вот например не приходится пользоваться приложениями для iOS или Android, я пробовал конечно — ну вообще не понравилось, так что этот протокол мне ни к чему.

Удаляем метатеги с xmlrpc.php из head сайта

Насколько я знаю, существует два метатега:

  • (RSD) и
  • .

    Первый удаляется достаточно просто — хуком на wp_head. Чтобы удалить второй, вам скорее всего придётся открыть файл header.php в вашей теме wp и вручную удалить его из HTML-кода.

    В теме вашего сайта этих тегов может и не быть.

    Смотрите также

    Впервые познакомился с WordPress в 2009 году. С 2014 года меня можно встретить на WordCamp по всему миру — официальной конфе по WordPress, иногда там выступаю, но с 2020 выступаю только на тех, которые сам организовываю. Также периодически школа Epic Skills и LoftSchool приглашают меня вести у них уроки/вебинары.

    Если вам нужна помощь с вашим сайтом или может даже разработка с нуля — пишите мне.

    Комментарии 17

    Прочитал статью про программу Windows Live Writer, и решил пользоваться ею, как все цивилизованные блогеры. Но при установке связи и авторизации с блогом возникли проблемы. Выскакивает окошко с надписью»Программа Windows Live Writer не может автоматически определять настройки блога. Для продолжения выберите тип блога» Выбираю WordPress 2.2 + Ниже окно для ввода адреса блога, предлагает ввести адрес в виде»http:////xmlrpc.php» Вот здесь и начинаются мучения. После ввода адреса дает ошибку:
    «Произошла ошибка при попытке подключится к вашей службе блога по адресу http://ayasam.ru/xmlrpc.php «. Когда ввожу этот адрес в командную строку, получаю такой ответ «XML-RPC server accepts POST requests only.»
    Все другие варианты дают ошибку 404. мой сайт на WordPress 3.5 Искал в Инете инфу не нашел. Может кто сталкивался с этой проблемой?

    Windows Live Writer не использую, однако я заметил вот что:

    Уязвимость WordPress через файл xmlrpc.php. Решение есть!

    2015-11-28 / Вр:01:02 / просмотров: 24973

    Совсем недавно я позакрывал все дыры к адресу для входа в админ панель и думал, что все – атаки на вход админ панель прекратятся. Но я был абсолютно неправ, вечером мне пришло сообщение, что было заблокировано еще два IP адреса, которые ломились в админ (плагин limit login attempts).

    Я был в шоке, как им это удается?

    Но, так как у меня на WordPress установлен плагин «WordPress Firewall 2», мне пришло на почту уведомление о том, что были две атаки на файл «xmlrpc.php» .

    Заметьте, IP адреса совершенно одинаковы как в первом скриншоте, так и во втором. Значит, взломщик не использовал для взлома прямой адрес для входа в админ, он это делал через «xmlrpc.php» (мои догадки и они могут быть спорными).
    Почитал в интернете о файле «xmlrpc.php» и оказалось действительно, что это файл является дверью для взломщика, которая плохо защищенная. Именно большинство атак происходит благодаря этой лазейке, которая по умолчанию включена на всех сайтах WordPress. Вот те на! Называется, защитил свой блог. Это все равно, что позакрывал все окна и двери от вора на замки, но черный вход оставил открытым!

    Нужен ли файл «xmlrpc.php»?
    Прочитав некоторую информацию, я понял, что файл «xmlrpc.php» не такой уж и важен для WordPress. Просто с его помощью можно управлять блогом через различные приложения. Не знаю как вы, но я этой возможностью не пользуюсь, значит, зачем мне этот файл нужен, тем более, если он еще такой уязвимый. Будем отключать файл «xmlrpc.php» !

    Чтобы отключить файл «xmlrpc.php» , для самых ленивых рекомендуют использовать плагин «Disable XML-RPC». А поскольку мы не такие, то все сделаем сами, тем более это не сложно.

    Зайдите в файл функции темы «functions.php» и в самом конце файла перед знаком « ?> » вставьте вот этот код:

    Зайдите в файл «header.php» и найдите вот такую строчку:

    В файле «.htaccess» в самом конце вставьте вот такой код:

    Этим кодом мы всем запретим доступ к файлу «xmlrpc.php» .
    Я думаю, этого достаточно!

    С сегодняшнего дня я буду тестировать результат в течение месяца. Если за этот период не появится новая статья о том, что снова кто-то лезет в админку, значит задача решена и можно на некоторое время расслабиться .

    На сегодня все! Надеюсь, что статья была вам полезна, так как защита блога – это всегда важно и актуально.

    Интересно, какие еще загадки и сюрпризы таит в себе мой любимый движок WordPress?

    Вызов удаленных процедур (RPC)

    Концепция удаленного вызова процедур

    Идея вызова удаленных процедур состоит в расширении хорошо известного и понятного механизма передачи управления и данных внутри программы, выполняющейся на одной машине, на передачу управления и данных через сеть. Средства удаленного вызова процедур предназначены для облегчения организации распределенных вычислений. Наибольшая эффективность использования RPC достигается в тех приложениях, в которых существует интерактивная связь между удаленными компонентами с небольшим временем ответов и относительно малым количеством передаваемых данных. Такие приложения называются RPC-ориентированными.

    Характерными чертами вызова локальных процедур являются:

    Асимметричность, то есть одна из взаимодействующих сторон является инициатором;

    Синхронность, то есть выполнение вызывающей процедуры при останавливается с момента выдачи запроса и возобновляется только после возврата из вызываемой процедуры.

    Реализация удаленных вызовов существенно сложнее реализации вызовов локальных процедур. Начнем с того, что поскольку вызывающая и вызываемая процедуры выполняются на разных машинах, то они имеют разные адресные пространства, и это создает проблемы при передаче параметров и результатов, особенно если машины не идентичны. Так как RPC не может рассчитывать на разделяемую память, то это означает, что параметры RPC не должны содержать указателей на ячейки нестековой памяти и что значения параметров должны копироваться с одного компьютера на другой. Следующим отличием RPC от локального вызова является то, что он обязательно использует нижележащую систему связи, однако это не должно быть явно видно ни в определении процедур, ни в самих процедурах. Удаленность вносит дополнительные проблемы. Выполнение вызывающей программы и вызываемой локальной процедуры в одной машине реализуется в рамках единого процесса. Но в реализации RPC участвуют как минимум два процесса — по одному в каждой машине. В случае, если один из них аварийно завершится, могут возникнуть следующие ситуации: при аварии вызывающей процедуры удаленно вызванные процедуры станут «осиротевшими», а при аварийном завершении удаленных процедур станут «обездоленными родителями» вызывающие процедуры, которые будут безрезультатно ожидать ответа от удаленных процедур.

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

    Эти и некоторые другие проблемы решает широко распространенная технология RPC, лежащая в основе многих распределенных операционных систем.

    Базовые операции RPC

    Чтобы понять работу RPC, рассмотрим вначале выполнение вызова локальной процедуры в обычной машине, работающей автономно. Пусть это, например, будет системный вызов

    где fd — целое число,
    buf — массив символов,
    nbytes — целое число.

    Чтобы осуществить вызов, вызывающая процедура заталкивает параметры в стек в обратном порядке (рисунок 3.1). После того, как вызов read выполнен, он помещает возвращаемое значение в регистр, перемещает адрес возврата и возвращает управление вызывающей процедуре, которая выбирает параметры из стека, возвращая его в исходное состояние. Заметим, что в языке С параметры могут вызываться или по ссылке (by name), или по значению (by value). По отношению к вызываемой процедуре параметры-значения являются инициализируемыми локальными переменными. Вызываемая процедура может изменить их, и это не повлияет на значение оригиналов этих переменных в вызывающей процедуре.

    Если в вызываемую процедуру передается указатель на переменную, то изменение значения этой переменной вызываемой процедурой влечет изменение значения этой переменной и для вызывающей процедуры. Этот факт весьма существенен для RPC.

    Существует также другой механизм передачи параметров, который не используется в языке С. Он называется call-by-copy/restore и состоит в необходимости копирования вызывающей программой переменных в стек в виде значений, а затем копирования назад после выполнения вызова поверх оригинальных значений вызывающей процедуры.

    Решение о том, какой механизм передачи параметров использовать, принимается разработчиками языка. Иногда это зависит от типа передаваемых данных. В языке С, например, целые и другие скалярные данные всегда передаются по значению, а массивы — по ссылке.

    Рис. 3.1. а) Стек до выполнения вызова read;
    б) Стек во время выполнения процедуры;
    в) Стек после возврата в вызывающую программу

    Идея, положенная в основу RPC, состоит в том, чтобы сделать вызов удаленной процедуры выглядящим по возможности также, как и вызов локальной процедуры. Другими словами — сделать RPC прозрачным: вызывающей процедуре не требуется знать, что вызываемая процедура находится на другой машине, и наоборот.

    RPC достигает прозрачности следующим путем. Когда вызываемая процедура действительно является удаленной, в библиотеку помещается вместо локальной процедуры другая версия процедуры, называемая клиентским стабом (stub — заглушка). Подобно оригинальной процедуре, стаб вызывается с использованием вызывающей последовательности (как на рисунке 3.1), так же происходит прерывание при обращении к ядру. Только в отличие от оригинальной процедуры он не помещает параметры в регистры и не запрашивает у ядра данные, вместо этого он формирует сообщение для отправки ядру удаленной машины.

    Этапы выполнения RPC

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

    Затем параметры должны быть преобразованы в соответствующий формат и вставлены в буфер сообщения. К этому моменту сообщение готово к передаче, поэтому выполняется прерывание по вызову ядра.

    Рис. 3.2. Remote Procedure Call

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

    На стороне сервера поступающие биты помещаются принимающей аппаратурой либо во встроенный буфер, либо в оперативную память. Когда вся информация будет получена, генерируется прерывание. Обработчик прерывания проверяет правильность данных пакета и определяет, какому стабу следует их передать. Если ни один из стабов не ожидает этот пакет, обработчик должен либо поместить его в буфер, либо вообще отказаться от него. Если имеется ожидающий стаб, то сообщение копируется ему. Наконец, выполняется переключение контекстов, в результате чего восстанавливаются регистры и карта памяти, принимая те значения, которые они имели в момент, когда стаб сделал вызов receive.

    Теперь начинает работу серверный стаб. Он распаковывает параметры и помещает их соответствующим образом в стек. Когда все готово, выполняется вызов сервера. После выполнения процедуры сервер передает результаты клиенту. Для этого выполняются все описанные выше этапы, только в обратном порядке.

    Рисунок 3.3 показывает последовательность команд, которую необходимо выполнить для каждого RPC-вызова, а рисунок 3.4 — какая доля общего времени выполнения RPC тратится на выполнение каждого их описанных 14 этапов. Исследования были проведены на мультипроцессорной рабочей станции DEC Firefly, и, хотя наличие пяти процессоров обязательно повлияло на результаты измерений, приведенная на рисунке гистограмма дает общее представление о процессе выполнения RPC.

    Рис. 3.3. Этапы выполнения процедуры RPC

    Рис. 3.4. Распределение времени между 14 этапами выполнения RPC

    3. Упаковать параметры

    4. Заполнить поле заголовка

    5. Вычислить контрольную сумму в сообщении

    6. Прерывание к ядру

    7. Очередь пакета на выполнение

    8. Передача сообщения контроллеру по шине QBUS

    9. Время передачи по сети Ethernet

    10. Получить пакет от контроллера

    11. Процедура обработки прерывания

    12. Вычисление контрольной суммы

    13. Переключение контекста в пространство пользователя

    14. Выполнение серверного стаба

    Динамическое связывание

    Рассмотрим вопрос о том, как клиент задает месторасположение сервера. Одним из методов решения этой проблемы является непосредственное использование сетевого адреса сервера в клиентской программе. Недостаток такого подхода — его чрезвычайная негибкость: при перемещении сервера, или при увеличении числа серверов, или при изменении интерфейса во всех этих и многих других случаях необходимо перекомпилировать все программы, которые использовали жесткое задание адреса сервера. Для того, чтобы избежать всех этих проблем, в некоторых распределенных системах используется так называемое динамическое связывание.

    Начальным моментом для динамического связывания является формальное определение (спецификация) сервера. Спецификация содержит имя файл-сервера, номер версии и список процедур-услуг, предоставляемых данным сервером для клиентов (рисунок 3.5). Для каждой процедуры дается описание ее параметров с указанием того, является ли данный параметр входным или выходным относительно сервера. Некоторые параметры могут быть одновременно входными и выходными — например, некоторый массив, который посылается клиентом на сервер, модифицируется там, а затем возвращается обратно клиенту (операция copy/ restore).

    Рис. 3.5. Спецификация сервера RPC

    Формальная спецификация сервера используется в качестве исходных данных для программы-генератора стабов, которая создает как клиентские, так и серверные стабы. Затем они помещаются в соответствующие библиотеки. Когда пользовательская (клиентская) программа вызывает любую процедуру, определенную в спецификации сервера, соответствующая стаб-процедура связывается с двоичным кодом программы. Аналогично, когда компилируется сервер, с ним связываются серверные стабы.

    При запуске сервера самым первым его действием является передача своего серверного интерфейса специальной программе, называемой binder’ом. Этот процесс, известный как процесс регистрации сервера, включает передачу сервером своего имени, номера версии, уникального идентификатора и описателя местонахождения сервера. Описатель системно независим и может представлять собой IP, Ethernet, X.500 или еще какой-либо адрес. Кроме того, он может содержать и другую информацию, например, относящуюся к аутентификации.

    Когда клиент вызывает одну из удаленных процедур первый раз, например, read, клиентский стаб видит, что он еще не подсоединен к серверу, и посылает сообщение binder-программе с просьбой об импорте интерфейса нужной версии нужного сервера. Если такой сервер существует, то binder передает описатель и уникальный идентификатор клиентскому стабу.

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

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

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

    Семантика RPC в случае отказов

    В идеале RPC должен функционировать правильно и в случае отказов. Рассмотрим следующие классы отказов:

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

    Потерян запрос от клиента к серверу. Самое простое решение — через определенное время повторить запрос.

    Потеряно ответное сообщение от сервера клиенту. Этот вариант сложнее предыдущего, так как некоторые процедуры не являются идемпотентными. Идемпотентной называется процедура, запрос на выполнение которой можно повторить несколько раз, и результат при этом не изменится. Примером такой процедуры может служить чтение файла. Но вот процедура снятия некоторой суммы с банковского счета не является идемпотентной, и в случае потери ответа повторный запрос может существенно изменить состояние счета клиента. Одним из возможных решений является приведение всех процедур к идемпотентному виду. Однако на практике это не всегда удается, поэтому может быть использован другой метод — последовательная нумерация всех запросов клиентским ядром. Ядро сервера запоминает номер самого последнего запроса от каждого из клиентов, и при получении каждого запроса выполняет анализ — является ли этот запрос первичным или повторным.

    Сервер потерпел аварию после получения запроса. Здесь также важно свойство идемпотентности, но к сожалению не может быть применен подход с нумерацией запросов. В данном случае имеет значение, когда произошел отказ — до или после выполнения операции. Но клиентское ядро не может распознать эти ситуации, для него известно только то, что время ответа истекло. Существует три подхода к этой проблеме:

    Ждать до тех пор, пока сервер не перезагрузится и пытаться выполнить операцию снова. Этот подход гарантирует, что RPC был выполнен до конца по крайней мере один раз, а возможно и более.

    Сразу сообщить приложению об ошибке. Этот подход гарантирует, что RPC был выполнен не более одного раза.

    Третий подход не гарантирует ничего. Когда сервер отказывает, клиенту не оказывается никакой поддержки. RPC может быть или не выполнен вообще, или выполнен много раз. Во всяком случае этот способ очень легко реализовать.

    Ни один из этих подходов не является очень привлекательным. А идеальный вариант, который бы гарантировал ровно одно выполнение RPC, в общем случае не может быть реализован по принципиальным соображениям. Пусть, например, удаленной операцией является печать некоторого текста, которая включает загрузку буфера принтера и установку одного бита в некотором управляющем регистре принтера, в результате которой принтер стартует. Авария сервера может произойти как за микросекунду до, так и за микросекунду после установки управляющего бита. Момент сбоя целиком определяет процедуру восстановления, но клиент о моменте сбоя узнать не может. Короче говоря, возможность аварии сервера радикально меняет природу RPC и ясно отражает разницу между централизованной и распределенной системой. В первом случае крах сервера ведет к краху клиента, и восстановление невозможно. Во втором случае действия по восстановлению системы выполнить и возможно, и необходимо.

    Клиент потерпел аварию после отсылки запроса. В этом случае выполняются вычисления результатов, которых никто не ожидает. Такие вычисления называют «сиротами». Наличие сирот может вызвать различные проблемы: непроизводительные затраты процессорного времени, блокирование ресурсов, подмена ответа на текущий запрос ответом на запрос, который был выдан клиентской машиной еще до перезапуска системы.

    Как поступать с сиротами? Рассмотрим 4 возможных решения.

    Уничтожение. До того, как клиентский стаб посылает RPC-сообщение, он делает отметку в журнале, оповещая о том, что он будет сейчас делать. Журнал хранится на диске или в другой памяти, устойчивой к сбоям. После аварии система перезагружается, журнал анализируется и сироты ликвидируются. К недостаткам такого подхода относятся, во-первых, повышенные затраты, связанные с записью о каждом RPC на диск, а, во-вторых, возможная неэффективность из-за появления сирот второго поколения, порожденных RPC-вызовами, выданными сиротами первого поколения.

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

    Мягкое перевоплощение аналогично предыдущему случаю, за исключением того, что отыскиваются и уничтожаются не все удаленные вычисления, а только вычисления перезагружающегося клиента.

    Истечение срока. Каждому запросу отводится стандартный отрезок времени Т, в течение которого он должен быть выполнен. Если запрос не выполняется за отведенное время, то выделяется дополнительный квант. Хотя это и требует дополнительной работы, но если после аварии клиента сервер ждет в течение интервала Т до перезагрузки клиента, то все сироты обязательно уничтожаются.

    На практике ни один из этих подходов не желателен, более того, уничтожение сирот может усугубить ситуацию. Например, пусть сирота заблокировал один или более файлов базы данных. Если сирота будет вдруг уничтожен, то эти блокировки останутся, кроме того уничтоженные сироты могут остаться стоять в различных системных очередях, в будущем они могут вызвать выполнение новых процессов и т.п.

    XML-RPC: вызов процедур посредством XML

    RPC расшифровывается как Remote Procedure Call — удаленный вызов процедур с помощью XML. Как же работает XML-RPC и каковы его отличия от стандарта SOAP?

    На сцене — XML-RPC

    RPC — удаленный вызов процедур с помощью XML. Сама методика удаленного вызова процедуры известна давно и используется в таких технологиях, как DCOM, SOAP, CORBA. RPC предназначен для построения распределенных клиент-серверных приложений. Это дает возможность строить приложения, которые работают в гетерогенных сетях, например на компьютерах различных систем, производить удаленную обработку данных и управление удаленными приложениями.

    Приведем сильно упрощенный пример. Приложение, выполняя обработку некоторых данных на локальной машине, обращается к некоторой процедуре. Если ее реализация присутствует в программе, то процедура (функция) принимает параметры, выполняет действие и возвращает некоторые данные. Если это удаленный вызов, мы должны знать, где будет исполняться наша процедура. Запрос на выполнение процедуры вместе с параметрами записывается в виде XML-документа и посредством HTTP передается по сети на другой компьютер, где из XML-документа извлекается имя процедуры, параметры и прочая нужная информация. После завершения работы процедуры формируется ответ (например, возвращаемые данные) — и он передается компьютеру, пославшему запрос. Заметим, что для прикладной программы все действия совершенно прозрачны.

    По этому принципу функционируют все системы, и различия в реализации и процедуре обмена не оказывают существенного влияния на его суть.

    Хорошо, предположим, у нас есть возможность удаленно вызывать процедуры и функции — чего же нам еще? А вот чего. Формат обмена данными при классической модели RPC (DCOM, CORBA) остается бинарным — а значит, работать с ним сложнее, он не слишком подходит, если надо организовать работу распределенной системы, где между отдельными участками сети стоят firewall/прокси-серверы. Технология DCOM, например, реализована для Windows-систем, CORBA функционирует на разных платформах, но наиболее полноценна ее реализация на J2EE. Значит, всегда найдется (и действительно находится) такая конфигурация сети/платформ, чтобы для реализации распределенной системы в ней ни одна технология не подходила. Так что же делать?

    Задавшись этим вопросом, компания UserLand Software Inc. создала технологию XML-RPC. Основным транспортом в ней является протокол HTTP; формат данных — XML. Это снимает ограничения, налагаемые как на конфигурацию сети, так и на маршрут следования пакетов,- вызовы XML-RPC представляют собой простой тип данных text/xml и свободно проходят сквозь шлюзы везде, где допускается ретрансляция http-трафика.

    У новой технологии есть и другие преимущества. Применение XML для описания данных позволило упростить программные средства создания распределенных приложений, снизились требования к клиенту и серверу. Например, теперь есть возможность связать веб-планшет с сервером на работе и с домашним компьютером. Программы разбора (парсинга) XML сейчас существуют практически для всех операционных систем и на всех языках программирования — следовательно, препятствий для внедрения технологии вроде бы нет.

    Что же это такое?

    Рассмотрение XML-RPC проведем на упрощенном тестовом примере. Для снижения затрат мы разворачиваем систему, где на один компьютер (сервер) ставится мощное ПО для перевода, проверка синтаксиса и грамматики, а все клиенты обращаются к нему посредством XML-RPC. (Конечно, этот пример выдуман, чтобы легче было познакомить читателя с технологией — но, господа программисты, кто мешает реально сделать такую систему?)

    Сообщение XML-RPC передается методом POST-протокола HTTP. Сообщения бывают трех типов: запрос, ответ и сообщение об ошибке.

    XML-RPC запрос

    Описание

  • Предупреждение!
    POST /RPC2 HTTP/1.0 User-Agent: MyAPP-Word/5.1.2 (WinNT) Host: server.localnet.com Content-Type: text/xml Content-length: 172 CheckWord

    Сначала идет стандартный заголовок http-запроса. MIME-тип данных должен быть text/xml, длина также обязательно должна присутствовать и иметь корректное значение, равное длине передаваемого сообщения.

    Стандартный заголовок любого корректного XML-документа.

    Корневой узел. Не допускается вложенности тегов — значит, одним запросом мы можем вызвать только один метод.

    Тег указывает на объект и название метода, который вызывается. Можно указывать так, как принято в языках программирования вызывать свойства класса: имя метода — через точку после имени класса. Можно также передавать пути и имя программы. Мы вызываем метод CheckWord объекта OrfoCheck.

    задаются параметры, которые передаются в метод. Секция может содержать произвольное число подэлементов

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

    Все теги, согласно спецификации XML, должны иметь соответствующие закрывающие элементы — в XML-RPC нет одиночных тегов.

    Типы данных

    В протоколе XML-RPC предусмотрено семь простых типов данных и два сложных, для передачи параметров методу и возвращаемых значений. Эти типы отображают основные типы данных реальных языков программирования. Более сложные типы, такие, например, как объекты, нужно передавать в двоичном виде или заменять структурами.

    Целые числа — задаются тегом или и представляются 4-байтовыми целыми числами со знаком. Для задания отрицательных чисел ставится знак «-«, например 34, 344, -15.

    Логический тип данных представляется тегом и может иметь значения 0 (false) или 1 (true). Можно использовать как 1/0, так и символьные константы true/false.

    ASCII-строка — тип данных, принимаемый по умолчанию. Представляет собой просто строку символов, заключенную в теги . В качестве символов нельзя использовать служебные знаки » и представляют собой числа с плавающей точкой двойной точности. Как разделитель целой и дробной части используется знак «,». Пробелы недопустимы. Отрицательные числа задаются знаком «-» перед числом.

    Дата/время. Для передачи времени/даты служит тег . Пример времени — 19980717T14:08:55 (в спецификации написано, что сервер сам должен определять, как посылать время/дату. Использовать этот тип данных, пользоваться структурой или же просто передавать дату как строку не рекомендуется).

    Двоичные данные передаются в закодированном (base64) виде и описываются тегом .

    Структуры. Для передачи структурированных данных можно конструировать свои структуры. Структура определяется корневым элементом , который может содержать произвольное количество элементов , определяющих каждый член структуры. Член структуры описывается двумя тегами: первый, , описывает имя члена, второй, содержит значение члена (вместе с тегом, описывающим тип данных). Например, так описывается структура с двух строковых элементов:

    Что такое код xmlrpc_set_type

    xmlrpc_set_type — Sets xmlrpc type, base64 or datetime, for a PHP string value

    Description bool xmlrpc_set_type ( string value, string type)

    This function is EXPERIMENTAL . The behaviour of this function, the name of this function, and anything else documented about this function may change without notice in a future release of PHP. Use this function at your own risk.

    Warning

    This function is currently not documented; only the argument list is available.

    The problem is that PHP has a string type which is also used to hold binary data and dates. But XML-RPC defines three separate types for strings, binary data, and dates. How do you tell how you want strings encoded? That’s where this function comes in.

    Suppose the XML-RPC method «log.data» took a string, a date, and a binary object. To tell XML-RPC that the date (which is a PHP string) is a really a date and that the binary data (which is also a PHP string) is really binary data, try:

    $string = «My logging event.»;
    $date = «20030115T12:22:37»; // Must be this format
    $binary = fread($fp, 128);
    xmlrpc_set_type(&$date, «datetime»);
    xmlrpc_set_type(&$binary, «base64»);
    $xmlrpcReq = xmlrpc_encode_request(«log.data», array($string, $date, $binary));

    Note the reference passing in the calls to xmlrpc_set_type; that enables the function to change the values from strings into what xmlrpc_encode/_request expects (which are objects that include a bonus field that tells the desired XML-RPC type).

    xmlrpc_set_type

    Sets xmlrpc type, base64 or datetime, for a PHP string value

    Description

    Sets xmlrpc type, base64 or datetime, for a PHP string value.

    This function is EXPERIMENTAL. The behaviour of this function, its name, and surrounding documentation may change without notice in a future release of PHP. This function should be used at your own risk.

    Parameters

    Value to set the type

    ‘base64’ or ‘datetime’

    Return Values

    Returns TRUE on success or FALSE on failure. If successful, value is converted to an object.

    Examples

    Example #1 A xmlrpc_set_type example

    = date ( «Ymd\TH:i:s» , time ());
    xmlrpc_set_type ( $params , ‘datetime’ );
    echo xmlrpc_encode ( $params );

    The above example will output something similar to:

    Errors/Exceptions

    Issues E_WARNING with type unsupported by XMLRPC.

    Илон Маск рекомендует:  Как растянуть фон на всю ширину окна
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL
    Warning