httptoolkit / mockttp

Powerful friendly HTTP mock server & proxy library
https://httptoolkit.com
Apache License 2.0
786 stars 88 forks source link

How to return cached request from thenPassThrough without hitting external request. #168

Closed shirshak55 closed 7 months ago

shirshak55 commented 7 months ago

Hi,

I want to cache response in response object and return the cached request if it already exist in the key. My initial solution is


    #response: any = {}

    activateRules = async () => {
        this.#server?.forAnyRequest().always().thenPassThrough({
            beforeRequest: (req) => {
                try {
                    // if (req.url.includes("api")) {
                    let urlObj = new URL(req.url)
                    let params = new URLSearchParams(urlObj.search)

                    this.#requests[req.id] = {
                        url: req.url,
                        request_dt: Date.now(),
                    }
                    // }
                } catch (e) {
                    console.error(e)
                }

            },
            beforeResponse: async (response) => {
                try {
                    let id = response.id
                    if (id in this.#requests) {
                        let req = this.#requests[id]
                        if (req.url in this.#response) {
                            console.log("RETURN CACHE")
                            return {
                                headers: { 'content-type': 'application/json' },
                                body: this.#response[req.url]
                            }
                        }
                        this.#response[req.url] = await response.body.getText()
                        delete this.#requests[id]
                    }
                } catch (e) {
                    console.error(e)
                }
                return {}
            },
            proxyConfig: {
                proxyUrl: "http://127.0.0.1:8000",
            },
            ignoreHostHttpsErrors: true
        })
    }

The problem is whenever mockttp is making external request, even tho i am not using it. I see there is thenReply, but I want to do it dynamically, so it works for any links.

Thanks.

pimterry commented 7 months ago

Ah, I'm not totally sure, but I think you're saying the issue is that although your cached content gets returned correctly, Mockttp is sending a request upstream anyway (and just not using the result). Is that right?

That's easy to fix - you just need to return a response field in beforeRequest (which runs before the request is sent upstream) if you have a cached result available. The problem is that beforeResponse is always run after the upstream request has already been sent & completed, so no matter what you do it can't skip anything.

The response option docs are here: https://httptoolkit.github.io/mockttp/interfaces/requestHandlers.CallbackRequestResult.html#response. There's some examples in the tests starting here: https://github.com/httptoolkit/mockttp/blob/64091fc9b1230064be96a2294d2d7992608ecdc0/test/integration/proxying/http-proxying.spec.ts#L565

shirshak55 commented 7 months ago

thanks