Estamos usando Werkzeug e Flask para construir uma API REST. Nesse contexto, não queremos o comportamento automático de adicionar barras finais, pois isso leva a assimetrias entre GETs e outras solicitações, e é aceitável ser estrito aqui.
Atualmente, precisamos usar uma classe de regra personalizada que se conecta aos internos ( Rule.match
e RequestSlash
) para fazer isso.
Faria sentido adicionar isso como uma opção de configuração de primeira ordem? Algo como append_slash
(para comparar a opção Django equivalente) em mapas de URL?
app.url_map.strict_slashes = False
é tudo que você precisa para evitar isso.
Isso realmente faz com que a rota corresponda quando a barra estiver faltando. Eu quero que seja 404.
O comportamento atual é:
| Regra tem barra final | O caminho tem uma barra final | strict_slashes
| Resultado |
| - | - | - | - |
| N | N | True
| (partida) |
| N | N | False
| (partida) |
| N | Y | True
| 404
| N | Y | False
| 404
| Y | N | True
| 301
| Y | N | False
| (partida) |
| Y | Y | True
| (partida) |
| Y | Y | False
| (partida) |
Eu quero um 404 quando a regra tem uma barra final, mas o caminho não. No momento, estou fazendo isso por meio de:
class StrictRule(Rule):
def match(self, path, method=None):
try:
result = super(StrictRule, self).match(path, method)
except RequestSlash:
return None
return result
Mas eu prefiro não chegar em partes internas.
Usar a regra personalizada seria a maneira correta de fazer isso no Flask. Decidimos internamente não tentar criar tudo para todos nas regras. Se quiser uma regra além do que é oferecido como padrão, você precisará especificá-la. Para Flash, você definiria url_rule_class
para a nova classe. Veja a documentação do Flask para mais informações. http://flask.pocoo.org/docs/1.0/api/?highlight=rule#flask.Flask.url_rule_class
@aenglander
De acordo com https://github.com/pallets/werkzeug/issues/1246#issuecomment -362099342, o problema aqui é com a implementação da regra personalizada. RequestSlash
é explicitamente marcado como uma exceção interna por https://github.com/pallets/werkzeug/blob/a220671d66755a94630a212378754bb432811158/src/werkzeug/routing.py#L259 -L260, então é muito estranho lidar com isso Código de usuário.
E embora eu certamente concorde que as regras básicas não devem oferecer suporte a todos os casos de uso possíveis, não corresponder a uma barra final ausente é um caso de uso muito comum. Para a arte anterior, este padrão é um dos poucos que são explicitamente expostos na configuração do Django via APPEND_SLASH
: https://docs.djangoproject.com/en/dev/ref/settings/#append -slash.
"Interno", neste caso, significa "manipulado internamente", não "apenas para" uso interno ". O código que você mostrou pode ser usado.
@davidism Obrigado pelo esclarecimento. Eu vou em frente e vou com isso, então.
Comentários muito úteis
app.url_map.strict_slashes = False
é tudo que você precisa para evitar isso.