Question

Nous allons supposer que j'ai chaîne comme '= & /; # +%? Être une partie de mon URL, disons comme ceci:

example.com/servletPath/someOtherPath/myString/something.html?a=b&c=d#asdf

où myString est la chaîne ci-dessus. Je suis partie critique si codé URL ressemble

example.com/servletPath/someOtherPath/%3D%26%3F%2F%3B%23%2B%25/something.html?a=b&c=d#asdf

Jusqu'à présent, si bon.

Quand je suis dans le servlet et je lis tout de request.getRequestURI(), request.getRequestURL() ou request.getPathInfo(), la valeur retournée est déjà décodé, si je reçois strilng comme

someOtherPath/=&?/;#+%/something.html?a=b&c=d#asdf

et je ne peux pas la différence entre les vrais caractères spéciaux et ceux codés.

Je l'ai résolu de problème particulier en interdisant au-dessus de caractères au total, ce qui fonctionne dans cette situation, mais je me demande toujours est-il un moyen d'obtenir URL undecoded dans la classe de servlet.

ENCORE UN AUTRE EDIT: Quand je l'ai frappé ce problème hier soir j'étais trop fatigué pour remarquer ce qui se passe vraiment, qui est encore plus bizarre J'ai servlet cartographié, disons / servletPath / * après que je mets tout ce que je veux et obtenir mon servlet répondre en fonction du reste d'un chemin, sauf quand il est 2F% dans le chemin. Dans ce cas, demande frappe jamais le servlet , et je reçois 404! Si je mets « / » au lieu de% 2F il fonctionne correctement. Je suis en cours d'exécution Tomcat 6.0.14 Java 1.6.0-04 sur Linux.

Était-ce utile?

La solution

Il y a une différence fondamentale entre « % 2F » et « / », aussi bien pour le navigateur et le serveur.

La spécification HttpServletRequest dit (sans logique, AFAICT):

  • getContextPath: non décodé
  • getPathInfo: décodé
  • getPathTranslated: non décodé
  • getQueryString: non décodé
  • getRequestURI: non décodé
  • getServletPath: décodé

Le résultat de getPathInfo () devrait être décodé, mais le résultat de getRequestURI () ne doit pas décoder. Le cas échéant, votre conteneur de servlets viole la spécification (comme Wouter Coekaerts et François Gravel correctement souligné). Quelle version Tomcat utilisez-vous?

Pour rendre les choses encore plus confuses, les versions de Tomcat actuelles rejettent les chemins contenant encodages de certains caractères spéciaux, pour des raisons de sécurité .

Autres conseils

S'il y a un %2F dans le décodée url, cela signifie que le codé url contenu %252F.

Depuis %2F est / Pourquoi ne pas simplement diviser le "\/" et ne pas se soucier de l'encodage d'URL?

Selon le Javadoc, getRequestURI ne doivent pas décoder la chaîne. D'autre part, getServletPath renvoie une chaîne décodée. Je l'ai testé en utilisant cette jetée et il se comporte comme décrit dans le document localement.

Alors, il pourrait y avoir quelque chose d'autre en jeu dans votre situation puisque le comportement que vous décrivez ne correspond pas à la documentation du Soleil.

Il semble que vous essayez de faire quelque chose Resty (utilisez Jersey). Pouvez-vous est analysez juste à côté des parties avant et arrière de l'URL pour obtenir les données que vous cherchez?

url.substring (startLength, url.length - endLength);

Mise à jour: cette réponse a été à l'origine indiquant à tort que « / » et « % 2F » dans un chemin doit toujours être traité de la même. Ils sont en fait différents parce qu'un chemin est une liste de segments / -Séparé.

Vous ne devriez pas avoir à faire une différence entre un caractère codé et non codé la partie de chemin de l'URL. Il n'y a pas de caractère à l'intérieur du chemin qui peut avoir une signification particulière dans une URL. Par exemple. « % 2F » doit être interprété de la même que « / », et un navigateur qui accède à une telle URL est libre de remplacer l'un par l'autre comme il le juge opportun. Faire une différence entre eux enfreint la norme de la façon dont les URL sont codées.

Dans l'URL complète, vous devez faire une différence entre les échappées et les caractères non-échappement pour différentes raisons, notamment:

  • Pour voir où la partie de chemin se termine. Parce qu'un ? codé dans le chemin ne doit pas être considéré comme la fin.
  • Dans la chaîne de requête. Du fait partie de la valeur d'un paramètre peut contenir « et » ou « = », ...
  • A l'intérieur d'un trajet, un '/' sépare les deux segments, tandis que '% 2F' peut être contenu dans un segment

Java traite bien avec les deux premiers cas:

  • getPathInfo() qui retourne uniquement la partie du chemin, décodé
  • getParameter(String) aux parties d'accès de la partie de la requête

Il ne traite pas bien avec le troisième cas. Si vous voulez faire une différence entre « / » comme la séparation des deux segments de chemin, et l'intérieur d'un segment de chemin « / » (% 2F), vous ne pouvez pas représenter systématiquement le chemin comme une chaîne décodée. Vous pouvez représenter comme une chaîne codée (par exemple « foo / bar% 2Fbaz »), soit comme une liste de segments décodés (par exemple « toto », « bar / baz »). Mais parce que getPathInfo () API promet de faire cela (une chaîne décodé), il n'a pas d'autre choix que de traiter « / » et « % 2F » comme le même.

Pour les applications Web habituelles, cela est très bien. Si vous êtes dans les rares cas où vous avez vraiment besoin de faire la différence, vous pouvez faire votre propre analyse syntaxique de l'URL, obtenir la version brute avec getRequestURI(). Si que l'on donne l'URL décodée comme vous le prétendez, alors cela signifie qu'il ya un bogue dans l'implémentation de servlet que vous utilisez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top