Loops de redirecionamento de produto
-
13-12-2019 - |
Pergunta
Temos um site Magento (1.6.2) em um servidor LEMP que está em execução há pouco mais de 2 anos.Recentemente fizemos algumas alterações;
- Mudou todo o site para HTTPS.
- Criou todas as novas categorias e se livrou das antigas, mas manteve os mesmos produtos
Criou redirecionamentos de servidor no formulário;
Localização/this/Old/Category {rewrite ^(this/Old/category)/? (.*) $ https://oursite.co.uk/new/category$2 permanentes;}
Isso funciona tanto para páginas de categoria quanto para quaisquer produtos dentro delas e achamos que estávamos todos bem!
No entanto, o Google WMT começou a mostrar muitos URLs que não foram seguidos, então investigamos e descobrimos que muitos produtos estão sendo redirecionados de forma estranha e resultando em loops de redirecionamento.
Na guia de rede do Chrome, posso ver que quando você acessa o URL antigo de determinados produtos, o redirecionamento do servidor entra em ação e você obtém a resposta adequada.No entanto, seguem-se redirecionamentos (aparentemente infinitos) que assumem o formato de;
aleatório / antigo / categoria / aleatório / antigo / categoria / aleatório / antigo / categoria / aleatório / antigo / categoria / aleatório / antigo / categoria / aleatório / antigo / categoria / aleatório / antigo / categoria / aleatório / antigo / categoria / aleatório / antigo/categoria/nome do produto
Basicamente, ele adiciona "aleatório/antigo/categoria" a cada solicitação, continuamente.Nossos hosts de servidor são inflexíveis: a) Magento (e, portanto, não é problema deles) eb) deve ter uma barra anterior.
Não consigo encontrar nenhuma configuração que possa causar isso.
- "usar redirecionamentos de servidor web" está definido como sim.
- Usei "grep" em um despejo de texto de nosso banco de dados para tentar encontrar qualquer ocorrência de um dos URLs afetados (sem alegria, e tenho certeza de que não seria o caso devido ao ponto 1).
- Também passei manualmente pela área administrativa com um pente fino e não consigo ver nenhuma causa possível.
Espero que esta seja informação suficiente.Alguém pode me dizer onde um redirecionamento pode estar acontecendo além do servidor?
ATUALIZAR:
Como Douglas apontou, parece que o novo URL também está sendo redirecionado, mas verifiquei o arquivo .conf do site (e outros) e não há nenhuma regra que possa causar isso.
ATUALIZAÇÃO2:
Tive um pequeno avanço.Parece que quando o Magento não consegue encontrar o produto na categoria para a qual foi redirecionado, ele vai dar voltas e mais voltas.Por que isso acontece em vez de apenas um 404 é um mistério para mim, então ajudar nisso também seria bom!
ATUALIZAÇÃO3:
3 anos, uma mudança de servidor, muita experiência e uma atualização para CE 1.9.3.8 mais tarde, acho que fiz um grande avanço!
Agora sei com certeza que este é um problema de roteamento do Magento, como ao adicionar um die();
linha em index.php o loop de redirecionamento não ocorre.
Adicionei este código de registro (que pode ser encontrado em vários lugares na internet) ao Mage_Core_Controller_Varien_Front aula:
Mage::log('----Matching routers------------------------------');
Mage::log('Total ' . count($this->_routers) . ': ' . implode(', ',
array_keys($this->_routers)));
while (!$request->isDispatched() && $i++<100) {
Mage::log('- Iteration ' . $i);
$requestData = array(
'path_info' => $request->getPathInfo(),
'module' => $request->getModuleName(),
'action' => $request->getActionName(),
'controller' => $request->getControllerName(),
'controller_module' => $request->getControllerModule(),
'route' => $request->getRouteName()
);
$st = '';
foreach ($requestData as $key => $val) {
$st .= "[{$key}={$val}]";
}
Mage::log('Request: ' . $st);
foreach ($this->_routers as $name => $router) {
if ($router->match($this->getRequest())) {
Mage::log('Matched by "' . $name . '" router, class ' .
get_class($router));
break;
}
}
}
Com um pouco de pesquisa e compreensão do código desta aula;Magento procura um roteador do sistema (seja núcleo ou módulos) para assumir a responsabilidade pelo $request
e assim que um corresponder, enviará um sinal de despacho.
Com o código de registro acima, obtive uma lista de roteadores, mas nenhuma informação no $requestData
matriz sugerindo que o roteador nunca foi despachado.
Em cada roteador listado eu fui para o Controlador/Roteador.php arquivo e encontrei o match(Zend_Controller_Request_Http $request)
método.Nas linhas anteriores a este método retornar verdadeiro (significando uma correspondência), adicionei uma linha de eco simples, EG:
echo "matched in the xxx module"; die();
Isso resultou em eu encontrar o roteador responsável e eu suspeito isso não está despachando a solicitação após a correspondência e, portanto, continua em loop.O módulo responsável é MageWorx_SeoSuite, suspeito que tenha sido modificado por terceiros no passado, pois não consigo encontrar referências a isso online.Mais investigações são necessárias, o que farei assim que puder.
Solução
Acontece que o match(Zend_Controller_Request_Http $request)
no roteador MageWorx_SeoSuite tinha uma instrução switch que resolveu CMS
, Rss
, Category
, Category_layer
e outras rotas.
O problema estava com o default
(ler:produtos) caso desta instrução switch.Foi uma situação única (o que explica porque afetou apenas alguns produtos).
Seria;
- Verifique se o final do URL (ou seja:o produto
urlKey
) teve uma reescrita e se não; - Verifique se a categoria de nível mais baixo do referido produto foi reescrita e se não;
- Carregue o produto por ID e busque o URL canônico do
MageWorx_SeoSuite
classe auxiliar; - Envie um redirecionamento para o URL canônico e atualize a resposta usando um código de resposta HTTP definido anteriormente, dependendo das definições de configuração.
exit();
Se qualquer uma das duas primeiras declarações condicionais fosse falso;o método seria return false;
(ou seja:roteador não corresponde).No entanto, se ambas as duas primeiras condicionais avaliadas como true
e algumas outras verificações foram aprovadas (o URL canônico não estava vazio etc.);a instrução enviaria o redirecionamento e então simplesmente exit();
.
Sou novo em toda a metodologia de roteamento, mas acredito que há algumas coisas erradas nisso;
- O método não retornou um booleano para todas as rotas das condicionais (por exemplo, se um produto e sua categoria imediata não tiveram reescrita).
- O método "combinaria", mas nunca foi
dispatch
'd. - Isso se baseia em meu conhecimento limitado (de graduação), mas:isso parece um design de software muito ruim.
Vale ressaltar neste momento, porque não quero descartar o MageWorx sem os fatos:Tenho certeza de que este código foi alterado nos últimos 5 anos (pelo qual várias empresas terceirizadas poderiam ter sido responsáveis).
Resumindo:eu comentei o default:
declaração case no switch para que o núcleo do Magento assuma a responsabilidade.Os URLs culpados agora vão para um 404
, no-route
page, o que é ideal, pois são todos caminhos antigos e inexistentes.Eu normalmente não alteraria o código do módulo dessa maneira aleatória, mas documentei isso bem e estamos em uma posição privilegiada porque a nova versão do nosso site está em desenvolvimento, portanto a "correção" é temporária.