URI é a tecnologia definitiva para identificação de qualquer coisa. É um conceito brilhantemente simples criado pelo gênio Tim Berners-Lee pra servir como um dos pilares da internet. Tá na internet, tem URI.
Opacidade
Esse post por exemplo está identificado pela seguinte URI:
http://alexandre.gaigalas.net/blog/2010/05/uris-opacidade-canonicalizacao-e-palavroes
Você como um ser humano cheio de sinapses doidas (dorgas, manolo) provavelmente associou o 2010 ao ano de publicação e o 05 ao mês. Dá pra ter uma idéia geral do assunto da página pelo restante, que é o que o WordPress gera usando o título do post. De qualquer forma a URL poderia ser essa aqui:
http://alexandre.gaigalas.net/blog/?p=97
Não dá pra extrair muita informação disso, exceto talvez pelo fato de ser meu post de número 97 no blog.
URIs tem um forte significado dentro de determinados contextos, como mostrei aí em cima, mas do ponto de vista da especificação todos esses dados não significam absolutamente nada além de uma identificação. É similar aos números de alguns documentos, placas de veículos e por aí vai: Seu propósito é identificar, a extração de conteúdo é uma mera conveniência e pode ser totalmente subjetivo.
Por exemplo, os grandes sites de notícias que permitem que você altere a URI sem alterar a porção dela que identifica a notícia:
URI original:http://g1.globo.com/Noticias/Tecnologia/0,,MUL1468723-6174,00-IPAD+VIRA+ISCA+PARA+CODIGOS+MALICIOSOS+EM+MECANISMOS+DE+BUSCA.html
URI alterada (mesma notícia): http://g1.globo.com/Noticias/Tecnologia/0,,MUL1468723-6174,00-IPAD+MANDA+BEIJO+PRA+CRAVINHOS.html
Da mesma forma que placas de carros que começam com “A” geralmente são do Paraná, mas talvez tenham sido trasnferidas pra outros estados e não reflitam mais esse estado.
Anatomia de uma URI
Uma URI pode ser dividida em partes:
http://www.google.com/search?q=gaigalas#resultStats
- http é o esquema
- www.google.com é o domínio
- /search é o caminho
- ?q=gaigalas é a query string
- #resultStats é o fragmento
Cada uma dessas partes representa um nível distinto de identificação:
O esquema define o protocolo pelo qual aquele recurso identificado trafegará. O mais comum é o http, mas você provavelmente deve ter visto o mailto para endereços de email e o file para arquivos.
O domínio é próprio de alguns esquemas, e no http ele indica o hostname no qual o servidor que processará o endereço encontra-se.
O caminho é a útlima parte genuinamente opaca da URL. Ele é uma identificação genérica dentro de um hostname.
A query string já é claramente uma parte não opaca, e representa uma determinada busca dentro de um recurso.
E o fragmento finalmente identifica algo dentro do documento disponibilizado pelo servidor.
Canonicalização (eu não sei realmente se essa palavra existe, que doido né?)
Canonicalizar uma URI é uma forma de reorganizar suas diversas partes utilizando um processo que não altera seu significado. Aí que vem a parte importante de saber qual porção da URI é opaca, qual porção não é e como podemos mexer nisso.
O hostname de uma URI é sempre não-sensível a capitalização. Tanto faz ser em letras maiúsculas ou minúsculas, portanto um dos primeiros passos pra canonicalizar a URI é passar o hostname todo pra letras minúsculas. Isso mesmo, hostnames miguxos perdem toda sua mágica, e para todos os efeitos os seguintes hostnames são idênticos:
- www.exemple.com
- WWW.EXAMPLE.COM
- wWw.ExAmPlE.cOm
Com o caminho, ou path, não podemos mexer na capitalização. Alguns servidores são sensíveis a essas alterações. Simplesmente não podemos mexer em nada dessa parte.
A query string possui um formato próprio, e embora não seja certo é geralmente seguro aplicar um processo não-padrão para canonicalizá-la. Em uma query string você pode ter um ou mais conjuntos de chave/valor, separados pelo caractere &.
O processo de canonicalização se dá por interpretar os conjuntos de chave/valor, ordenar as chaves naturalmente e re-formatá-las:
- ?foo=bar&bar=baz&q=alganet&fulano=ciclano
- foo=bar, bar=baz, q=alganet, fulano=ciclano
- bar=baz, foo=bar, fulano=ciclano, q=alganet
- ?bar=baz&foo=bar&fulano=ciclano&q=alganet
As query strings geralmente possuem parâmetros pelos quais um determinado recurso será buscado, a ordem na qual esses parâmetros é passada raramente influi na busca por esse recurso, portanto é quase sempre seguro afirmar que as duas URIs a seguir identificam o mesmo recurso:
- http://example.com/something?foo=bar&bar=baz&q=alganet&fulano=ciclano
- http://example.com/something?bar=baz&foo=bar&fulano=ciclano&q=alganet
O fragmento, de acordo com o protocolo HTTP, depende do contexto no qual ele se encontra para tornar-se relevante ou não. Servidores que processam requisições e respostas HTTP não devem considerá-lo, mas os clientes (navegadores, robôs de varredura e por aí vai) podem considerá-lo se necessário. Como instrumento de identificação ele carrega significado, e as duas URIs a seguir, embora teoricamente trafeguem exatamente o mesmo recurso, não são consideradas idênticas:
- http://example.org/thing
- http://example.org/thing#part
Resumindo:
- Passe o hostname e o esquema pra minúsculo
- Não mexa no caminho
- Ordene os parâmetros da query string
- Não mexa no fragmento, mas ignore sua presença somente se for uma aplicação server-side
Se muitas URIs podem ser diferentes e possuir o mesmo significado, faz sentido armazená-las e processá-las todas de maneira idêntica, é esse o propósito de canonicalizá-las.