diff --git a/CHANGES b/CHANGES
index 59a5925..2bb4095 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,8 @@
 0.24.0
 ------
 
+* Added `real_adapter_send` parameter to `RequestsMock` that will allow users to set
+  through which function they would like to send real requests
 * Added support for re.Pattern based header matching.
 * Added support for gzipped response bodies to `json_params_matcher`.
 * Moved types-pyyaml dependency to `tests_requires`
diff --git a/responses/__init__.py b/responses/__init__.py
index a89e2d7..ea7009d 100644
--- a/responses/__init__.py
+++ b/responses/__init__.py
@@ -49,7 +49,8 @@ except ImportError:  # pragma: no cover
 try:
     from requests.packages.urllib3.connection import HTTPHeaderDict
 except ImportError:  # pragma: no cover
-    from urllib3.response import HTTPHeaderDict  # type: ignore[attr-defined]
+    from urllib3.response import HTTPHeaderDict
+
 try:
     from requests.packages.urllib3.util.url import parse_url
 except ImportError:  # pragma: no cover
@@ -84,14 +85,25 @@ if TYPE_CHECKING:  # pragma: no cover
         ) -> models.Response:
             ...
 
-
-# Block of type annotations
-_Body = Union[str, BaseException, "Response", BufferedReader, bytes, None]
-_F = Callable[..., Any]
-_HeaderSet = Optional[Union[Mapping[str, str], List[Tuple[str, str]]]]
-_MatcherIterable = Iterable[Callable[..., Tuple[bool, str]]]
-_HTTPMethodOrResponse = Optional[Union[str, "BaseResponse"]]
-_URLPatternType = Union["Pattern[str]", str]
+    # Block of type annotations
+    _Body = Union[str, BaseException, "Response", BufferedReader, bytes, None]
+    _F = Callable[..., Any]
+    _HeaderSet = Optional[Union[Mapping[str, str], List[Tuple[str, str]]]]
+    _MatcherIterable = Iterable[Callable[..., Tuple[bool, str]]]
+    _HTTPMethodOrResponse = Optional[Union[str, "BaseResponse"]]
+    _URLPatternType = Union["Pattern[str]", str]
+    _HTTPAdapterSend = Callable[
+        [
+            HTTPAdapter,
+            PreparedRequest,
+            bool,
+            float | tuple[float, float] | tuple[float, None] | None,
+            bool | str,
+            bytes | str | tuple[bytes | str, bytes | str] | None,
+            Mapping[str, str] | None,
+        ],
+        models.Response,
+    ]
 
 
 Call = namedtuple("Call", ["request", "response"])
@@ -250,7 +262,7 @@ class CallList(Sequence[Any], Sized):
     def __getitem__(self, idx: Union[int, slice]) -> Union[Call, List[Call]]:
         return self._calls[idx]
 
-    def add(self, request: "PreparedRequest", response: _Body) -> None:
+    def add(self, request: "PreparedRequest", response: "_Body") -> None:
         self._calls.append(Call(request, response))
 
     def reset(self) -> None:
@@ -258,8 +270,8 @@ class CallList(Sequence[Any], Sized):
 
 
 def _ensure_url_default_path(
-    url: _URLPatternType,
-) -> _URLPatternType:
+    url: "_URLPatternType",
+) -> "_URLPatternType":
     """Add empty URL path '/' if doesn't exist.
 
     Examples
@@ -376,7 +388,7 @@ class BaseResponse:
     def __init__(
         self,
         method: str,
-        url: _URLPatternType,
+        url: "_URLPatternType",
         match_querystring: Union[bool, object] = None,
         match: "_MatcherIterable" = (),
         *,
@@ -384,7 +396,7 @@ class BaseResponse:
     ) -> None:
         self.method: str = method
         # ensure the url has a default path set if the url is a string
-        self.url: _URLPatternType = _ensure_url_default_path(url)
+        self.url: "_URLPatternType" = _ensure_url_default_path(url)
 
         if self._should_match_querystring(match_querystring):
             match = tuple(match) + (
@@ -434,7 +446,7 @@ class BaseResponse:
 
         return bool(urlsplit(self.url).query)
 
-    def _url_matches(self, url: _URLPatternType, other: str) -> bool:
+    def _url_matches(self, url: "_URLPatternType", other: str) -> bool:
         """Compares two URLs.
 
         Compares only scheme, netloc and path. If 'url' is a re.Pattern, then checks that
@@ -532,8 +544,8 @@ class Response(BaseResponse):
     def __init__(
         self,
         method: str,
-        url: _URLPatternType,
-        body: _Body = "",
+        url: "_URLPatternType",
+        body: "_Body" = "",
         json: Optional[Any] = None,
         status: int = 200,
         headers: Optional[Mapping[str, str]] = None,
@@ -556,7 +568,7 @@ class Response(BaseResponse):
             else:
                 content_type = "text/plain"
 
-        self.body: _Body = body
+        self.body: "_Body" = body
         self.status: int = status
         self.headers: Optional[Mapping[str, str]] = headers
 
@@ -608,7 +620,7 @@ class CallbackResponse(BaseResponse):
     def __init__(
         self,
         method: str,
-        url: _URLPatternType,
+        url: "_URLPatternType",
         callback: Callable[[Any], Any],
         stream: Optional[bool] = None,
         content_type: Optional[str] = "text/plain",
@@ -678,6 +690,8 @@ class RequestsMock:
         passthru_prefixes: Tuple[str, ...] = (),
         target: str = "requests.adapters.HTTPAdapter.send",
         registry: Type[FirstMatchRegistry] = FirstMatchRegistry,
+        *,
+        real_adapter_send: "_HTTPAdapterSend" = _real_send,
     ) -> None:
         self._calls: CallList = CallList()
         self.reset()
@@ -688,6 +702,7 @@ class RequestsMock:
         self.target: str = target
         self._patcher: Optional["_mock_patcher[Any]"] = None
         self._thread_lock = _ThreadingLock()
+        self._real_send = real_adapter_send
 
     def get_registry(self) -> FirstMatchRegistry:
         """Returns current registry instance with responses.
@@ -726,10 +741,10 @@ class RequestsMock:
 
     def add(
         self,
-        method: _HTTPMethodOrResponse = None,
+        method: "_HTTPMethodOrResponse" = None,
         url: "Optional[_URLPatternType]" = None,
-        body: _Body = "",
-        adding_headers: _HeaderSet = None,
+        body: "_Body" = "",
+        adding_headers: "_HeaderSet" = None,
         *args: Any,
         **kwargs: Any,
     ) -> BaseResponse:
@@ -808,7 +823,7 @@ class RequestsMock:
                 auto_calculate_content_length=rsp["auto_calculate_content_length"],
             )
 
-    def add_passthru(self, prefix: _URLPatternType) -> None:
+    def add_passthru(self, prefix: "_URLPatternType") -> None:
         """
         Register a URL prefix or regex to passthru any non-matching mock requests to.
 
@@ -829,7 +844,7 @@ class RequestsMock:
 
     def remove(
         self,
-        method_or_response: _HTTPMethodOrResponse = None,
+        method_or_response: "_HTTPMethodOrResponse" = None,
         url: "Optional[_URLPatternType]" = None,
     ) -> List[BaseResponse]:
         """
@@ -852,9 +867,9 @@ class RequestsMock:
 
     def replace(
         self,
-        method_or_response: _HTTPMethodOrResponse = None,
+        method_or_response: "_HTTPMethodOrResponse" = None,
         url: "Optional[_URLPatternType]" = None,
-        body: _Body = "",
+        body: "_Body" = "",
         *args: Any,
         **kwargs: Any,
     ) -> BaseResponse:
@@ -878,9 +893,9 @@ class RequestsMock:
 
     def upsert(
         self,
-        method_or_response: _HTTPMethodOrResponse = None,
+        method_or_response: "_HTTPMethodOrResponse" = None,
         url: "Optional[_URLPatternType]" = None,
-        body: _Body = "",
+        body: "_Body" = "",
         *args: Any,
         **kwargs: Any,
     ) -> BaseResponse:
@@ -901,9 +916,10 @@ class RequestsMock:
     def add_callback(
         self,
         method: str,
-        url: _URLPatternType,
+        url: "_URLPatternType",
         callback: Callable[
-            ["PreparedRequest"], Union[Exception, Tuple[int, Mapping[str, str], _Body]]
+            ["PreparedRequest"],
+            Union[Exception, Tuple[int, Mapping[str, str], "_Body"]],
         ],
         match_querystring: Union[bool, FalseBool] = FalseBool(),
         content_type: Optional[str] = "text/plain",
@@ -940,7 +956,7 @@ class RequestsMock:
         return success
 
     @overload
-    def activate(self, func: _F = ...) -> _F:
+    def activate(self, func: "_F" = ...) -> "_F":
         """Overload for scenario when 'responses.activate' is used."""
 
     @overload
@@ -958,15 +974,15 @@ class RequestsMock:
 
     def activate(
         self,
-        func: Optional[_F] = None,
+        func: Optional["_F"] = None,
         *,
         registry: Optional[Type[Any]] = None,
         assert_all_requests_are_fired: bool = False,
-    ) -> Union[Callable[["_F"], "_F"], _F]:
+    ) -> Union[Callable[["_F"], "_F"], "_F"]:
         if func is not None:
             return get_wrapped(func, self)
 
-        def deco_activate(function: _F) -> Callable[..., Any]:
+        def deco_activate(function: "_F") -> Callable[..., Any]:
             return get_wrapped(
                 function,
                 self,
@@ -1028,7 +1044,7 @@ class RequestsMock:
                 ]
             ):
                 logger.info("request.allowed-passthru", extra={"url": request_url})
-                return _real_send(adapter, request, **kwargs)
+                return self._real_send(adapter, request, **kwargs)  # type: ignore
 
             error_msg = (
                 "Connection refused by Responses - the call doesn't "
@@ -1055,7 +1071,7 @@ class RequestsMock:
 
         if match.passthrough:
             logger.info("request.passthrough-response", extra={"url": request_url})
-            response = _real_send(adapter, request, **kwargs)  # type: ignore[assignment]
+            response = self._real_send(adapter, request, **kwargs)  # type: ignore
         else:
             try:
                 response = adapter.build_response(  # type: ignore[no-untyped-call]

diff --git a/responses/tests/test_responses.py b/responses/tests/test_responses.py
index 2ae3d65..b6c1a5e 100644
--- a/responses/tests/test_responses.py
+++ b/responses/tests/test_responses.py
@@ -1838,6 +1838,34 @@ class TestPassthru:
         run()
         assert_reset()
 
+    def test_real_send_argument(self):
+        def run():
+            # the following mock will serve to catch the real send request from another mock and
+            # will "donate" `unbound_on_send` method
+            mock_to_catch_real_send = responses.RequestsMock(
+                assert_all_requests_are_fired=True
+            )
+            mock_to_catch_real_send.post(
+                "http://send-this-request-through.com", status=500
+            )
+
+            with responses.RequestsMock(
+                assert_all_requests_are_fired=True,
+                real_adapter_send=mock_to_catch_real_send.unbound_on_send(),
+            ) as r_mock:
+                r_mock.add_passthru("http://send-this-request-through.com")
+
+                r_mock.add(responses.POST, "https://example.org", status=200)
+
+                response = requests.post("https://example.org")
+                assert response.status_code == 200
+
+                response = requests.post("http://send-this-request-through.com")
+                assert response.status_code == 500
+
+        run()
+        assert_reset()
+
 
 def test_method_named_param():
     @responses.activate

RecursionError with passthru and _real_send override
### Describe the bug

When using the `responses._real_send = self.r_mock.unbound_on_send()` solution described [here](https://github.com/getmoto/moto/issues/6417), I am getting a recursion error.

### Additional context

This issue replaces [this one](https://github.com/getsentry/responses/issues/669)

### Version of `responses`

0.23.3

### Steps to Reproduce

You can run `unittest` on this file and get the error :)

```python
import os
import re
import unittest
import requests

os.environ["ENVIRONMENT"] = "tests"

import responses


def my_function():
    # Send an email
    requests.post("https://example.org")

    # Do something else with the passthru
    requests.post("http://localhost:7700/indexes/test/documents")

    return "OK"


class _TestCase(unittest.TestCase):
    def setUp(self):
        self.r_mock = responses.RequestsMock(assert_all_requests_are_fired=True)
        self.r_mock.start()
        self.r_mock.add_passthru(re.compile(rf"http://localhost:7700.*"))
        responses._real_send = self.r_mock.unbound_on_send()

    def tearDown(self):
        self.r_mock.stop()
        self.r_mock.reset()


class MyTest(_TestCase):

    def test_indexing(self):
        self.r_mock.add(responses.POST, "https://example.org", status=200)
        self.assertEqual("OK", my_function())
```

### Expected Result

The test should run fine

### Actual Result

```
============================= test session starts ==============================
collecting ... collected 1 item

reproduce.py::MyTest::test_indexing 

============================== 1 failed in 0.19s ===============================
FAILED                               [100%]
reproduce.py:34 (MyTest.test_indexing)
self = <reproduce.MyTest testMethod=test_indexing>

    def test_indexing(self):
        self.r_mock.add(responses.POST, "https://example.org", status=200)
>       self.assertEqual("OK", my_function())

reproduce.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
reproduce.py:16: in my_function
    requests.post("http://localhost:7700/indexes/test/documents")
.venv/lib/python3.11/site-packages/requests/api.py:115: in post
    return request("post", url, data=data, json=json, **kwargs)
.venv/lib/python3.11/site-packages/requests/api.py:59: in request
    return session.request(method=method, url=url, **kwargs)
.venv/lib/python3.11/site-packages/requests/sessions.py:587: in request
    resp = self.send(prep, **send_kwargs)
.venv/lib/python3.11/site-packages/requests/sessions.py:701: in send
    r = adapter.send(request, **kwargs)
.venv/lib/python3.11/site-packages/responses/__init__.py:1127: in send
    return self._on_request(adapter, request, **kwargs)
.venv/lib/python3.11/site-packages/responses/__init__.py:1033: in _on_request
    return _real_send(adapter, request, **kwargs)
.venv/lib/python3.11/site-packages/responses/__init__.py:1127: in send
    return self._on_request(adapter, request, **kwargs)
E   RecursionError: maximum recursion depth exceeded while calling a Python object
!!! Recursion detected (same locals & position)
```
responses/tests/test_responses.py::TestPassthru::test_real_send_argument
responses/tests/test_responses.py::test_response responses/tests/test_responses.py::test_response_encoded responses/tests/test_responses.py::test_response_with_instance responses/tests/test_responses.py::test_replace[http://example.com/two-http://example.com/two] responses/tests/test_responses.py::test_replace[original1-replacement1] responses/tests/test_responses.py::test_replace[http://example\\.com/two-http://example\\.com/two] responses/tests/test_responses.py::test_replace_error[http://example.com/one-http://example\\.com/one] responses/tests/test_responses.py::test_replace_error[http://example\\.com/one-http://example.com/one] responses/tests/test_responses.py::test_replace_response_object_error responses/tests/test_responses.py::test_upsert_replace[http://example.com/two-http://example.com/two] responses/tests/test_responses.py::test_upsert_replace[original1-replacement1] responses/tests/test_responses.py::test_upsert_replace[http://example\\.com/two-http://example\\.com/two] responses/tests/test_responses.py::test_upsert_add[http://example.com/two-http://example.com/two] responses/tests/test_responses.py::test_upsert_add[original1-replacement1] responses/tests/test_responses.py::test_upsert_add[http://example\\.com/two-http://example\\.com/two] responses/tests/test_responses.py::test_remove responses/tests/test_responses.py::test_response_equality[args10-kwargs10-args20-kwargs20-True] responses/tests/test_responses.py::test_response_equality[args11-kwargs11-args21-kwargs21-False] responses/tests/test_responses.py::test_response_equality[args12-kwargs12-args22-kwargs22-False] responses/tests/test_responses.py::test_response_equality[args13-kwargs13-args23-kwargs23-True] responses/tests/test_responses.py::test_response_equality_different_objects responses/tests/test_responses.py::test_connection_error responses/tests/test_responses.py::test_match_querystring responses/tests/test_responses.py::test_match_querystring_empty responses/tests/test_responses.py::test_match_querystring_error responses/tests/test_responses.py::test_match_querystring_regex responses/tests/test_responses.py::test_match_querystring_error_regex responses/tests/test_responses.py::test_match_querystring_auto_activates responses/tests/test_responses.py::test_match_querystring_missing_key responses/tests/test_responses.py::test_accept_string_body responses/tests/test_responses.py::test_accept_json_body responses/tests/test_responses.py::test_no_content_type responses/tests/test_responses.py::test_arbitrary_status_code responses/tests/test_responses.py::test_throw_connection_error_explicit responses/tests/test_responses.py::test_callback responses/tests/test_responses.py::test_deprecated_package_attributes responses/tests/test_responses.py::test_callback_deprecated_stream_argument responses/tests/test_responses.py::test_callback_deprecated_match_querystring_argument responses/tests/test_responses.py::test_callback_match_querystring_default_false responses/tests/test_responses.py::test_callback_exception_result responses/tests/test_responses.py::test_callback_exception_body responses/tests/test_responses.py::test_callback_no_content_type responses/tests/test_responses.py::test_callback_content_type_dict responses/tests/test_responses.py::test_callback_matchers responses/tests/test_responses.py::test_callback_matchers_fail responses/tests/test_responses.py::test_callback_content_type_tuple responses/tests/test_responses.py::test_regular_expression_url responses/tests/test_responses.py::test_base_response_get_response responses/tests/test_responses.py::TestAdapters::test_custom_adapter[CustomAdapter] responses/tests/test_responses.py::TestAdapters::test_custom_adapter[PositionalArgsAdapter] responses/tests/test_responses.py::TestAdapters::test_custom_adapter[PositionalArgsIncompleteAdapter] responses/tests/test_responses.py::test_responses_as_context_manager responses/tests/test_responses.py::test_activate_doesnt_change_signature responses/tests/test_responses.py::TestFixtures::test_function responses/tests/test_responses.py::TestFixtures::test_function_decorated responses/tests/test_responses.py::test_activate_mock_interaction responses/tests/test_responses.py::test_activate_doesnt_change_signature_with_return_type responses/tests/test_responses.py::test_activate_doesnt_change_signature_for_method responses/tests/test_responses.py::test_response_cookies responses/tests/test_responses.py::test_response_cookies_secure responses/tests/test_responses.py::test_response_cookies_multiple responses/tests/test_responses.py::test_response_cookies_session[True-True] responses/tests/test_responses.py::test_response_cookies_session[True-False] responses/tests/test_responses.py::test_response_cookies_session[True-None] responses/tests/test_responses.py::test_response_cookies_session[False-True] responses/tests/test_responses.py::test_response_cookies_session[False-False] responses/tests/test_responses.py::test_response_cookies_session[False-None] responses/tests/test_responses.py::test_response_cookies_session[None-True] responses/tests/test_responses.py::test_response_cookies_session[None-False] responses/tests/test_responses.py::test_response_cookies_session[None-None] responses/tests/test_responses.py::test_response_callback responses/tests/test_responses.py::test_response_filebody responses/tests/test_responses.py::test_use_stream_twice_to_double_raw_io responses/tests/test_responses.py::test_assert_all_requests_are_fired responses/tests/test_responses.py::test_assert_all_requests_fired_multiple responses/tests/test_responses.py::test_allow_redirects_samehost responses/tests/test_responses.py::test_path_segments responses/tests/test_responses.py::test_handles_unicode_querystring responses/tests/test_responses.py::test_handles_unicode_url responses/tests/test_responses.py::test_handles_unicode_body responses/tests/test_responses.py::test_handles_buffered_reader_body responses/tests/test_responses.py::test_headers responses/tests/test_responses.py::test_content_length_error responses/tests/test_responses.py::test_stream_with_none_chunk_size responses/tests/test_responses.py::test_legacy_adding_headers responses/tests/test_responses.py::test_legacy_adding_headers_with_content_type responses/tests/test_responses.py::test_auto_calculate_content_length_string_body responses/tests/test_responses.py::test_auto_calculate_content_length_bytes_body responses/tests/test_responses.py::test_auto_calculate_content_length_json_body responses/tests/test_responses.py::test_auto_calculate_content_length_unicode_body responses/tests/test_responses.py::test_auto_calculate_content_length_doesnt_work_for_buffered_reader_body responses/tests/test_responses.py::test_auto_calculate_content_length_doesnt_override_existing_value responses/tests/test_responses.py::test_multiple_responses responses/tests/test_responses.py::test_multiple_responses_intermixed responses/tests/test_responses.py::test_multiple_urls responses/tests/test_responses.py::test_multiple_methods responses/tests/test_responses.py::TestPassthru::test_passthrough_flag responses/tests/test_responses.py::TestPassthru::test_passthrough_kwarg responses/tests/test_responses.py::TestPassthru::test_passthrough_response responses/tests/test_responses.py::TestPassthru::test_passthrough_response_stream responses/tests/test_responses.py::TestPassthru::test_passthru_prefixes responses/tests/test_responses.py::TestPassthru::test_passthru responses/tests/test_responses.py::TestPassthru::test_passthru_regex responses/tests/test_responses.py::TestPassthru::test_passthru_does_not_persist_across_tests responses/tests/test_responses.py::TestPassthru::test_passthru_unicode responses/tests/test_responses.py::test_method_named_param responses/tests/test_responses.py::test_custom_target responses/tests/test_responses.py::test_request_param[http://example.com] responses/tests/test_responses.py::test_request_param[http://example.com/some/path] responses/tests/test_responses.py::test_request_param[http://example.com/other/path/] responses/tests/test_responses.py::test_request_param_with_multiple_values_for_the_same_key responses/tests/test_responses.py::test_assert_call_count[http://example.com] responses/tests/test_responses.py::test_assert_call_count[http://example.com?hello=world] responses/tests/test_responses.py::test_call_count_with_matcher responses/tests/test_responses.py::test_call_count_without_matcher responses/tests/test_responses.py::test_fail_request_error responses/tests/test_responses.py::test_response_representations[response_params0-<Response(url='http://example.com/' responses/tests/test_responses.py::test_response_representations[response_params1-<Response(url='http://another-domain.com/' responses/tests/test_responses.py::test_response_representations[response_params2-<Response(url='http://abcd.com/' responses/tests/test_responses.py::test_mocked_responses_list_registered responses/tests/test_responses.py::test_rfc_compliance[http://service-A/foo?q=fizz-http://service-a/foo?q=fizz] responses/tests/test_responses.py::test_rfc_compliance[http://service-a/foo-http://service-A/foo] responses/tests/test_responses.py::test_rfc_compliance[http://someHost-AwAy/-http://somehost-away/] responses/tests/test_responses.py::test_rfc_compliance[http://fizzbuzz/foo-http://fizzbuzz/foo] responses/tests/test_responses.py::test_requests_between_add responses/tests/test_responses.py::test_responses_reuse responses/tests/test_responses.py::TestStrictWrapper::test_strict_wrapper responses/tests/test_responses.py::TestStrictWrapper::test_nested_decorators[True] responses/tests/test_responses.py::TestStrictWrapper::test_nested_decorators[False] responses/tests/test_responses.py::TestStrictWrapper::test_nested_decorators[None] responses/tests/test_responses.py::TestMultipleWrappers::test_wrapped responses/tests/test_responses.py::TestMultipleWrappers::test_call_another_wrapped_function responses/tests/test_responses.py::TestMultipleWrappers::test_mock_not_leaked responses/tests/test_responses.py::TestShortcuts::test_delete responses/tests/test_responses.py::TestShortcuts::test_get responses/tests/test_responses.py::TestShortcuts::test_head responses/tests/test_responses.py::TestShortcuts::test_options responses/tests/test_responses.py::TestShortcuts::test_patch responses/tests/test_responses.py::TestShortcuts::test_post responses/tests/test_responses.py::TestShortcuts::test_put responses/tests/test_responses.py::TestUnitTestPatchSetup::test_function responses/tests/test_responses.py::TestUnitTestPatchSetupRaises::test_function responses/tests/test_responses.py::test_reset_in_the_middle responses/tests/test_responses.py::test_redirect responses/tests/test_responses.py::TestMaxRetry::test_max_retries responses/tests/test_responses.py::TestMaxRetry::test_max_retries_exceed[True] responses/tests/test_responses.py::TestMaxRetry::test_max_retries_exceed[False] responses/tests/test_responses.py::TestMaxRetry::test_max_retries_exceed_msg responses/tests/test_responses.py::TestMaxRetry::test_adapter_retry_untouched responses/tests/test_responses.py::test_request_object_attached_to_exception