sexta-feira, 25 de abril de 2008

Compilando Mysql Proxy

Bom, necessitei usar o Mysql Proxy para fazer um Load Balance, e para variar um pouco não tinha o binário para instalar no RedHat 5 64 bits, aí começou a epopéia da compilação, diante da dificuldade resolvi coloborar com a comunidade e deixar um passo a passo da intalação, que segue :

Instalar as as dependências necessárias do sistema

yum install mysql-devel libevent-devel

Baixar a ultima versão do Mysql Proxy http://dev.mysql.com/downloads/mysql-proxy/
Baixar a ultima versão do Lua em http://www.lua.org/ftp/

Descompactar as versões em um diretório, farei isto em /usr/src

tar xzfv lua-5.1.3.tar.gz -C /usr/src
tar xzfv mysql-proxy-0.6.1.tar.gz -C /usr/src


Vamos primeiro compilar o Lua, como uso uma distribuição 64 bits e gosto que tudo estaja instalado conforme a distribuição, vou alterar alguma linhas do Makefile

cd /usr/src/lua-5.1.3
vi Makefile

INSTALL_TOP= /usr
INSTALL_LIB= $(INSTALL_TOP)/lib64
INSTALL_CMOD= $(INSTALL_TOP)/lib64/lua/$V


E compilar ...

make linux
make install


Bom agora vamos compilar o Mysql Proxy ...

cd /usr/src/mysql-proxy-0.6.1/

Aqui começa o pulo do gato, primeiramente as váriveis para compilar com o lua, a distribuição fala que necessita delas LUA_LIBS e LUA_CFLAGS, porém não fala de seu conteúdo, pois bem, depois de várias tentativas e algumas compilações na unha, acabei encontrando elas:

export LUA_LIBS="-L/usr/lib64/lua/5.1/ -llua -lm"
export LUA_CFLAGS=" "


Para aqueles que não alteraram o Makefile do Lua ...

export LUA_LIBS="-L/usr/local/lib/lua/5.1/ -llua -lm"
export LUA_CFLAGS=" "


Agora para gerar os Makefiles...

./configure LDFLAGS="-ldl"

Pronto, com estas parâmetros "ocultos" é só compilar e instalar...

make
make install


É só isto ... mas foram-se um bom tempo e muita dor de cabeça para chegar aqui ...

sexta-feira, 4 de abril de 2008

Reescrevendo URL a partir de parametros de outra URL

O processo consiste em reescrever a URL a partir do valor contido em uma variável de parâmetro da URL de origem
Exemplo:
de
http://localhost/template.aspx&palavra=ipod&acao=busca&menu=compareprecos&imageField.x=0&imageField.y=0

para
http://localhost/search?q=ipod&x=0&y=0

Onde :
localhost - é o servidor
/template.aspx - é a URL
&palavra=ipod&acao=busca&menu=compareprecos&imageField.x=0&imageField.y=0 - é parâmetro da URL
palavra=ipod - é a variável 'palavra' com seu valor 'ipod'
search - é a nova URL
?q=ipod&x=0&y=0 - é o novo parâmetro d URL contendo um valor de uma variável do parâmetro antigo

E o que desejamos é apenas este valor de uma unica variável o resto seria todo descartado, a principio o rewrite não faz isto, pois os mecanismos contido nele trata apenas do absoluto que é passado e não de seus parâmetros, apesar de conter uma variável que contem estes parâmetros (%{QUERY_STRING}), e isto é parte do que utilizaremos junto com um mecanismo que passa para um programa externo, o RewriteMap

- O parametro RewriteMap é utilizado da seguinte maneira:

RewriteMap MapName MapType:MapSource

Onde :
MapName é o nome do mapeamento em si
MapType é o tipo do mapeamento
MapSource é onde esta este mapeamento

Bom utilizarei como nome do mapeamento nome_mapeamento, e neste caso como terei que tratar todo o parâmetro, utilizarei um programa externo para isto, usarei o perl para isto e utilizarei como tipo de mapeamento o paremetro prg e logo a seguir o caminho completo de execução do programa, ficando assim

RewriteMap nome_mapeamento prg:/var/www/scripts/remapemento.pl

Observe que existirá o programa /var/www/scripts/remapemento.pl , logo abaixo descrevo ele.
E para chama-lo seria:

${ MapName : LookupKey }
${ MapName : LookupKey | DefaultValue }

Onde:
LookupKey é o parametro passado para o programa externo, normalmente alguma variavel do Rewrite
DefaultValue é um valor padrão caso não exista um ou valor na variavel passada

Assim ficamos com a seguinte regra no Rewrite :

RewriteEngine on
RewriteMap nome_mapeamento prg:/var/www/scripts/remapemento.pl
RewriteRule ^/(template.aspx)$ /${nome_mapeamento:$1\&%{QUERY_STRING}} [R]


Para exemplificar, o programa em perl verifica se existe as variaveis com seus valores ( acao=busca e menu=compareprecos ) coletando o valor contido na variavel palavra , havendo a condição descrita reescreva para que na nova URL contenha apenas o valor coletado :

Exemplo

Entrada : template.aspx&palavra=ipod&acao=busca&menu=compareprecos&imageField.x=0&imageField.y=0

Saida : search?q=ipod&x=0&y=0

Abaixo o programa :

#!/usr/bin/perl
$| = 1;
debug=0;
# Cria o loop que ficará aguardando o repasse do rewrite
while () {
    open (RET,">>/tmp/retorno.log") if ( $debug );;
    $str = $_;
    $busca = "";
    $acao = 0;
    $menu = 0;
    print RET "$str\n" if ( $debug );
    # Separa os parametros em variavel=valor
    @array = split(/&/,$str);
    for ( @array ) {
        # Separa a variavel de seu valor
        @parte = split (/\=/);
        # Verifica se o nome da variavel é palavra se for salva seu valor
        if ( @parte[0] eq "palavra" ) {
            $busca = @parte[1] ;
            print RET "\n---\nbusca=$busca\n---\n" if ( $debug );
        }
        # Verifica primeira condição para reescrever varivel acao com valor busca
        if ( $_ eq "acao=busca" ) {
            $acao = 1;
        }
        # Verifica segunda condição para reescrever varivel menu com valor compareprecos
        if ( $_ eq "menu=compareprecos" ) {
            $menu = 1;
        }
        print RET "$_\n" if ( $debug );
    }
    # Satisfazendo as condicoes reescreve a URL caso contrario devolve ela sem alteraçao
    if (( $acao == 1) && ( $menu == 1 )) {
        print RET "search?q=$busca&x=0&y=0\n" if ( $debug );
        print "search?q=$busca&x=0&y=0\n" ;
    } else {
        int RET $str if ( $debug );
        print $str;
    }
    close (RET);
}