Construct an arbitrary HTTP request.
(
self,
method,
path,
data="",
content_type="application/octet-stream",
secure=False,
*,
headers=None,
query_params=None,
**extra,
)
| 731 | ) |
| 732 | |
| 733 | def generic( |
| 734 | self, |
| 735 | method, |
| 736 | path, |
| 737 | data=class="st">"", |
| 738 | content_type=class="st">"application/octet-stream", |
| 739 | secure=False, |
| 740 | *, |
| 741 | headers=None, |
| 742 | query_params=None, |
| 743 | **extra, |
| 744 | ): |
| 745 | class="st">""class="st">"Construct an arbitrary HTTP request."class="st">"" |
| 746 | parsed = urlsplit(str(path)) class="cm"># path can be lazy. |
| 747 | data = force_bytes(data, settings.DEFAULT_CHARSET) |
| 748 | s = { |
| 749 | class="st">"method": method, |
| 750 | class="st">"path": self._get_path(parsed), |
| 751 | class="st">"server": (class="st">"127.0.0.1", class="st">"443" if secure else class="st">"80"), |
| 752 | class="st">"scheme": class="st">"https" if secure else class="st">"http", |
| 753 | class="st">"headers": [(bclass="st">"host", bclass="st">"testserver")], |
| 754 | } |
| 755 | if self.defaults: |
| 756 | extra = {**self.defaults, **extra} |
| 757 | if data: |
| 758 | s[class="st">"headers"].extend( |
| 759 | [ |
| 760 | (bclass="st">"content-length", str(len(data)).encode(class="st">"ascii")), |
| 761 | (bclass="st">"content-type", content_type.encode(class="st">"ascii")), |
| 762 | ] |
| 763 | ) |
| 764 | s[class="st">"_body_file"] = FakePayload(data) |
| 765 | if query_params: |
| 766 | s[class="st">"query_string"] = urlencode(query_params, doseq=True) |
| 767 | elif query_string := extra.pop(class="st">"QUERY_STRING", None): |
| 768 | s[class="st">"query_string"] = query_string |
| 769 | else: |
| 770 | class="cm"># If QUERY_STRING is absent or empty, we want to extract it from |
| 771 | class="cm"># the URL. |
| 772 | s[class="st">"query_string"] = parsed.query |
| 773 | if headers: |
| 774 | extra.update(HttpHeaders.to_asgi_names(headers)) |
| 775 | s[class="st">"headers"] += [ |
| 776 | class="cm"># Avoid breaking test clients that just want to supply normalized |
| 777 | class="cm"># ASGI names, regardless of the fact that ASGIRequest drops headers |
| 778 | class="cm"># with underscores (CVE-2026-3902). |
| 779 | (key.lower().replace(class="st">"_", class="st">"-").encode(class="st">"ascii"), value.encode(class="st">"latin1")) |
| 780 | for key, value in extra.items() |
| 781 | ] |
| 782 | return self.request(**s) |
| 783 | |
| 784 | |
| 785 | class ClientMixin: |
nothing calls this directly
no test coverage detected