サーチ…


備考

http.ServeMuxは、HTTPリクエストのハンドラを呼び出すマルチプレクサを提供します。

標準ライブラリーマルチプレクサの代替品は次のとおりです。

カスタムサーバーとマルチプレクサを備えたHTTP Hello World

package main

import (
    "log"
    "net/http"
)

func main() {

    // Create a mux for routing incoming requests
    m := http.NewServeMux()

    // All URLs will be handled by this function
    m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, world!"))
    })

    // Create a server listening on port 8000
    s := &http.Server{
        Addr:    ":8000",
        Handler: m,
    }

    // Continue to process new requests until an error occurs
    log.Fatal(s.ListenAndServe())
}

Ctrl + Cを押して処理を停止します。

こんにちは世界

golangでWebサーバーを作成する典型的な方法は、標準ライブラリnet/httpモジュールを使用することです。

ここにはチュートリアルもあります

次のコードもそれを使用します。ここでは、可能な限り単純なHTTPサーバー実装があります。 HTTPリクエストに"Hello World"を応答します。

ワークスペース内のserver.goファイルに次のコードを保存します。

package main

import (
    "log"
    "net/http"
)

func main() {
    // All URLs will be handled by this function
    // http.HandleFunc uses the DefaultServeMux
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, world!"))
    })

    // Continue to process new requests until an error occurs
    log.Fatal(http.ListenAndServe(":8080", nil))
}

次の方法を使用してサーバーを実行できます。

$ go run server.go

あるいはコンパイルして実行することもできます。

$ go build server.go
$ ./server

サーバーは指定されたポート( :8080 )をリッスンします。任意のHTTPクライアントでテストできます。 cURLた例を次に示しcURL

curl -i http://localhost:8080/
HTTP/1.1 200 OK
Date: Wed, 20 Jul 2016 18:04:46 GMT
Content-Length: 13
Content-Type: text/plain; charset=utf-8

Hello, world!

Ctrl + Cを押して処理を停止します。

ハンドラ関数の使用

HandleFuncは、指定されたパターンのハンドラ関数をサーバmux(ルータ)に登録します。

基本的なHello Worldの例で見たように、無名関数を定義して渡すことができます:

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello, world!")
}

HandlerFunc型も渡すことができます。つまり、次のシグネチャを尊重する関数を渡すことができます。

func FunctionName(w http.ResponseWriter, req *http.Request)

以前に定義したHandlerFunc参照を渡す前の例を書き直すことができます。完全な例は次のとおりです。

package main

import (
    "fmt"
    "net/http"
)

// A HandlerFunc function
// Notice the signature of the function
func RootHandler(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintln(w, "Hello, world!")
}

func main() {
    // Here we pass the reference to the `RootHandler` handler function
    http.HandleFunc("/", RootHandler)
    panic(http.ListenAndServe(":8080", nil))
}

もちろん、異なるパスに対していくつかの関数ハンドラを定義することができます。

package main

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

func FooHandler(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintln(w, "Hello from foo!")
}

func BarHandler(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintln(w, "Hello from bar!")
}

func main() {
    http.HandleFunc("/foo", FooHandler)
    http.HandleFunc("/bar", BarHandler)

    log.Fatal(http.ListenAndServe(":8080", nil))
}

cURLを使用した出力は次のとおりです。

➜  ~ curl -i localhost:8080/foo
HTTP/1.1 200 OK
Date: Wed, 20 Jul 2016 18:23:08 GMT
Content-Length: 16
Content-Type: text/plain; charset=utf-8

Hello from foo!

➜  ~ curl -i localhost:8080/bar
HTTP/1.1 200 OK
Date: Wed, 20 Jul 2016 18:23:10 GMT
Content-Length: 16
Content-Type: text/plain; charset=utf-8

Hello from bar!

➜  ~ curl -i localhost:8080/
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Wed, 20 Jul 2016 18:23:13 GMT
Content-Length: 19

404 page not found

HTTPSサーバーの作成

証明書を生成する

HTTPSサーバーを実行するには、証明書が必要です。 openssl自己署名証明書を生成するには、次のコマンドを実行します。

openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout key.pem -out cert.pem -subj "/CN=example.com" -days 3650`

パラメータは次のとおりです。

  • req証明書要求ツールを使用する
  • x509自己署名証明書を作成します。
  • newkey rsa:4096 4096ビットの鍵長のRSAアルゴリズムを使用して新しい鍵と証明書を作成する
  • sha256主要ブラウザがセキュアであると考えるSHA256ハッシュアルゴリズムを強制します(2017年)
  • nodes秘密鍵のパスワード保護を無効にします。このパラメータがなければ、サーバは起動するたびにパスワードを要求する必要がありました。
  • keyoutファイルにキーを書き込む場所を指定します。
  • outファイルに証明書を書き込む場所を指定します。
  • subjこの証明書が有効であるドメイン名を定義します。
  • days午前この証明書は有効な日数は何日ですか? 3650は約です。 10年。

注:内部プロジェクト、デバッグ、テストなどには、自己署名証明書を使用することができます。そこにあるブラウザには、この証明書が安全でないことが記載されています。これを回避するには、証明書に証明機関が署名する必要があります。ほとんどの場合、これは無料では利用できません。 1つの例外は「Let's Encrypt」の動きです: https : //letsencrypt.org

必要なGoコード

次のコードを使用して、サーバーの構成TLSを処理できます。 cert.pemkey.pemはSSL証明書とキーです。上記のコマンドで生成されたものです。

package main

import (
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, world!"))
    })

    log.Fatal(http.ListenAndServeTLS(":443","cert.pem","key.pem", nil))
}

テンプレートを使用したHTTPリクエストへの応答

Goのテンプレートを使用してhttp.ResponseWriterhttp.ResponseWriter書き込むことができます。動的なページを作成したい場合、これは便利なツールとして証明されます。

(テンプレートがGoでどのように機能するかを知るには、 Go Templates Documentationページをご覧ください)。

HTTPリクエストに応答するためにhtml/templateを利用する簡単な例を続ける:

package main

import(
    "html/template"
    "net/http"
    "log"
)

func main(){
    http.HandleFunc("/",WelcomeHandler)
    http.ListenAndServe(":8080",nil)
}

type User struct{
    Name string
    nationality string //unexported field.
}

func check(err error){
    if err != nil{
        log.Fatal(err)
    }
}

func WelcomeHandler(w http.ResponseWriter, r *http.Request){
    if r.Method == "GET"{
        t,err := template.ParseFiles("welcomeform.html")
        check(err)
        t.Execute(w,nil)
    }else{
        r.ParseForm()
        myUser := User{}
        myUser.Name = r.Form.Get("entered_name")
        myUser.nationality = r.Form.Get("entered_nationality")
        t, err := template.ParseFiles("welcomeresponse.html")
        check(err)
        t.Execute(w,myUser)
    }
}

ここで、

  1. welcomeform.htmlは:
<head>
    <title> Help us greet you </title>
</head>
<body>
    <form method="POST" action="/">
        Enter Name: <input type="text" name="entered_name">
        Enter Nationality: <input type="text" name="entered_nationality">
        <input type="submit" value="Greet me!">
    </form>
</body>
  1. welcomeresponse.htmlは次のwelcomeresponse.htmlです:
<head>
    <title> Greetings, {{.Name}} </title>
</head>
<body>
    Greetings, {{.Name}}.<br>
    We know you are a {{.nationality}}!
</body>

注意:

  1. .htmlファイルが正しいディレクトリにあることを確認します。

  2. サーバ起動後にhttp://localhost:8080/アクセスできます。

  3. フォームを送信した後に見られるように、構造体の非公開の国籍フィールドは、期待通りにテンプレートパッケージによって解析できませんでした。

ServeMuxを使用したコンテンツ配信

単純な静的ファイルサーバーは次のようになります。

package main

import (
    "net/http"
)

func main() {
    muxer := http.NewServeMux()
    fileServerCss := http.FileServer(http.Dir("src/css"))
    fileServerJs := http.FileServer(http.Dir("src/js"))
    fileServerHtml := http.FileServer(http.Dir("content"))
    muxer.Handle("/", fileServerHtml)
    muxer.Handle("/css", fileServerCss)
    muxer.Handle("/js", fileServerJs)
    http.ListenAndServe(":8080", muxer)
}

httpメソッドの処理、クエリ文字列へのアクセス、本文のリクエスト

ここでは、APIの開発、リクエストのHTTPメソッドの区別、クエリ文字列値へのアクセス、リクエスト本文へのアクセスに関連する一般的なタスクの簡単な例を示します。

リソース

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

type customHandler struct{}

// ServeHTTP implements the http.Handler interface in the net/http package
func (h customHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

    // ParseForm will parse query string values and make r.Form available
    r.ParseForm()

    // r.Form is map of query string parameters
    // its' type is url.Values, which in turn is a map[string][]string
    queryMap := r.Form

    switch r.Method {
    case http.MethodGet:
        // Handle GET requests
        w.WriteHeader(http.StatusOK)
        w.Write([]byte(fmt.Sprintf("Query string values: %s", queryMap)))
        return
    case http.MethodPost:
        // Handle POST requests
        body, err := ioutil.ReadAll(r.Body)
        if err != nil {
            // Error occurred while parsing request body
            w.WriteHeader(http.StatusBadRequest)
            return
        }
        w.WriteHeader(http.StatusOK)
        w.Write([]byte(fmt.Sprintf("Query string values: %s\nBody posted: %s", queryMap, body)))
        return
    }

    // Other HTTP methods (eg PUT, PATCH, etc) are not handled by the above
    // so inform the client with appropriate status code
    w.WriteHeader(http.StatusMethodNotAllowed)
}

func main() {
    // All URLs will be handled by this function
    // http.Handle, similarly to http.HandleFunc
    // uses the DefaultServeMux
    http.Handle("/", customHandler{})

    // Continue to process new requests until an error occurs
    log.Fatal(http.ListenAndServe(":8080", nil))
}

サンプルカール出力:

$ curl -i 'localhost:8080?city=Seattle&state=WA' -H 'Content-Type: text/plain' -X GET
HTTP/1.1 200 OK
Date: Fri, 02 Sep 2016 16:36:24 GMT
Content-Length: 51
Content-Type: text/plain; charset=utf-8

Query string values: map[city:[Seattle] state:[WA]]%

$ curl -i 'localhost:8080?city=Seattle&state=WA' -H 'Content-Type: text/plain' -X POST -d "some post data"
HTTP/1.1 200 OK
Date: Fri, 02 Sep 2016 16:36:35 GMT
Content-Length: 79
Content-Type: text/plain; charset=utf-8

Query string values: map[city:[Seattle] state:[WA]]
Body posted: some post data%

$ curl -i 'localhost:8080?city=Seattle&state=WA' -H 'Content-Type: text/plain' -X PUT
HTTP/1.1 405 Method Not Allowed
Date: Fri, 02 Sep 2016 16:36:41 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow