티스토리 뷰
반응형
🚀 들어가며...
- 미들웨어를 공부하다가 장고에서 미들웨어는 request는 순서대로 들어오나 response는 역순으로 리턴되는 부분에서 왜 이렇게 설계를 했을까 하는 궁금증이 들어서 간단히 site-packages/django/core/handlers/base.py에 있는 소스를 분석해 보았습니다.
📑 내용
우선 저의 궁금증을 해결해줄 소스를 먼저 보여드리겠습니다.
def load_middleware(self):
"""
Populate middleware lists from settings.MIDDLEWARE_CLASSES.
Must be called after the environment is fixed (see __call__ in subclasses).
"""
self._view_middleware = []
self._template_response_middleware = []
self._response_middleware = []
self._exception_middleware = []
request_middleware = []
for middleware_path in settings.MIDDLEWARE_CLASSES:
mw_class = import_string(middleware_path)
try:
mw_instance = mw_class()
except MiddlewareNotUsed as exc:
if settings.DEBUG:
if six.text_type(exc):
logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc)
else:
logger.debug('MiddlewareNotUsed: %r', middleware_path)
continue
if hasattr(mw_instance, 'process_request'):
request_middleware.append(mw_instance.process_request)
if hasattr(mw_instance, 'process_view'):
self._view_middleware.append(mw_instance.process_view)
if hasattr(mw_instance, 'process_template_response'):
self._template_response_middleware.insert(0, mw_instance.process_template_response)
if hasattr(mw_instance, 'process_response'):
self._response_middleware.insert(0, mw_instance.process_response)
if hasattr(mw_instance, 'process_exception'):
self._exception_middleware.insert(0, mw_instance.process_exception)
# We only assign to this when initialization is complete as it is used
# as a flag for initialization being complete.
self._request_middleware = request_middleware
이 부분인데 여기서 settings.MIDDLEWARE_CLASSES에서 base.py에 미리 선언해둔 MIDDLEWARE_CLASSES에 미들웨어들을
가져와서 반복문을 돌며 템플릿용/리퀘스트용/리스폰스용을 정리하면서 response에 담습니다.
이 때, insert문을 이용하여 추가할 항목들을 리스트 0번째에 계속 밀어넣기 때문에 response에는 역순으로 담기는 것입니다. 그 다음은..
def get_response(self, request):
"Returns an HttpResponse object for the given HttpRequest"
# Setup default url resolver for this thread, this code is outside
# the try/except so we don't get a spurious "unbound local
# variable" exception in the event an exception is raised before
# resolver is set
(생략)
try:
response = None
# Apply request middleware
for middleware_method in self._request_middleware:
response = middleware_method(request)
if response:
break
if response is None:
if hasattr(request, 'urlconf'):
# Reset url resolver with a custom urlconf.
urlconf = request.urlconf
urlresolvers.set_urlconf(urlconf)
resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
resolver_match = resolver.resolve(request.path_info)
callback, callback_args, callback_kwargs = resolver_match
request.resolver_match = resolver_match
# Apply view middleware
for middleware_method in self._view_middleware:
response = middleware_method(request, callback, callback_args, callback_kwargs)
if response:
break
if response is None:
wrapped_callback = self.make_view_atomic(callback)
try:
response = wrapped_callback(request, *callback_args, **callback_kwargs)
이제 위 소스와 같이 바로 밑에서 함수를 실행하게 되는데, WSGI가 쓰레드를 돌다가 소켓에서 리퀘스트를 받으면
make_view_atomic 함수에서 미들웨어 함수를 일렬로 실행하게 됩니다. (단, 미들웨어를 종류별로 돌긴 합니다.)
def make_view_atomic(self, view):
non_atomic_requests = getattr(view, '_non_atomic_requests', set())
for db in connections.all():
if (db.settings_dict['ATOMIC_REQUESTS']
and db.alias not in non_atomic_requests):
view = transaction.atomic(using=db.alias)(view)
return view
위에 소스처럼 말이죠.
하지만.. 미들웨어를 response에 담을때 왜 0번째에 밀어넣는지에 대한 설계이유에 대해선 아무리 구글링과 공식문서를 찾아도 나오지가 않아서 궁금증이 해결되지는 않고 분석만 하다가 끝났습니다 ㅠㅠ
🙋🏻♂️ 후기
혹시나 저의 궁금증에 대해 조금이나마 정보를 가지고 계신 분들은 댓글로 공유 부탁드립니다!
그리고 위에 분석은 저의 생각을 토대로 분석하였기 때문에 잘못된 부분에 대한 피드백은 언제나 환영입니다! 감사합니다.
🔗 참고한 글
https://docs.djangoproject.com/ko/4.1/topics/http/middleware/
반응형
'Django' 카테고리의 다른 글
[Django] 서버 실행 과정 (0) | 2022.09.28 |
---|---|
[Django] 장고에서의 보안(XSS / CSRF protection) (0) | 2022.09.07 |
[Django] 파일 업로드 테스트 with Nginx, uWSGI (0) | 2022.07.25 |
[Django] static files (0) | 2022.07.21 |
[Django] 로그 남기기 - logging (0) | 2022.07.20 |
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- static files
- django ORM
- list
- Greedy Algorithm
- Default export
- ORM
- programmers
- Linux
- Named export
- PostgreSQL
- union-find
- SQL
- docker
- This
- uSWGI
- container
- JavaScript
- lv1
- db
- lv2
- django
- data formatting
- MVT
- Python
- Algorithm
- JS
- Master & Slave
- generator expression
- react
- 탐욕법
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함