2222)
2323
2424if MYPY :
25- from typing import Any , Awaitable , Callable , Dict , Optional , Union
25+ from typing import Any , Awaitable , Callable , Dict , Optional
2626
2727 from sentry_sdk ._types import Event
2828
@@ -367,10 +367,10 @@ def _make_request_event_processor(req, integration):
367367 def event_processor (event , hint ):
368368 # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]
369369
370- # Extract information from request
370+ # Add info from request to event
371371 request_info = event .get ("request" , {})
372372 if info :
373- if "cookies" in info and _should_send_default_pii () :
373+ if "cookies" in info :
374374 request_info ["cookies" ] = info ["cookies" ]
375375 if "data" in info :
376376 request_info ["data" ] = info ["data" ]
@@ -473,30 +473,46 @@ async def extract_request_info(self):
473473 request_info = {} # type: Dict[str, Any]
474474
475475 with capture_internal_exceptions ():
476+ # Add cookies
476477 if _should_send_default_pii ():
477478 request_info ["cookies" ] = self .cookies ()
478479
480+ # If there is no body, just return the cookies
479481 content_length = await self .content_length ()
480-
481- if content_length :
482- data = None # type: Union[Dict[str, Any], AnnotatedValue, None]
483-
484- if not request_body_within_bounds (client , content_length ):
485- data = AnnotatedValue .removed_because_over_size_limit ()
486-
487- else :
488- parsed_body = await self .parsed_body ()
489- if parsed_body is not None :
490- data = parsed_body
491- elif await self .raw_data ():
492- data = AnnotatedValue .removed_because_raw_data ()
493- else :
494- data = None
495-
496- if data is not None :
497- request_info ["data" ] = data
498-
499- return request_info
482+ if not content_length :
483+ return request_info
484+
485+ # Add annotation if body is too big
486+ if content_length and not request_body_within_bounds (
487+ client , content_length
488+ ):
489+ request_info ["data" ] = AnnotatedValue .removed_because_over_size_limit ()
490+ return request_info
491+
492+ # Add JSON body, if it is a JSON request
493+ json = await self .json ()
494+ if json :
495+ request_info ["data" ] = json
496+ return request_info
497+
498+ # Add form as key/value pairs, if request has form data
499+ form = await self .form ()
500+ if form :
501+ form_data = {}
502+ for key , val in iteritems (form ):
503+ is_file = isinstance (val , UploadFile )
504+ form_data [key ] = (
505+ val
506+ if not is_file
507+ else AnnotatedValue .removed_because_raw_data ()
508+ )
509+
510+ request_info ["data" ] = form_data
511+ return request_info
512+
513+ # Raw data, do not add body just an annotation
514+ request_info ["data" ] = AnnotatedValue .removed_because_raw_data ()
515+ return request_info
500516
501517 async def content_length (self ):
502518 # type: (StarletteRequestExtractor) -> Optional[int]
@@ -509,19 +525,17 @@ def cookies(self):
509525 # type: (StarletteRequestExtractor) -> Dict[str, Any]
510526 return self .request .cookies
511527
512- async def raw_data (self ):
513- # type: (StarletteRequestExtractor) -> Any
514- return await self .request .body ()
515-
516528 async def form (self ):
517529 # type: (StarletteRequestExtractor) -> Any
518- """
519- curl -X POST http://localhost:8000/upload/somethign -H "Content-Type: application/x-www-form-urlencoded" -d "username=kevin&password=welcome123"
520- curl -X POST http://localhost:8000/upload/somethign -F username=Julian -F password=hello123
521- """
522530 if multipart is None :
523531 return None
524532
533+ # Parse the body first to get it cached, as Starlette does not cache form() as it
534+ # does with body() and json() https://github.com/encode/starlette/discussions/1933
535+ # Calling `.form()` without calling `.body()` first will
536+ # potentially break the users project.
537+ await self .request .body ()
538+
525539 return await self .request .form ()
526540
527541 def is_json (self ):
@@ -530,33 +544,11 @@ def is_json(self):
530544
531545 async def json (self ):
532546 # type: (StarletteRequestExtractor) -> Optional[Dict[str, Any]]
533- """
534- curl -X POST localhost:8000/upload/something -H 'Content-Type: application/json' -d '{"login":"my_login","password":"my_password"}'
535- """
536547 if not self .is_json ():
537548 return None
538549
539550 return await self .request .json ()
540551
541- async def parsed_body (self ):
542- # type: (StarletteRequestExtractor) -> Any
543- """
544- curl -X POST http://localhost:8000/upload/somethign -F username=Julian -F password=hello123 -F photo=@photo.jpg
545- """
546- form = await self .form ()
547- if form :
548- data = {}
549- for key , val in iteritems (form ):
550- if isinstance (val , UploadFile ):
551- data [key ] = AnnotatedValue .removed_because_raw_data ()
552- else :
553- data [key ] = val
554-
555- return data
556-
557- json_data = await self .json ()
558- return json_data
559-
560552
561553def _set_transaction_name_and_source (event , transaction_style , request ):
562554 # type: (Event, str, Any) -> None
0 commit comments