<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Semyon&#039;s blog &#187; CMS</title>
	<atom:link href="http://uoziod.ru/tag/cms/feed/" rel="self" type="application/rss+xml" />
	<link>http://uoziod.ru</link>
	<description>May beauty be all around</description>
	<lastBuildDate>Tue, 08 Nov 2011 12:45:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Хостинг-Центр РБК и WordPress (depricated)</title>
		<link>http://uoziod.ru/2009/06/09/hc-ru-i-wordpress/</link>
		<comments>http://uoziod.ru/2009/06/09/hc-ru-i-wordpress/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 16:27:15 +0000</pubDate>
		<dc:creator>uoziod</dc:creator>
				<category><![CDATA[Веб]]></category>
		<category><![CDATA[.htaccess]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[хостинг]]></category>

		<guid isPermaLink="false">http://uoziod.ru/?p=21</guid>
		<description><![CDATA[Вот уже приблизительно два года я пользуюсь услугами хостинг-провайдера Хостинг-Центр РБК. В лист предоставляемых услуг входит возможность создания самостоятельных подсайтов внутри имеющегося домена, на которые накладываются странные ограничения. Те, кто пытался установить WordPress, TYPO3, Joomla и прочие гибко настраиваемые CMS наверняка знают о чём идёт речь. Проблема заключается в установленных ограничениях на оперативную память для [...]]]></description>
			<content:encoded><![CDATA[<p>Вот уже приблизительно два года я пользуюсь услугами хостинг-провайдера <em>Хостинг-Центр РБК</em>. В лист предоставляемых услуг входит возможность создания самостоятельных подсайтов внутри имеющегося домена, на которые накладываются странные ограничения. Те, кто пытался установить <strong>WordPress</strong>, <strong>TYPO3</strong>, <strong>Joomla</strong> и прочие гибко настраиваемые CMS наверняка знают о чём идёт речь.</p>
<p><span id="more-21"></span>Проблема заключается в установленных ограничениях на оперативную память для исполняемых скриптов. Поэтому при попытке запустить &laquo;громоздкий&raquo; скрипт сервер возвращает ошибку.</p>
<blockquote><p>Fatal error: Out of memory (allocated 9699328)</p></blockquote>
<p>Разговоры на эту тему с техподдержкой ХЦ <a title="Форум HostObzor" href="http://forum.hostobzor.ru/index.php?showtopic=11104" target="_blank">бесполезны</a>.</p>
<p>В данной статье речь пойдёт о простом (не идеальном) способе обхода описанной проблемы используя <em>.htaccess</em> и <em>php</em>.</p>
<p>Очевидно то, что для корректной установки и дальнейшей работы CMS необходимо будет запустить её на основном либо другом удалённом хостинге. Затем <em>.htaccess</em> на нашем подсайте будет отлавливать HTTP-запросы и отдавать их нашему <em>php-cкрипту</em>, который будет делать реальные запросы к удалённому сайту, забирать и изменять ссылки в содержимом, а затем его выводить.</p>
<p>Определимся с деталями. Положим что уже есть установленный и работающий <em>WordPress</em> на сайте <strong>http://www.site.ru/blog/</strong>. На основном хостинге создан подсайт <strong>blog.site.ru</strong>, где мы хотим видеть наш блог. В настройках веб-сервера нашего подсайта (в контрольной панели Хостинг-Центра РБК) выбрана версия PHP5. Версия движка <em>WordPress</em> &#8211; <strong>2.7.1</strong>.</p>
<h3>.htaccess</h3>
<p>Первым действием в публичной папке подсайта (&laquo;<em>~/www/htdocs/</em>&laquo;) создаём (либо изменяем содержимое уже имеющегося файла) &laquo;<em>.htaccess</em>&raquo; на следующие строки</p>
<pre>&lt;IfModule mod_rewrite.c&gt;
	RewriteEngine On
	RewriteBase /
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_FILENAME} !-d
	RewriteRule . /index.php [L]
&lt;/IfModule&gt;</pre>
<p>Это стандартный <em>.htaccess</em>-файл движка блогов WordPress, являющийся идеально подходящим как для нашего случая, так и для тех, когда на удалённом сайте установлена любая другая CMS. Данная конфигурация возвращает пользователю, запрашивающему адрес вида <strong>http://blog.site.ru/&lt;что угодно&gt;</strong> результат работы скрипта <em>index.php</em>. В самом <em>index.php</em> мы уже работаем с запрошенным URL.</p>
<blockquote><p>В PHP включена поддержка libcurl &#8212; библиотеки функций, написанной      Daniel Stenberg, которая позволяет взаимодействовать с различными     серверами по различным протоколам.</p></blockquote>
<p>Возможности этой библиотеки мы и будем в основном использовать в нашем скрипте.</p>
<p>Первый подводный камень &#8212; невозможность обработки нашим скриптом POST-запросов, а это значит что для наименьших &laquo;потерь&raquo; (да, они всё-таки предстоят в нашем случае) админкой <em>WordPress</em>&#8216;а придётся пользоваться по реальному адресу. Скорее всего проблема в том, что POST-запросы хранятся в заголовке документа, и при попытке внешнего скрипта (нашего <em>index.php</em>) для нашего реального сайта &laquo;подсунуть&raquo; ему переменные в POST-запросе останавливают выполнение нашего скрипта из соображений безопасности. Формы на сайте использующие метод GET (например тот же поиск) работать будут нормально.</p>
<h3>index.php</h3>
<p>Метод работы <strong>cURL</strong> в PHP делится на 2 части: случаи, когда мы работаем с заголовком запрашиваемого документа, и случаи, когда мы работаем с его телом. В нашем случае мы действуем сразу в обоих направлениях.</p>
<p>Итак, второе наше действие &#8212; создаём <em>index.php</em>.</p>
<p>Прежде всего определимся с переменными GET-форм. Передавать их в запросе следует используя специальный параметр сеанса <em>cURL</em> &#8212; <strong>CURLOPT_POSTFIELDS</strong>. Значение этого параметра &#8212; собственно сами данные POST-запроса известного вида &laquo;<em>?key=value&amp;key2=value2</em>&laquo;. Наш скрипт получает переменные эти в виде массива <strong>$_POST</strong>.</p>
<pre>foreach ($_POST as $key =&gt; $value) {
	$postapx .= "&amp;" . $key . '=' . $value;
}</pre>
<p>Этот фрагмент собирает все полученные скриптом переменные в строку (<strong>$postapx</strong>), которую мы будем присоединять к нашим запросам реальной страницы.</p>
<p>Как говорилось выше, работа <em>сURL</em> разделена на две части: <em>возврат заголовка</em> и <em>возврат содержимого</em> запрашиваемого документа. Прежде чем выводить содержимое, необходимо скопировать заголовок удалённой страницы.</p>
<pre>$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.site.ru/blog" . $_SERVER["REQUEST_URI"]);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
if ($postapx) {
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $postapx);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$resp = curl_exec($ch);
curl_close($ch);</pre>
<p>Инициализируем сеанс <em>cURL</em> и задаём ему параметры. <strong>CURLOPT_URL</strong> &#8212; указание запрашиваемой страницы. <strong>CURLOPT_HEADER</strong> &#8212; переключатель установленный в значение &laquo;включен&raquo; (по умолчанию &laquo;выключен&raquo;), отвечающий за возврат в результат заголовка. <strong>CURLOPT_NOBODY</strong> &#8212; переключатель, отключающий включение в результат запроса содержимого документа, потому как мы заняты пока исключительно заголовками. Затем мы проверяем наличие переменных GET-запроса нашему скрипту и при положительном результате включаем их в запрос удалённого документа.  Положительное значение переключателя <strong>CURL_RETURNTRANSFER</strong> запрещает прямой вывод результата запроса, вместо чего возвращает его в виде значения. Полезно, когда мы хотим записать его в переменную (<strong>$resp</strong>) для дальнейших операций над результатом. Все необходимые действия выполнены. Закрываем сеанс.</p>
<pre>$headLines = explode("\n", $resp);
$i = 0;
foreach ($headLines as &amp;$value) {
	$i++;
	if ($i &gt; 2) {
		$skip = false;
		if (
			strstr($value, "Connection: keep-alive") ||
			strstr($value, "Keep-Alive:") ||
			strstr($value, "Transfer-Encoding:")
		)
			$skip = true;
		if (!$skip)
			header($value);
	}
}</pre>
<p>Данные заголовка запрошенного документа сейчас хранятся в исходном виде &#8212; каждый новый параметр заголовка разделяется символом переноса строки <strong>\n</strong>. Существует необходимость работать с каждым параметром отдельно. Первая строка разбивает каждую новую строку принятой информации в отдельные элементы массива оператором <em>explode</em>. Далее наш скрипт перебирает каждый параметр на предмет необходимости включения его в наш документ.</p>
<blockquote><p>HTTP/1.1 200 OK<br />
Server: nginx/0.5.35</p></blockquote>
<p>Первые две строки наш скрипт вернёт и без их наследования, поэтому организованный перед циклом счётчик <strong>$i</strong> пропускает обработку первых двух строк результата. Есть ещё несколько параметров (<em>Connection</em>, <em>Keep-Alive</em> и <em>Transfer-Encoding</em>) которые мы не наследуем из-за неуместности их при работе со статичными веб-документами.</p>
<pre>$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.site.ru/blog" . $_SERVER["REQUEST_URI"] . $postapx);
if ($postapx) {
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $postapx);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$content = curl_exec($ch);
curl_close($ch);</pre>
<p>Снова инициализируем <em>cURL</em>-сессию, теперь уже для записи содержимого запрашиваемого документа в переменную <strong>$content</strong>.</p>
<pre>$content = str_replace('http://www.site.ru/blog', 'http://blog.site.ru', $content);
print $content;</pre>
<p>Затем производим в результате запроса замену всех присутствующих в нём ссылок на удалённые ресурсы и выводим его.</p>
<p>На этом этапе можно проверить работоспособность нашего скрипта. Но помните о рассказанных ранее проблемах с POST-запросами. Далее речь пойдёт лишь о частном случае с <em>WordPress</em>.</p>
<h3>А теперь о жертвах</h3>
<p>Сразу нужно упомянуть о том, что единственную <em>жертву</em> мы имеем лишь в случае, когда мы не используем других попыток создать POST-запрос нашему скрипту. В ином случае <em>жертвами</em> становятся все файлы, делающие эти попытки. Таким образом логично выключить из шаблона ссылки для входа и регистрации в административной зоне<em> WordPress</em> (вход и регистрация), т.к. всё-равно функционировать они не будут.</p>
<p>Как следствие: Вы публикуете новый материал и вообще пользуетесь админкой по реальному её адресу вида <strong>http://www.site.ru/blog/wp-login.php</strong>.</p>
<p>Публично POST-запрос в блоге также используется, когда пользователь пытается оставить комментарий к записи. Следовательно наша жертва &#8211; файл <strong>wp-comments-post.php</strong>. Он начинается со следующего блока:</p>
<pre>if ( 'POST' != $_SERVER['REQUEST_METHOD'] ) {
	header('Allow: POST');
	header('HTTP/1.1 405 Method Not Allowed');
	header('Content-Type: text/plain');
	exit;
}</pre>
<p>Он полностью комментируется. Затем методом поиска и замены ищем все фрагменты &laquo;<strong>$_POST</strong>&raquo; заменяя их на &laquo;<strong>$_GET</strong>&laquo;.</p>
<p>Нужно помнить об этих изменениях при обновлениях движка <em>WordPress</em> эти изменения аннулируются.</p>
<p>Последний этап &#8212; изменение метода формы обращённой к только что изменённому файлу. В случае с использованием стандартной темы <strong>Kubrick</strong> она находится в файле <strong>comments.php</strong> в каталоге темы.</p>
<p>В нём ищем:</p>
<pre>&lt;form action="&lt;?php echo get_option('siteurl'); ?&gt;/wp-comments-post.php" method="POST" id="commentform"&gt;</pre>
<p>&#8230; и заменяем <strong>method=&quot;POST&quot;</strong> на <strong>method=&quot;GET&quot;</strong>.</p>
<p>Вот и всё!</p>
<p><a href="http://uoziod.ru/wp-content/uploads/2009/06/hc-ru-wordpress.zip">Архив содержащий скрипт и изменённый wp-comment-post.php</a> (<em>2,459 b</em>)</p>
<p><strong>UPD от 15.07.2009:</strong><br />
Яндекс снял с индекса&#8230; Пожалуй есть причины переселить блог на другой хостинг.</p>
<p><small>© <a href="http://uoziod.ru">Semyon&#039;s blog</a>, 2009.<br />
<a href="http://uoziod.ru/2009/06/09/hc-ru-i-wordpress/">Прямая ссылка</a> |
<a href="http://uoziod.ru/2009/06/09/hc-ru-i-wordpress/#comments">комментариев: 10</a> |
добавить в
<a href="http://del.icio.us/post?url=http://uoziod.ru/2009/06/09/hc-ru-i-wordpress/&title=Хостинг-Центр РБК и WordPress (depricated)">del.icio.us</a>
<br/>
Теги: <a href="http://uoziod.ru/tag/htaccess/" rel="tag">.htaccess</a>, <a href="http://uoziod.ru/tag/cms/" rel="tag">CMS</a>, <a href="http://uoziod.ru/tag/hack/" rel="tag">hack</a>, <a href="http://uoziod.ru/tag/php/" rel="tag">php</a>, <a href="http://uoziod.ru/tag/wordpress/" rel="tag">WordPress</a>, <a href="http://uoziod.ru/tag/%d1%85%d0%be%d1%81%d1%82%d0%b8%d0%bd%d0%b3/" rel="tag">хостинг</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://uoziod.ru/2009/06/09/hc-ru-i-wordpress/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

