首頁  >  文章  >  後端開發  >  發布二進位資料(應用程式/八位元組流)

發布二進位資料(應用程式/八位元組流)

WBOY
WBOY轉載
2024-02-05 21:15:28792瀏覽

發布二進位資料(應用程式/八位元組流)

問題內容

我想上傳一個內容類型設定為application/octet-stream的檔案以及請求正文中檔案的二進位資料。我將如何在 golang 中做到這一點,這是我的起始程式碼:

package main

import (
    "fmt"
    "log"
    "net/http"
    "net/http/httputil"
    "os"
)

func main() {
    file, err := os.Open("file.pdf")
    if err != nil {
        log.Fatalln(err)
    }

    req, err := http.NewRequest("POST", fmt.Sprintf("https://example.com/upload"), nil)
    req.Header.Add("Content-Type", "application/octet-stream")

    if err != nil {
        log.Fatalln(err)
    }

    client := &http.Client{
        Transport: &http.Transport{
            DisableCompression: true,
        },
    }

    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    reqDump, err := httputil.DumpRequest(req, true)
    if err != nil {
        log.Fatalln(err)
    }

    fmt.Println(reqDump)
}

正確答案


我整理了一個可以幫助您解決問題的答案。所有程式碼都屬於 main.go 文件,只是為了演示。它有兩個主要部分:handlermain 函數。讓我們從處理程序開始。

http 處理程序

func handlefile(w http.responsewriter, r *http.request) {
    if r.method != http.methodpost {
        w.writeheader(http.statusmethodnotallowed)
        return
    }
    fmt.println("handlefile")
    data, err := io.readall(r.body)
    if err != nil {
        panic(err)
    }
    defer r.body.close()
    w.write(data)
}

在這裡,我只是依賴你使用的(僅go標準庫:httpiofmt套件)。我們只需要將從 http 請求中讀取的傳入有效負載寫入回應流。

主要功能

func main() {
    r := http.NewServeMux()
    r.HandleFunc("/example", HandleFile)
    srv := http.Server{
        Addr:    ":8000",
        Handler: r,
    }

    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        defer wg.Done()
        if err := srv.ListenAndServe(); err != nil {
            fmt.Println(err.Error())
        }
    }()

    file, err := os.Open("file.txt")
    if err != nil {
        panic(err)
    }
    defer file.Close()
    req, err := http.NewRequest(http.MethodPost, "http://localhost:8000/example", file)
    if err != nil {
        panic(err)
    }
    req.Header.Set("Content-Type", "application/octet-stream")
    client := &http.Client{
        Transport: &http.Transport{
            DisableCompression: true,
        },
    }
    res, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer res.Body.Close()
    data, err := io.ReadAll(res.Body)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(data))

    srv.Shutdown(context.Background())
    wg.Wait()
}

相反,main函數有更多的邏輯需要處理。讓我們在列表中回顧一下它們:

  1. 它會建立一個 http 伺服器來服務傳入的請求。我們對其進行檢測,以使用我們先前建立的 handlefile 處理程序來回覆針對 /example 端點的請求。
  2. 我們使用 sync.waitgroup 在單獨的 goroutine 中執行伺服器。由於這一點,伺服器已啟動並運行,但我們可以繼續我們的程式並在其中發送 http 請求。
  3. 我們準備一個 http 請求,其中包含從本機檔案系統讀取的檔案內容(在我們的範例中為 file.txt)。我們將 content-type 標頭設為 application/octet-stream 並將檔案句柄傳遞給 newrequest 函數。
  4. 我們發出請求並列印 http 回應負載的內容。
  5. 我們關閉伺服器並使用 wg.wait 方法告訴 waitgroup 等待所有 goroutine。

最終考慮因素

這裡寫的程式碼絕對可以改進。無論如何,只是為了演示,我更願意讓它盡可能接近原始文件,以便讓您更好地理解如何在 http 伺服器上發布二進製文件以及如何同時運行客戶端和伺服器同一個程式。如果有不清楚的地方,請告訴我,謝謝!

以上是發布二進位資料(應用程式/八位元組流)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除