Werkzeug์ Flask๋ฅผ ์ฌ์ฉํ์ฌ REST API๋ฅผ ๊ตฌ์ถํ๊ณ ์์ต๋๋ค. ์ด ๋งฅ๋ฝ์์ ์ฐ๋ฆฌ๋ ํํ ์ฌ๋์๋ฅผ ์ถ๊ฐํ๋ ์๋ ๋์์ ์ํ์ง ์์ต๋๋ค. ์ด๋ GET์ ๋ค๋ฅธ ์์ฒญ ๊ฐ์ ๋น๋์นญ์ผ๋ก ์ด์ด์ง๋ฉฐ ์ฌ๊ธฐ์์๋ ์๊ฒฉํ๊ฒ ํ์ฉ๋ฉ๋๋ค.
ํ์ฌ ์ด๋ฅผ ์ํํ๊ธฐ ์ํด ๋ด๋ถ์ ์ฐ๊ฒฐ๋๋ ์ฌ์ฉ์ ์ ์ ๊ท์น ํด๋์ค( Rule.match
๋ฐ RequestSlash
)๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
์ด๊ฒ์ 1์ฐจ ๊ตฌ์ฑ ์ต์
์ผ๋ก ์ถ๊ฐํ๋ ๊ฒ์ด ์๋ฏธ๊ฐ ์์ต๋๊น? URL ๋งต์์ append_slash
(๋์ผํ Django ์ต์
๊ณผ ๋ณํํ๊ธฐ ์ํด)์ ๊ฐ์ ๊ฒ?
app.url_map.strict_slashes = False
๋ ์ด๊ฒ์ ํผํ๊ธฐ ์ํด ํ์ํ ์ ๋ถ์
๋๋ค.
์ฌ๋์๊ฐ ์์ผ๋ฉด ์ค์ ๋ก ๊ฒฝ๋ก๊ฐ ์ผ์นํฉ๋๋ค. ๋๋ ๊ทธ๊ฒ์ 404๋ก ์ํ๋ค.
ํ์ฌ ๋์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
| ๊ท์น์ ์ฌ๋์๊ฐ ์์ต๋๋ค. | ๊ฒฝ๋ก์ ์ฌ๋์๊ฐ ์์ต๋๋ค | strict_slashes
| ๊ฒฐ๊ณผ |
|-|-|-|-|
| ์ | ์ | True
| (๊ฒฝ๊ธฐ) |
| ์ | ์ | False
| (๊ฒฝ๊ธฐ) |
| ์ | ์ | True
| 404 |
| ์ | ์ | False
| 404 |
| ์ | ์ | True
| 301 |
| ์ | ์ | False
| (๊ฒฝ๊ธฐ) |
| ์ | ์ | True
| (๊ฒฝ๊ธฐ) |
| ์ | ์ | False
| (๊ฒฝ๊ธฐ) |
๊ท์น์ ํํ ์ฌ๋์๊ฐ ์์ง๋ง ๊ฒฝ๋ก์๋ ์๋ ๊ฒฝ์ฐ 404๋ฅผ ์ํฉ๋๋ค. ์ง๊ธ์ ๋ค์์ ํตํด ์ด ์์ ์ ์ํํ๊ณ ์์ต๋๋ค.
class StrictRule(Rule):
def match(self, path, method=None):
try:
result = super(StrictRule, self).match(path, method)
except RequestSlash:
return None
return result
ํ์ง๋ง ๋ด๋ถ์ ์์ ๋์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ฌ์ฉ์ ์ง์ ๊ท์น์ ์ฌ์ฉํ๋ ๊ฒ์ด Flask์์ ์ด๋ฅผ ์ํํ๋ ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ์
๋๋ค. ์ฐ๋ฆฌ๋ ๋ด๋ถ์ ์ผ๋ก ๋ชจ๋ ์ฌ๋์ ์ํ ๊ท์น์ ๋ง๋ค๋ ค๊ณ ํ์ง ์๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ํ์ค์ผ๋ก ์ ๊ณต๋๋ ๊ฒ ์ด์์ ๊ท์น์ ์ํ๋ฉด ์ด๋ฅผ ์ง์ ํด์ผ ํฉ๋๋ค. Flash์ ๊ฒฝ์ฐ url_rule_class
๋ฅผ ์ ํด๋์ค๋ก ์ค์ ํฉ๋๋ค. ์์ธํ ๋ด์ฉ์ Flask ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์. http://flask.pocoo.org/docs/1.0/api/?highlight=rule#flask.Flask.url_rule_class
@englander
https://github.com/pallets/werkzeug/issues/1246#issuecomment -362099342์ ๋ฐ๋ฅด๋ฉด ์ฌ๊ธฐ์ ๋ฌธ์ ๋ ์ฌ์ฉ์ ์ง์ ๊ท์น ๊ตฌํ์ ์์ต๋๋ค. RequestSlash
๋ https://github.com/pallets/werkzeug/blob/a220671d66755a94630a212378754bb432811158/src/werkzeug/routing.py#L259 -L260์ ๋ฐ๋ผ ๋ด๋ถ ์์ธ๋ก ๋ช
์์ ์ผ๋ก ํ์๋์ด ์์ด ์ด๋ฅผ ์ฒ๋ฆฌํ๊ธฐ๊ฐ ๋งค์ฐ ์ด๋ ต์ต๋๋ค. ์ฌ์ฉ์ ์ฝ๋.
๊ทธ๋ฆฌ๊ณ ๊ธฐ๋ณธ ๊ท์น์ด ๊ฐ๋ฅํ ๋ชจ๋ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ง์ํด์๋ ์ ๋๋ค๋ ๋ฐ์๋ ํ์คํ ๋์ํ์ง๋ง ํํ ์ฌ๋์๊ฐ ์๋ ๊ฒฝ์ฐ ์ผ์นํ์ง ์๋ ๊ฒ์ ๋งค์ฐ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก์
๋๋ค. ์ ํ ๊ธฐ์ ์ ๊ฒฝ์ฐ ์ด ํจํด์ APPEND_SLASH
: https://docs.djangoproject.com/en/dev/ref/settings/#append -slash๋ฅผ ํตํด Django ๊ตฌ์ฑ์์ ๋ช
์์ ์ผ๋ก ๋
ธ์ถ๋๋ ๋ช ์ ๋๋ ํจํด ์ค ํ๋์
๋๋ค.
์ด ๊ฒฝ์ฐ "๋ด๋ถ"๋ "๋ด๋ถ ์ ์ฉ"์ด ์๋๋ผ "๋ด๋ถ์ ์ผ๋ก ์ฒ๋ฆฌ๋จ"์ ์๋ฏธํฉ๋๋ค. ๋ณด์ฌ์ฃผ์ ์ฝ๋๋ ์ฌ์ฉํด๋ ๊ด์ฐฎ์ต๋๋ค.
@davidism ์ค๋ช ๊ฐ์ฌํฉ๋๋ค. ๊ทธ๋ผ ์ด๋๋ก ์งํํ๊ฒ ์ต๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
app.url_map.strict_slashes = False
๋ ์ด๊ฒ์ ํผํ๊ธฐ ์ํด ํ์ํ ์ ๋ถ์ ๋๋ค.