iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 9
0

今日目標

今天的目標是要實作轉發請求到 Github,那要怎麼轉發呢?先來分析一下平常上 Github 時瀏覽器幫你做了什麼:

  1. 瀏覽器發出 GET 請求到 Github
  2. Github 回覆 html 頁面給瀏覽器
  3. 瀏覽器呈現 Github 頁面給你看

而用了我們做的 Phish Github 之後應該要變成這樣:

  1. 瀏覽器發出 GET 請求到我們的 Phish Github
  2. Phish Github 發出 一模一樣 的請求給 Github
  3. Github 回覆 html 頁面給 Phish Github
  4. Phish Github 回覆 html 頁面給瀏覽器
  5. 瀏覽器呈現 Github 頁面給你看

其中 2,3 兩步就是我們今天要做的

實作轉發請求到 Github

複製請求

因為第二步要發出 一模一樣 的請求給 Github,這邊實作一個 cloneRequest複製請求

func cloneRequest(r *http.Request) *http.Request {
    // 取得原請求的 method、body
    method := r.Method
    body := r.Body

    // 取得原請求的 url,把它的域名替換成真正的 Github
    path := r.URL.Path
    rawQuery := r.URL.RawQuery
    url := "https://github.com" + path + "?" + rawQuery

    // 建立新的 http.Request
    req, err := http.NewRequest(method, url, body)
    if err != nil {
        panic(err)
    }
    return req
}

這邊依據原請求 methodbody 還有替換過的網址去建立一個新的請求,如果原本的請求是 GET http://localhost/Larry850806,那新的請求就會把它替換成 GET https://github.com/Larry850806

發出請求

再寫一個 sendReqToUpStream 負責把請求送到 Upstream(上游),也就是真正的 Github。

func sendReqToUpstream(req *http.Request) []byte {
    // 建立 http client
    client := http.Client{}

    // client.Do(req) 會發出請求到 Github、得到回覆 resp
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }

    // 把回覆的 body 從 Reader(串流)轉成 []byte
    respBody, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    resp.Body.Close()

    // 回傳 body
    return respBody
}

在 Go 裡面要發請求必須先建立一個 http client,請求結束後會得到一個 resp.Body 是 Github 回覆回來的 body,body 的型別是 Reader,有點像 Stream(串流)的概念,要用 ioutil.ReadAll 把它讀取出來變成 []byte,最後回傳 body

回覆 html 頁面給瀏覽器

func handler(w http.ResponseWriter, r *http.Request) {
    req := cloneRequest(r)
    body := sendReqToUpstream(req)
    w.Write(body)
}

接下來就是最重要的 handler,針對每個請求都先用 cloneRequest 複製一個一模一樣的請求,如果原請求是要新增一個 repo,那就複製一個新增 repo 的請求,然後發送到 Github

取得 Github 的回覆之後(也許是新增成功之類的),再把 body 原封不動的傳回給瀏覽器,這樣使用者就會在我們的 Phish Github 上看到新增成功的畫面,而且這個畫面是來自真正的 Github

問題

現在已經稍微做出一個雛形了,左邊的是真正的 Github,右邊則是自己架在 localhost 的假 Github,因為畫面是都是來自 Github,所以會長得一模一樣

眼尖的同學們有沒有發現右圖中左上角的 Github logo 會連回真正的 Github 呢?我們將在明天解決這個問題,聰明的各位也可以先想想看為什麼會這樣,怎麼解決?

小結

現在 Phish Github 已經有點 Github 的樣子了,雖然很多功能都還沒支援就是了,今天的程式碼也有放在 Github,建議大家可以下載程式碼到自己電腦上跑跑看,把 Github 跑在 localhost 還滿有趣的

跟前幾天一樣,有什麼問題都歡迎留言發問,我會盡量回答,謝謝大家


上一篇
Day08-動手架一個 HTTP Server
下一篇
Day10-替換頁面中的網址
系列文
Go Phishing!30 天用 Go 實作 Reverse Proxy 之釣魚大作戰30

尚未有邦友留言

立即登入留言