如果說你在某處看到了一個短網址,想先確認這個網址會跑道哪裡時,有哪些方法呢?
開開看
可是就是不想開才想要想辦法不是嗎…
curl -I http://example.com | grep Location
可是必須開個 terminal …
使用第三方工具
自己做個小工具
原理上來說蠻容易的,正好當練習不是嗎?
原理很容易是為何呢? 轉網址的方法有三個
HTTP 3XX
HTML meta tag
<meta http-equiv="refresh" content="0; URL=http://www.example.com/" />
JavaScript
window.location
而最常見的方法是使用 HTTP 3XX 回應。因此,想知道有沒有轉址可以
使用 HTTP
HEAD
詢問該連結若狀態碼是 3XX ,則查看回傳訊息的
Location
header 項目
依據這樣的規則就可以寫程式了
練習 take one !
這樣的工作感覺很適合 JavaScript 來做不是嗎?想想,若使用 Fetch API 加上瀏覽器,還可以有漂亮的使用者界面呢!
不過很不幸這個方法完全沒有用,因為有 cross origin 的限制。所以如果要透過網頁的話,詢問連結的邏輯必須放在伺服器,而不是瀏覽器端。
練習 take two !
那這時候,不如就把製作此工具的工程當作是練習 Rust 程式語言的契機吧。
規劃
要用 Rust 來完成這個工具,最基本上需要
hyper
crate 提供 HTTP 服務tokio-core
crate 提供非同步處理功能hyper-tls
crate 提供 HTTPS 的功能
上面不包括使用者界面可能會使用到的其他元件
軟體的架構上,把後面的探測邏輯包裝在 struct Fetch
內,並且放入自己的 crate 中。
在自己的 Rust 專案中區分 subcrate 的好處是
更加明確的區分非界面以及界面的程式碼
加快編譯速度。在開發使用者界面時,不需要重新編譯內部邏輯的部份
難處
使用 Rust 的難處在於,要符合生命週期標記 (lifetime) 、借用檢查等機制 (borrow checker) 的要求。此外,還有多型物件的回傳問題。
以這個程式來說,遇到比較難處理的是多型物件回傳的問題。因為 hyper
使用了非同步模型,牽扯了 futures
crate 的 trait Future
。在撰寫這樣的程式時, refactor 完成後,最終一定會有 function 的回傳結果是 trait Future
的物件,那這時該如何描述呢?其實用 Box
就可以解決了大部分的問題了。
那,第二不好處理的問題是 lifetime 的問題。在這個程式裡面遇到的是 Box
內的 lifetime 。預設中, Box
內物件的 lifetime 是 'static
(等同程式的壽命),但有時候某些物件無法存留如此久,就必須在 Box
內加上註記。
第三個問題點,在於對 hyper
的不熟悉,以及沒有仔細讀 hyper
的文件所導致。仔細來說,就是在利用 future 設定好進行 HTTP query 的流程之後,必須把該 future 傳送給 Core::run
。沒有傳送的話會導致程式停頓,或者發生找不到事件處理迴圈的錯誤。
第四個問題是加入 HTTPS 支援的方法。 hyper
crate 本身似乎沒有明確指出(不然就是漏看了)如何增加 HTTPS 支援。 Google 後發現可以增加 hyper-tls
crate ,然後使用 HttpsConnector
來初始化 Client
來達成功用。
最終成品:練習二號 rust-redirection-probe
所以,這樣練習得出的結果就是 rust-redirection-probe
了。
請移步到 https://gitlab.com/chiakikame/rust-redirection-probe 來取得程式碼。拿到程式碼之後請利用 cargo
來建置。
功能
可以看 HTTP / HTTPS 連結是否會經由 3XX 重新導向
可以一口氣查詢多組連結
可以用來觀摩如何把內部邏輯(程式庫)以及呈現邏輯(目前只有文字界面)區分開
相對容易使用:在 MS Windows 之下可以不用先打開 terminal 再使用。
用法
|
|
可改進處
更好看的使用者界面
Terminal 可以給更多提示
試著在程式碼中標注 rustdoc 註解