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

Reinvent your career. Join DEV.

It takes one minute and is worth it for your career.

Get started

Top comments (0)

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up