DEV Community

Cover image for MicroPython 1.24.0 的 requests 重新導向的問題
codemee
codemee

Posted on • Edited on

MicroPython 1.24.0 的 requests 重新導向的問題

MicroPython 的 requests 模組中實作的 request 函式有個問題,如果叫用時傳入的 headers 引數中包含有 Host 表頭,就會沿用該表頭,而不是使用實際上從 url 引數中取出的主機:

        if "Host" not in headers:
            headers["Host"] = host
        ...
        # Iterate over keys to avoid tuple alloc
        for k in headers:
            s.write(k)
            s.write(b": ")
            s.write(headers[k])
            s.write(b"\r\n")
Enter fullscreen mode Exit fullscreen mode

這是為了方便讓你強制指定主機。不過如果伺服器回應 301 等重新導向的要求時,它會傳入目前的 headers 遞迴叫用自己,而不是從回應表頭中的重新導向網址中解析出的主機名稱:

    if redirect:
        s.close()
        if status in [301, 302, 303]:
            return request("GET", redirect, None, None, headers, stream)
        else:
            return request(method, redirect, data, json, headers, stream)
Enter fullscreen mode Exit fullscreen mode

這使得重新導向時仍然沿用原本的主機,如果重新導向的網址中主機名稱和原本的不同,就可能會導致重新導向失敗。

舉例來說,如果你使用 Google 的 Apps Script 實作 web 應用,並透過 TextOutput 物件傳回文字類型的回應,礙於安全因素,它會在回應時要求重新導向,才能取得真正的回應內容。取用 web 應用的網址是:

https://script.google.com/....
Enter fullscreen mode Exit fullscreen mode

但重新導向的網址卻是:

https://script.googleusercontent.com/...
Enter fullscreen mode Exit fullscreen mode

如果重新導向時仍然採用原本的 script.google.com 為 Host 表頭,就會得到 404 的回應。

為了解決這個問題,我們必須要在伺服器要求重新導向的時候,把 Host 表頭從 headers 內移除

    if redirect:
        s.close()
        # use the Host in the redirect URL
        if "Host" in headers:
            headers.pop("Host")
        if status in [301, 302, 303]:
            return request("GET", redirect, None, None, headers, stream)
        else:
            return request(method, redirect, data, json, headers, stream)
Enter fullscreen mode Exit fullscreen mode

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs