...
 
Commits (155)
RewriteEngine On
RewriteBase /
#Uncommenbt to lock WP
#RewriteCond %{REQUEST_URI} ^(.*)?register.*$ [OR]
#RewriteCond %{REQUEST_URI} ^(.*)?wp-comment-post\.php(.*)$ [OR]
#RewriteCond %{REQUEST_URI} ^(.*)?wp-login\.php(.*)$ [OR]
#RewriteCond %{REQUEST_URI} ^(.*)?wp-post\.php(.*)$ [OR]
#RewriteCond %{REQUEST_URI} ^(.*)?wp-admin$
#RewriteRule ^(.*)$ http://cavallette.noblogs.org/2013/11/8487 [R,L]
RewriteRule ^index\.php$ - [L]
#### moved blogs.
RewriteCond %{HTTP_HOST} ^ventitre\.noblogs\.org [NC]
RewriteRule ^/?(.*) http://www.ventitre.org/$1 [L,R=301,NE]
####
#avoid inspection of queries log
RewriteRule ^/noblogs_queries.* /ancheno [L,R=404]
# uploaded files
RewriteRule ^files/(.+) wp-includes/ms-files.php?file=$1 [L]
RewriteCond %{HTTP_X_FORWARDED_PROTO} https [NC]
RewriteRule ^gallery/([0-9]+)/(previews|previews-med)/(.*)$ https://noblogs.org/oldgal/$1/$2/$3 [R=301,L]
RewriteRule ^gallery/([0-9]+)/(previews|previews-med)/(.*)$ http://noblogs.org/oldgal/$1/$2/$3 [R=301,L]
#RewriteRule ^gallery/([0-9]+)/(previews|previews-med)/(.*)$ oldgal/$1/$2/$3 [L]
RewriteRule ^gallery/[0-9]+/(.*)$ wp-includes/ms-files.php?file=2010/08/$1 [L]
RewriteRule ^resource/[^/]+/preview/(.*)$ wp-includes/ms-files.php?file=2010/08/$1 [L]
RewriteRule ^resource/[^/]+/download/(.*)$ wp-includes/ms-files.php?file=2010/08/$1 [L]
# BEGIN WPSuperCache
<IfModule mod_rewrite.c>
AddDefaultCharset UTF-8
# Commented in order to cache more
# RewriteCond %{REQUEST_URI} !^.*[^/]$
RewriteCond %{REQUEST_URI} !^.*//.*$
RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{QUERY_STRING} !.*=.*
RewriteCond %{HTTP:Cookie} !^.*(comment_author_|wordpress_logged_in|wp-postpass_).*$
RewriteCond %{HTTP:X-Wap-Profile} !^[a-z0-9\"]+ [NC]
RewriteCond %{HTTP:Profile} !^[a-z0-9\"]+ [NC]
RewriteCond %{HTTP_USER_AGENT} !^.*(2.0\ MMP|240x320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo\ Wii|Nitro|Nokia|Opera\ Mini|Palm|PlayStation\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows\ CE|WinWAP|YahooSeeker/M1A1-R2D2|iPhone|iPod|Android|BlackBerry9530|LG-TU915\ Obigo|LGE\ VX|webOS|Nokia5800).*
RewriteCond %{HTTP_user_agent} !^(w3c\ |w3c-|acs-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|eric|hipt|htc_|inno|ipaq|ipod|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|lg/u|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda\ |xda-).*
RewriteCond %{HTTP:Accept-Encoding} gzip
#RewriteCond %{HTTP:X-Forwarded-Proto} !^https$
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/%{HTTP:X-Forwarded-Proto}/$1/index.html.gz -f
RewriteRule ^(.*) "/wp-content/cache/supercache/%{HTTP_HOST}/%{HTTP:X-Forwarded-Proto}/$1/index.html.gz" [L]
#Commented in order to cache more
#RewriteCond %{REQUEST_URI} !^.*[^/]$
RewriteCond %{REQUEST_URI} !^.*//.*$
RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{QUERY_STRING} !.*=.*
RewriteCond %{HTTP:Cookie} !^.*(comment_author_|wordpress_logged_in|wp-postpass_).*$
RewriteCond %{HTTP:X-Wap-Profile} !^[a-z0-9\"]+ [NC]
RewriteCond %{HTTP:Profile} !^[a-z0-9\"]+ [NC]
RewriteCond %{HTTP_USER_AGENT} !^.*(2.0\ MMP|240x320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo\ Wii|Nitro|Nokia|Opera\ Mini|Palm|PlayStation\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows\ CE|WinWAP|YahooSeeker/M1A1-R2D2|iPhone|iPod|Android|BlackBerry9530|LG-TU915\ Obigo|LGE\ VX|webOS|Nokia5800).*
RewriteCond %{HTTP_user_agent} !^(w3c\ |w3c-|acs-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|eric|hipt|htc_|inno|ipaq|ipod|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|lg/u|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda\ |xda-).*
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/%{HTTP:X-Forwarded-Proto}/$1/index.html -f
#RewriteCond %{HTTP:X-Forwarded-Proto} !^https$
RewriteRule ^(.*) "/wp-content/cache/supercache/%{HTTP_HOST}/%{HTTP:X-Forwarded-Proto}/$1/index.html" [L]
</IfModule>
# END WPSuperCache
# BEGIN WordPress
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule . index.php [L]
# END WordPress
# BEGIN noblogs
# .git doesn't exist
RedirectMatch 404 /\\.git(/|$)
# allow gathering stats only from localhost
<Files apc_stats_r2mon.php>
Order Allow,Deny
Allow from 127.0.0.1
</Files>
# END noblogs
This diff is collapsed.
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*.noblogs.org" />
</cross-domain-policy>
<?php
// Common settings
$wpdb->persistent = true;
$wpdb->max_connections = 30;
/* Disable responsiveness check, is not needed in our configuration and is causing
connection errors for the wrong implementation */
$wpdb->check_tcp_responsiveness = false;
include_once('r2db/db-hash.php');
include_once('r2db/db-backends.php');
// Set up global dataset with master databases
noblogs_load_global_dataset(NOBLOGS_MASTER_CONFIG, NOBLOGS_HOST_FILE);
// Add all the sharded blog databases.
$wpdb_reverse_backend_map = noblogs_load_backends(NOBLOGS_BACKEND_CONFIG, $wpdb->hash_map);
favicon.ico

246 Bytes

Uso di HyperDB con il piano R di A/I
------------------------------------
I database di noblogs sono distribuiti su piu' di un backend, utilizzando
un sistema di consistent hashing che associa ogni blog_id ad un backend
specifico.
L'elenco dei backend e' specificato nel file /etc/noblogs/backends.
Lo schema e' molto semplice e si basa sull'ID pubblico di ciascun server
(es, latitanza:1, confino:3, etc). Ogni server ha un database 'noblogs_ID'
(in /opt/noblogs/mysql), cui puo' accedere l'utente 'noblogsdb'.
<?php
function noblogs_split_db($file) {
$db_url = trim(file_get_contents($file));
return parse_url($db_url);
}
function noblogs_load_backends($db_config_file, $hashptr) {
global $wpdb;
$backend_map = array();
$fp = @fopen($db_config_file, "r");
if (!$fp) {
die("Database backends not configured!");
}
while (($line = fgets($fp, 1024)) !== false) {
$wline = rtrim($line);
if ($wline == "" || $wline[0] == '#') {
continue;
}
$line_parts = explode(" ", $wline);
$server_id = $line_parts[0];
$dataset = "backend_" . $server_id;
$backend_url = $line_parts[2];
$backend_url_data = parse_url($backend_url);
$backend = array(
"host" => $backend_url_data["host"] . ":" . $backend_url_data["port"],
"user" => $backend_url_data["user"],
"password" => $backend_url_data["pass"],
"name" => substr($backend_url_data["path"], 1),
"dataset" => $dataset,
"read" => 1, "write" => 1, "timeout" => 10
);
$wpdb->add_database($backend);
$hashptr->addTarget($dataset);
$backend_map[$dataset] = $backend;
}
fclose($fp);
return $backend_map;
}
function noblogs_load_global_dataset($master_file, $ip_file) {
global $wpdb;
$mdata = noblogs_split_db($master_file);
$ldata = trim(file_get_contents($ip_file));
$globaldb = array(
"host" => $mdata["host"] . ":" . $mdata["port"],
"user" => $mdata["user"],
"password" => $mdata["pass"],
"name" => substr($mdata["path"], 1),
"dataset" => "global",
"read" => 1, "write" => 1, "timeout" => 2
);
if ($mdata['host'] == $ldata) {
$wpdb->add_database($globaldb);
} else {
$globaldb['read'] = 0;
$wpdb->add_database($globaldb);
$globaldb['host'] = $ldata . ":" . $mdata["port"];
$globaldb['read'] = 1;
$globaldb['write'] = 0;
$wpdb->add_database($globaldb);
}
}
<?php
require_once(dirname(__FILE__) . '/flexihash.php');
require_once( ABSPATH . 'wp-config.php' );
$wpdb->hash_map = new Flexihash(null, R2DB_FLEXIHASH_REPLICAS);
/* Hashing function to map blogs to databases.
*
* Implements a consistent hashing scheme using Flexihash.
*/
function noblogs_db_callback($query, $wpdb) {
$wpdb_hash = $wpdb->hash_map;
if (preg_match("/^{$wpdb->base_prefix}(\d+)_/", $wpdb->table, $matches)) {
$blog_id = $matches[1];
return $wpdb_hash->lookup($blog_id);
}
}
$wpdb->add_callback('noblogs_db_callback');
<?php
/**
* Flexihash - A simple consistent hashing implementation for PHP.
*
* The MIT License
*
* Copyright (c) 2008 Paul Annesley
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author Paul Annesley
* @link http://paul.annesley.cc/
* @copyright Paul Annesley, 2008
*/
/**
* A simple consistent hashing implementation with pluggable hash algorithms.
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
class Flexihash
{
/**
* The number of positions to hash each target to.
*
* @var int
*/
private $_replicas = 64;
/**
* The hash algorithm, encapsulated in a Flexihash_Hasher implementation.
* @var object Flexihash_Hasher
*/
private $_hasher;
/**
* Internal counter for current number of targets.
* @var int
*/
private $_targetCount = 0;
/**
* Internal map of positions (hash outputs) to targets
* @var array { position => target, ... }
*/
private $_positionToTarget = array();
/**
* Internal map of targets to lists of positions that target is hashed to.
* @var array { target => [ position, position, ... ], ... }
*/
private $_targetToPositions = array();
/**
* Whether the internal map of positions to targets is already sorted.
* @var boolean
*/
private $_positionToTargetSorted = false;
/**
* Constructor
* @param object $hasher Flexihash_Hasher
* @param int $replicas Amount of positions to hash each target to.
*/
public function __construct(Flexihash_Hasher $hasher = null, $replicas = null)
{
$this->_hasher = $hasher ? $hasher : new Flexihash_Crc32Hasher();
if (!empty($replicas)) $this->_replicas = $replicas;
}
/**
* Add a target.
* @param string $target
* @param float $weight
* @chainable
*/
public function addTarget($target, $weight=1)
{
if (isset($this->_targetToPositions[$target]))
{
throw new Flexihash_Exception("Target '$target' already exists.");
}
$this->_targetToPositions[$target] = array();
// hash the target into multiple positions
for ($i = 0; $i < round($this->_replicas*$weight); $i++)
{
$position = $this->_hasher->hash($target . $i);
$this->_positionToTarget[$position] = $target; // lookup
$this->_targetToPositions[$target] []= $position; // target removal
}
$this->_positionToTargetSorted = false;
$this->_targetCount++;
return $this;
}
/**
* Add a list of targets.
* @param array $targets
* @param float $weight
* @chainable
*/
public function addTargets($targets, $weight=1)
{
foreach ($targets as $target)
{
$this->addTarget($target,$weight);
}
return $this;
}
/**
* Remove a target.
* @param string $target
* @chainable
*/
public function removeTarget($target)
{
if (!isset($this->_targetToPositions[$target]))
{
throw new Flexihash_Exception("Target '$target' does not exist.");
}
foreach ($this->_targetToPositions[$target] as $position)
{
unset($this->_positionToTarget[$position]);
}
unset($this->_targetToPositions[$target]);
$this->_targetCount--;
return $this;
}
/**
* A list of all potential targets
* @return array
*/
public function getAllTargets()
{
return array_keys($this->_targetToPositions);
}
/**
* Looks up the target for the given resource.
* @param string $resource
* @return string
*/
public function lookup($resource)
{
$targets = $this->lookupList($resource, 1);
if (empty($targets)) throw new Flexihash_Exception('No targets exist');
return $targets[0];
}
/**
* Get a list of targets for the resource, in order of precedence.
* Up to $requestedCount targets are returned, less if there are fewer in total.
*
* @param string $resource
* @param int $requestedCount The length of the list to return
* @return array List of targets
*/
public function lookupList($resource, $requestedCount)
{
if (!$requestedCount)
throw new Flexihash_Exception('Invalid count requested');
// handle no targets
if (empty($this->_positionToTarget))
return array();
// optimize single target
if ($this->_targetCount == 1)
return array_unique(array_values($this->_positionToTarget));
// hash resource to a position
$resourcePosition = $this->_hasher->hash($resource);
$results = array();
$collect = false;
$this->_sortPositionTargets();
// search values above the resourcePosition
foreach ($this->_positionToTarget as $key => $value)
{
// start collecting targets after passing resource position
if (!$collect && $key > $resourcePosition)
{
$collect = true;
}
// only collect the first instance of any target
if ($collect && !in_array($value, $results))
{
$results []= $value;
}
// return when enough results, or list exhausted
if (count($results) == $requestedCount || count($results) == $this->_targetCount)
{
return $results;
}
}
// loop to start - search values below the resourcePosition
foreach ($this->_positionToTarget as $key => $value)
{
if (!in_array($value, $results))
{
$results []= $value;
}
// return when enough results, or list exhausted
if (count($results) == $requestedCount || count($results) == $this->_targetCount)
{
return $results;
}
}
// return results after iterating through both "parts"
return $results;
}
public function __toString()
{
return sprintf(
'%s{targets:[%s]}',
get_class($this),
implode(',', $this->getAllTargets())
);
}
// ----------------------------------------
// private methods
/**
* Sorts the internal mapping (positions to targets) by position
*/
private function _sortPositionTargets()
{
// sort by key (position) if not already
if (!$this->_positionToTargetSorted)
{
ksort($this->_positionToTarget, SORT_REGULAR);
$this->_positionToTargetSorted = true;
}
}
}
/**
* Hashes given values into a sortable fixed size address space.
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
interface Flexihash_Hasher
{
/**
* Hashes the given string into a 32bit address space.
*
* Note that the output may be more than 32bits of raw data, for example
* hexidecimal characters representing a 32bit value.
*
* The data must have 0xFFFFFFFF possible values, and be sortable by
* PHP sort functions using SORT_REGULAR.
*
* @param string
* @return mixed A sortable format with 0xFFFFFFFF possible values
*/
public function hash($string);
}
/**
* Uses CRC32 to hash a value into a signed 32bit int address space.
* Under 32bit PHP this (safely) overflows into negatives ints.
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
class Flexihash_Crc32Hasher
implements Flexihash_Hasher
{
/* (non-phpdoc)
* @see Flexihash_Hasher::hash()
*/
public function hash($string)
{
return crc32($string);
}
}
/**
* Uses CRC32 to hash a value into a 32bit binary string data address space.
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
class Flexihash_Md5Hasher
implements Flexihash_Hasher
{
/* (non-phpdoc)
* @see Flexihash_Hasher::hash()
*/
public function hash($string)
{
return substr(md5($string), 0, 8); // 8 hexits = 32bit
// 4 bytes of binary md5 data could also be used, but
// performance seems to be the same.
}
}
/**
* An exception thrown by Flexihash.
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
class Flexihash_Exception extends Exception
{
}
#!/opt/noblogs/cron/php-noblogs
<?php
// Load wordpress api.
define('WP_CACHE',false);
/** Setup WordPress environment */
require_once('wp-load.php');
require_once('db-config.php');
function old_hash($dbid) {
if (($dbid % 2) == 0) {
return array('host' => '172.16.1.3',
'port' => '3307',
'user' => 'noblogs',
'password' => 'n0bl0gst3st',
'db' => 'noblogs_2');
} else {
return array('host' => '172.16.1.8',
'port' => '3307',
'user' => 'noblogsusr',
'password' => 'n0bl0gsdb4xpw!',
'db' => 'noblogs');
}
}
function new_hash($dbid, $reversemap) {
global $wpdb;
$lookup = $wpdb->hash_map->lookup($dbid);
$backend = $reversemap[$lookup];
$result = array();
if (preg_match('/^(.*):([0-9]*)$/', $backend['host'], $matches)) {
$result['host'] = $matches[1];
$result['port'] = $matches[2];
}
$result['user'] = $backend['user'];
$result['password'] = $backend['password'];
$result['db'] = $backend['name'];
return $result;
}
function mysqlopts(&$attrs) {
return ("-h" . $attrs['host'] . " -P" . $attrs['port'] . " -u" . $attrs['user']
. " '-p" . $attrs['password'] . "'");
}
function mysqlurl(&$attrs) {
return ("mysql://" . $attrs['user'] . "@" . $attrs['host']
. ":" . $attrs['port'] . "/" . $attrs['db']);
}
function get_all_blogs()
{
global $wpdb;
// $sql = "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE public = 1 AND deleted = 0 AND archived = '0' ORDER BY domain, path";
$sql = "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE public = 0 ORDER BY domain, path";
$result = $wpdb->get_results($sql);
return ($result);
}
$hashmap = new Flexihash();
$reverse_backend_map = noblogs_load_backends(NOBLOGS_BACKEND_CONFIG, $hashmap);
$new_counts = array();
$moved_count = 0;
$blogs = get_all_blogs();
foreach ($blogs as $blog) {
$blog_id = $blog->blog_id;
$old_params = old_hash($blog_id);
$old_dburi = mysqlurl($old_params);
$new_params = new_hash($blog_id, $reverse_backend_map);
$new_dburi = mysqlurl($new_params);
if ($new_counts[$new_params['host']]) {
$new_counts[$new_params['host']] += 1;
} else {
$new_counts[$new_params['host']] = 1;
}
if ($old_dburi != $new_dburi) {
echo "echo moving blog $blog_id from " . $old_params['host'] . " to " . $new_params['host'] . "\n";
echo "tables=\$(mysql " . mysqlopts($old_params) . " " . $old_params['db'] . " -NBe \"show tables like 'wp\\_" . $blog_id . "\\_%'\")\n";
echo "mysqldump --opt " . mysqlopts($old_params) . " " . $old_params['db'] . " \${tables} \\\n";
echo " | mysql " . mysqlopts($new_params) . " " . $new_params['db'] . "\n";
$moved_count += 1;
} else {
echo "echo blog $blog_id stays on " . $old_params['host'] . "\n";
}
}
echo "\n\n\nBlog distribution:\n";
print_r($new_counts);
print "\n $moved_count blogs moved\n";
#!/opt/noblogs/cron/php-noblogs
<?php
if ($argv[1]) {
$blog_domain = $argv[1];
if (!preg_match('/\.noblogs\.org$/', $blog_domain)) {
$blog_domain = $blog_domain . '.noblogs.org';
}
} else {
die("Usage: get-backend <blog_name>\n");
}
// Load wordpress api.
define('WP_CACHE',false);
/** Setup WordPress environment */
require_once('wp-load.php');
require_once('db-config.php');
function new_hash($dbid, $reversemap) {
global $wpdb;
$lookup = $wpdb->hash_map->lookup($dbid);
$backend = $reversemap[$lookup];
$result = array();
if (preg_match('/^(.*):([0-9]*)$/', $backend['host'], $matches)) {
$result['host'] = $matches[1];
$result['port'] = $matches[2];
}
$result['user'] = $backend['user'];
$result['password'] = $backend['password'];
$result['db'] = $backend['name'];
return $result;
}
function get_blog($domain)
{
global $wpdb;
// $sql = "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE public = 1 AND deleted = 0 AND archived = '0' ORDER BY domain, path";
$sql = "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE domain = '" . $domain . "'";
$result = $wpdb->get_results($sql);
return ($result[0]);
}
$hashmap = new Flexihash();
$reverse_backend_map = noblogs_load_backends(NOBLOGS_BACKEND_CONFIG, $hashmap);
$blog = get_blog($blog_domain);
$backend = new_hash($blog->blog_id, $reverse_backend_map);
echo "\n" . $blog_domain . " (id " . $blog->blog_id . ")\n\n";
print_r($backend);
#!/opt/noblogs/cron/php-noblogs
<?php
/*
Parse command line options
*/
$opts = getopt('',array('no-database', 'calc-size', 'db-only'));
if (array_key_exists('calc-size', $opts)) {
$opts['no-database'] = true;
$g_added_size = array();
}
$new_topology = array_pop($argv);
$old_topology = array_pop($argv);
if (!($new_topology && $old_topology)) {
usage();
exit(-1);
}
// Get all blogs
define('WP_CACHE',false);
require_once('wp-load.php');
require_once('db-config.php');
$blogs = get_all_blogs();
$n_hashmap = new Flexihash();
$new_map = noblogs_load_backends($new_topology, $n_hashmap);
$o_hashmap = new Flexihash();
$old_map = noblogs_load_backends($old_topology, $o_hashmap);
foreach ($blogs as $blog) {
$blog_id = $blog->blog_id;
$old_params = fhash($blog_id, $old_map, $o_hashmap);
$old_dburi = mysqlurl($old_params);
$new_params = fhash($blog_id, $new_map, $n_hashmap);
$new_dburi = mysqlurl($new_params);
if ($new_counts[$new_params['host']]) {
$new_counts[$new_params['host']] += 1;
} else {
$new_counts[$new_params['host']] = 1;
}
if ($old_dburi != $new_dburi) {
echo "echo moving blog $blog_id from " . $old_params['host'] . " to " . $new_params['host'] . "\n";
if ( !array_key_exists('no-database', $opts) ) {
echo "tables=\$(mysql " . mysqlopts($old_params) . " " . $old_params['db'] . " -NBe \"show tables like 'wp\\_" . $blog_id . "\\_%'\")\n";
echo "mysqldump --opt " . mysqlopts($old_params) . " " . $old_params['db'] . " \${tables} \\\n";
echo " | mysql " . mysqlopts($new_params) . " " . $new_params['db'] . "\n";
}
if (!array_key_exists('db-only',$opts)) {
if (array_key_exists('calc-size', $opts)) {
# $cmd = sprintf("ssh root@%s du -sk /opt/noblogs/www/wp-content/blogs.dir/%d", $old_params['host'], $blog_id);
$cmd = sprintf("du -sk /opt/noblogs/www/wp-content/blogs.dir/%d", $blog_id);
list($size, $dummy) = explode("\t",exec($cmd, $ret));
$g_added_size[$new_params['host']] += $size;
} else {
printf("ssh root@%s rsync -avz --delete /opt/noblogs/www/wp-content/blogs.dir/%d root@%s:/opt/noblogs/www/wp-content/blogs.dir/\n", $old_params['host'], $blog_id, $new_params['host']);
}
}
$moved_count += 1;
} else {
echo "echo blog $blog_id stays on " . $old_params['host'] . "\n";
}
}
echo "\n\n\nBlog distribution:\n";
print_r($new_counts);
echo "\n $moved_count blogs moved\n";
if (array_key_exists('calc-size', $opts)) {
echo "Variations in disk space for hosts (kB):\n";
print_r($g_added_size);
}
function fhash($dbid, $reversemap, $hashptr) {
$lookup = $hashptr->lookup($dbid);
$backend = $reversemap[$lookup];
$result = array();
if (preg_match('/^(.*):([0-9]*)$/', $backend['host'], $matches)) {
$result['host'] = $matches[1];
$result['port'] = $matches[2];
}
$result['user'] = $backend['user'];
$result['password'] = $backend['password'];
$result['db'] = $backend['name'];
return $result;
}
function mysqlopts(&$attrs) {
return ("-h" . $attrs['host'] . " -P" . $attrs['port'] . " -u" . $attrs['user']
. " '-p" . $attrs['password'] . "'");
}
function mysqlurl(&$attrs) {
return ("mysql://" . $attrs['user'] . "@" . $attrs['host']
. ":" . $attrs['port'] . "/" . $attrs['db']);
}
function get_all_blogs()
{
global $wpdb;
$sql = "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE deleted = 0 AND archived = '0' ORDER BY domain, path";
$result = $wpdb->get_results($sql);
return ($result);
}
function usage() {
$str = <<<USAGE
noblogs-new-topology.php [--no-database|--calc-size] <OLD_MAP> <NEW_MAP>
USAGE;
echo $str;
}
......@@ -656,6 +656,7 @@ function upgrade_101() {
* @global wpdb $wpdb WordPress database abstraction object.
*/
function upgrade_110() {
return;
global $wpdb;
// Set user_nicename.
......
......@@ -189,7 +189,7 @@ if ( ! is_multisite() ) {
*/
function _add_themes_utility_last() {
// Must use API on the admin_menu hook, direct modification is only possible on/before the _admin_menu hook
add_submenu_page('themes.php', _x('Editor', 'theme editor'), _x('Editor', 'theme editor'), 'edit_themes', 'theme-editor.php');
add_submenu_page('themes.php', _x('Editor', 'theme editor'), _x('Editor', 'theme editor'), 'switch_themes', 'theme-editor.php');
}
$count = '';
......
<?php
# WP SUPER CACHE 0.8.9.1
function wpcache_broken_message() {
if ( false == strpos( $_SERVER[ 'REQUEST_URI' ], 'wp-admin' ) )
echo "<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->";
}
if ( !include_once( WP_CONTENT_DIR . '/plugins/wp-super-cache/wp-cache-phase1.php' ) ) {
if ( !@is_file( WP_CONTENT_DIR . '/plugins/wp-super-cache/wp-cache-phase1.php' ) )
register_shutdown_function( 'wpcache_broken_message' );
}
?>
<?php
// HyperDB
// This file should be installed at ABSPATH/wp-content/db.php
......@@ -33,13 +32,20 @@ if ( defined('DB_CONFIG_FILE') && file_exists( DB_CONFIG_FILE ) ) {
}
/**
* Common definitions
* Common definitions
*/
define( 'HYPERDB_LAG_OK', 1 );
define( 'HYPERDB_LAG_BEHIND', 2 );
define( 'HYPERDB_LAG_UNKNOWN', 3 );
class hyperdb extends wpdb {
/**
* A/I patch!
* store a FlexiHash() instance here.
*/
var $hash_map;
/**
* The last table that was queried
* @var string
......@@ -235,7 +241,7 @@ class hyperdb extends wpdb {
/**
* Add a callback to a group of callbacks.
* The default group is 'dataset', used to examine
* The default group is 'dataset', used to examine
* queries and determine dataset.
*/
function add_callback( $callback, $group = 'dataset' ) {
......@@ -274,6 +280,12 @@ class hyperdb extends wpdb {
. ')\W(\w+)\W/is', $q, $maybe) )
return $maybe[1];
// SHOW TABLES LIKE (used in some plugins)
if ( preg_match('/^\s*'
. 'SHOW\s+TABLES\s+LIKE\s+'
. '\W(\w+)\W/is', $q, $maybe) )
return $maybe[1];
// Big pattern for the rest of the table-related queries in MySQL 5.0
if ( preg_match('/^\s*(?:'
. '(?:EXPLAIN\s+(?:EXTENDED\s+)?)?SELECT.*?\s+FROM'
......@@ -391,6 +403,10 @@ class hyperdb extends wpdb {
else
$this->dataset = $dataset;
if (WP_DEBUG === true) {
$_ai_msg = sprintf("We choose dataset %s for query '%s'", $this->dataset, $query);
$this->print_error($_ai_msg);
}
// Determine whether the query must be sent to the master (a writable server)
if ( !empty( $use_master ) || $this->srtm === true || isset($this->srtm[$this->table]) ) {
$use_master = true;
......@@ -468,7 +484,7 @@ class hyperdb extends wpdb {
break;
}
if ( isset( $conn['queries'] ) )
if ( isset( $conn['queries'] ) )
++$conn['queries'];
else
$conn['queries'] = 1;
......@@ -492,13 +508,13 @@ class hyperdb extends wpdb {
foreach ( $this->hyper_servers[$dataset][$operation] as $group => $items ) {
$keys = array_keys($items);
shuffle($keys);
foreach ( $keys as $key )
foreach ( $keys as $key )
$servers[] = compact('group', 'key');
}
if ( !$tries_remaining = count( $servers ) )
if ( !$tries_remaining = count( $servers ) )
return $this->bail("No database servers were found to match the query. ($this->table, $dataset)");
if ( !isset( $unique_servers ) )
$unique_servers = $tries_remaining;
......@@ -510,8 +526,8 @@ class hyperdb extends wpdb {
$success = false;
foreach ( $servers as $group_key ) {
--$tries_remaining;
--$tries_remaining;
// If all servers are lagged, we need to start ignoring the lag and retry
if ( count( $unique_lagged_slaves ) == $unique_servers )
break;
......@@ -575,7 +591,7 @@ class hyperdb extends wpdb {
if ( $use_master || !$tries_remaining || !$this->check_tcp_responsiveness
|| true === $tcp = $this->check_tcp_responsiveness($host, $port, $timeout) )
{
$this->dbhs[$dbhname] = @ $connect_function( "$host:$port", $user, $password, true );
$this->dbhs[$dbhname] = @ $connect_function( "$host:$port", $user, $password, true );
} else {
$this->dbhs[$dbhname] = false;
}
......@@ -620,20 +636,23 @@ class hyperdb extends wpdb {
$success = false;
$this->last_connection = compact('dbhname', 'host', 'port', 'user', 'name', 'tcp', 'elapsed', 'success');
$this->db_connections[] = $this->last_connection;
$msg = date( "Y-m-d H:i:s" ) . " Can't select $dbhname - \n";
$msg .= "'referrer' => '{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}',\n";
$msg .= "'server' => {$server},\n";
$msg .= "'host' => {$host},\n";
$msg .= "'error' => " . mysql_error() . ",\n";
$msg .= "'errno' => " . mysql_errno() . ",\n";
$msg .= "'tcp_responsive' => " . ( $tcp === true ? 'true' : $tcp ) . ",\n";
$msg .= "'lagged_status' => " . ( isset( $lagged_status ) ? $lagged_status : HYPERDB_LAG_UNKNOWN );
$this->print_error( $msg );
/* Workaround to stop logging a/i */
if ( AI_LOG_HYPERDB == true ) {
$msg = date( "Y-m-d H:i:s" ) . " Can't select $dbhname - \n";
$msg .= "'referrer' => '{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}',\n";
$msg .= "'server' => {$server},\n";
$msg .= "'host' => {$host},\n";
$msg .= "'error' => " . mysql_error() . ",\n";
$msg .= "'errno' => " . mysql_errno() . ",\n";
$msg .= "'tcp_responsive' => " . ( $tcp === true ? 'true' : $tcp ) . ",\n";
$msg .= "'lagged_status' => " . ( isset( $lagged_status ) ? $lagged_status : HYPERDB_LAG_UNKNOWN );
$this->print_error( $msg );
}
}
if ( !$success || !isset($this->dbhs[$dbhname]) || !is_resource( $this->dbhs[$dbhname] ) ) {
if ( !isset( $ignore_slave_lag ) && count( $unique_lagged_slaves ) ) {
if ( !isset( $ignore_slave_lag ) && count( $unique_lagged_slaves ) ) {
// Lagged slaves were not used. Ignore the lag for this connection attempt and retry.
$ignore_slave_lag = true;
$tries_remaining = count( $servers );
......@@ -656,7 +675,7 @@ class hyperdb extends wpdb {
break;
} while ( true );
if ( !isset( $charset ) )
if ( !isset( $charset ) )
$charset = null;
if ( !isset( $collate ) )
......@@ -664,6 +683,15 @@ class hyperdb extends wpdb {
$this->set_charset($this->dbhs[$dbhname], $charset, $collate);
if ( !isset( $charset ) )
$charset = null;
if ( !isset( $collate ) )
$collate = null;
// AI workaround: set all queries to latin1
$this->set_charset($this->dbhs[$dbhname], 'latin1');
$this->dbh = $this->dbhs[$dbhname]; // needed by $wpdb->_real_escape()
$this->last_used_server = compact('host', 'user', 'name', 'read', 'write');
......@@ -755,6 +783,11 @@ class hyperdb extends wpdb {
if ( ! is_resource($this->dbh) )
return false;
// A/I: prevent mysql-proxy to cache the admin section
if (strpos($_SERVER['REQUEST_URI'], '/wp-admin/') !== false) {
$query .= ' /* NO CACHE */';
}
$this->timer_start();
$this->result = mysql_query($query, $this->dbh);
$elapsed = $this->timer_stop();
......@@ -984,11 +1017,28 @@ class hyperdb extends wpdb {
}
// Helper functions for configuration
} // class hyperdb
$wpdb = new hyperdb();
/**
* AI custom: Logs all queries for debugging purposes
*/
function ai_log_db_queries($query, $time, $backtrace=null, hyperdb $obj ) {
$fh = fopen( ABSPATH . '/profiling/noblogs_queries_'. date('Ymd') . '.log', 'a');
if (!$fh) {
return array($query, $time, $backtrace);
}
fwrite($fh, sprintf("##\n#Date: %s\n#Query time: %s\n%s\n", date('r'), $time, $query));
fclose($fh);
return array($query, $time, $backtrace);
}
$wpdb = new hyperdb();
if ( AI_DB_PROFILER === true ) {
$wpdb->save_queries = true;
$wpdb->save_query_callback = 'ai_log_db_queries';
}
require( DB_CONFIG_FILE );
?>
......@@ -480,8 +480,8 @@ add_action('login_head', array(&$ds_more_privacy_options, 'noindex'),1);
//no pings unless public either
add_filter('option_ping_sites', array(&$ds_more_privacy_options, 'privacy_ping_filter'),1);
//email SuperAdmin when privacy changes
add_action( 'update_blog_public', array(&$ds_more_privacy_options,'ds_mail_super_admin'));
//add_action( 'update_blog_public', array(&$ds_more_privacy_options,'ds_mail_super_admin'));
}
?>
\ No newline at end of file
?>
<?php
/*
Plugin Name: Noblogs Wp SSL
Plugin URI: https://git.autistici.org/ai/noblogs-wp-ssl
Description: Rewrite internal URLS to use HTTPS.
Version: 0.1
Author: Cloudflare, sand
License: GPLv2
*/
/*
Heavily copied from: https://wordpress.org/plugins/cloudflare/
*/
if ( !function_exists('add_action') ) {
echo "This is a Wordpress plugin and should not be called directly";
exit;
}
function rewrite_links($buffer) {
// replace href or src attributes within script, link, base, and img tags with just "//" for protocol
$re = "#(<(?:script|link|base|img|form|a)(?:[^>]*)(?:href|src|action)=[\"'])http://([^.]+\.noblogs\.org)#i";
$subst = "$1https://$2";
return preg_replace($re, $subst, $buffer);
}
// This is a filter function that act on the post $content
function noblogs_wp_ssl_content_filter($content) {
// skip rewrite if not on HTTPS
if (empty($_SERVER['HTTPS'])) {
return $content;
}
$return = rewrite_links($content);
if ($return) {
$content = $return;
}
return $content;
}
add_filter('the_content', 'noblogs_wp_ssl_content_filter');
<?php
if ( !function_exists( 'wp_password_change_notification' ) ) {
function wp_password_change_notification() {}
}
?>
<?php
//Utilizza gli avatar di buddypress se presenti
function nfm_bp_avtar_upload_path_correct($path){
if ( bp_core_is_multisite() ){
$path = ABSPATH . get_blog_option( BP_ROOT_BLOG, 'upload_path' );
}
return $path;
}
add_filter('bp_core_avatar_upload_path', 'nfm_bp_avtar_upload_path_correct', 1);
function nfm_bp_avatar_upload_url_correct($url){
if ( bp_core_is_multisite() ){
#$url = get_blog_option( BP_ROOT_BLOG, 'siteurl' ) . "/wp-content/uploads";
$url = site_url( 'wp-content/uploads' );
}
return $url;
}
add_filter('bp_core_avatar_url', 'nfm_bp_avatar_upload_url_correct', 1);
// fine