nghttp2

package module
v0.0.0-...-d785811 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 26, 2018 License: LGPL-3.0 Imports: 17 Imported by: 0

README

nghttp2

nghttp2 is libnghttp2 binding for golang

see doc here

server usage example:

cert, err := tls.LoadX509KeyPair("testdata/server.crt", "testdata/server.key")
if err != nil {
	log.Fatal(err)
}

l, err := tls.Listen("tcp", "127.0.0.1:1100", &tls.Config{
	Certificates: []tls.Certificate{cert},
	NextProtos:   []string{"h2"},
})
if err != nil {
	log.Fatal(err)
}
defer l.Close()
addr := l.Addr().String()

http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
	f("%+v", r)
	hdr := w.Header()
	hdr.Set("content-type", "text/plain")
	hdr.Set("aa", "bb")
	d, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Println(err)
		return
	}
	w.Write(d)
})

for {
	c, err := l.Accept()
	if err != nil {
		break
	}
	h2conn, err := NewServerConn(c, nil)
	if err != nil {
		log.Fatal(err)
	}
	f("%+v", h2conn)
	go h2conn.Run()
}

client usage example:

conn, err := tls.Dial("tcp", "nghttp2.org:443", &tls.Config{
    NextProtos: []string{"h2"},
    ServerName: "nghttp2.org",
})
if err != nil {
    log.Fatal(err)
}
defer conn.Close()

cstate := conn.ConnectionState()
if cstate.NegotiatedProtocol != "h2" {
    log.Fatal("no http2 on server")
}

h2conn, err := NewClientConn(conn)
if err != nil {
    log.Fatal(err)
}

param := url.Values{}
param.Add("e", "b")
param.Add("f", "d")
data := bytes.NewReader([]byte(param.Encode()))
req, _ := http.NewRequest("POST",
    "https://nghttp2.org/httpbin/post?a=b&c=d",
    data)

log.Printf("%+v", req)

req.Header.Set("user-agent", "go-nghttp2/1.0")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

res, err := h2conn.CreateRequest(req)
if err != nil {
    log.Fatal(err)
}

if res.StatusCode != http.StatusOK {
    log.Printf("expect %d, got %d", http.StatusOK, res.StatusCode)
}
res.Write(os.Stderr)

co-work with net/http server example:

l, err := net.Listen("tcp", "127.0.0.1:1222")
if err != nil {
    log.Fatal(err)
}
srv := &http.Server{
    TLSConfig: &tls.Config{
        NextProtos: []string{"h2", "http/1.1"},
    },
    TLSNextProto: map[string]func(*http.Server, *tls.Conn, http.Handler){
        "h2": nghttp2.HTTP2Handler,
    },
}
defer srv.Close()

srv.ServeTLS(l, "testdata/server.crt", "testdata/server.key")

see http2_test.go for more details

Documentation

Overview

Package nghttp2 is libnghttp2 binding for golang.

server example

cert, err := tls.LoadX509KeyPair("testdata/server.crt", "testdata/server.key")
if err != nil {
	log.Fatal(err)
}

l, err := tls.Listen("tcp", "127.0.0.1:1100", &tls.Config{
	Certificates: []tls.Certificate{cert},
	NextProtos:   []string{"h2"},
})
if err != nil {
	log.Fatal(err)
}
defer l.Close()
addr := l.Addr().String()

http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
	log.Printf("%+v", r)
	hdr := w.Header()
	hdr.Set("content-type", "text/plain")
	hdr.Set("aa", "bb")
	d, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Println(err)
		return
	}
	w.Write(d)
})

for {
	c, err := l.Accept()
	if err != nil {
		break
	}
	h2conn, err := Server(c, nil)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("%+v", h2conn)
	go h2conn.Run()
}

client example

conn, err := tls.Dial("tcp", "nghttp2.org:443", &tls.Config{
    NextProtos: []string{"h2"},
    ServerName: "nghttp2.org",
})
if err != nil {
    log.Fatal(err)
}
defer conn.Close()
if err := conn.Handshake(); err != nil{
    log.Fatal(err)
}
cstate := conn.ConnectionState()
if cstate.NegotiatedProtocol != "h2" {
    log.Fatal("no http2 on server")
}

h2conn, err := Client(conn)
if err != nil {
    log.Fatal(err)
}

param := url.Values{}
param.Add("e", "b")
param.Add("f", "d")
data := bytes.NewReader([]byte(param.Encode()))
req, _ := http.NewRequest("POST",
    "https://nghttp2.org/httpbin/post?a=b&c=d",
    data)

log.Printf("%+v", req)

req.Header.Set("user-agent", "go-nghttp2/1.0")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

res, err := h2conn.RoundTrip(req)
if err != nil {
    log.Fatal(err)
}

if res.StatusCode != http.StatusOK {
    log.Printf("expect %d, got %d", http.StatusOK, res.StatusCode)
}
res.Write(os.Stderr)

co-work with net/http example

l, err := net.Listen("tcp", "127.0.0.1:1222")
if err != nil {
    log.Fatal(err)
}
srv := &http.Server{
    TLSConfig: &tls.Config{
        NextProtos: []string{"h2", "http/1.1"},
    },
    TLSNextProto: map[string]func(*http.Server, *tls.Conn, http.Handler){
        "h2": nghttp2.HTTP2Handler,
    },
}
defer srv.Close()

srv.ServeTLS(l, "testdata/server.crt", "testdata/server.key")

see http2_test.go for more details

Index

Constants

View Source
const (
	NGHTTP2_NO_ERROR                      = 0
	NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE = -521
	NGHTTP2_ERR_CALLBACK_FAILURE          = -902
	NGHTTP2_ERR_DEFERRED                  = -508
)

Variables

This section is empty.

Functions

func HTTP2Handler

func HTTP2Handler(srv *http.Server, conn *tls.Conn, handler http.Handler)

HTTP2Handler is the http2 server handler that can co-work with standard net/http.

usage example:

l, err := net.Listen("tcp", ":1222")
srv := &http.Server{
  TLSConfig: &tls.Config{
      NextProtos:[]string{"h2", "http/1.1"},
 }
 TLSNextProto: map[string]func(*http.Server, *tls.Conn, http.Handler){
     "h2": nghttp2.Http2Handler
   }
 }
srv.ServeTLS(l, "server.crt", "server.key")

Types

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn http2 connection

func Client

func Client(c net.Conn) (*Conn, error)

Client create client side http2 connection on c

c must be TLS connection and negotiated for h2

the Conn.Run have alread called, you should not call it again

func Dial

func Dial(network, addr string, cfg *tls.Config) (*Conn, error)

Dial connect to addr and create a http2 client Conn

the Conn.Run have already called, should not call it again

func Server

func Server(c net.Conn, handler http.Handler) (*Conn, error)

Server create server side http2 connection on c

c must be TLS connection and negotiated for h2

the Conn.Run not called, you must run it

func (*Conn) CanTakeNewRequest

func (c *Conn) CanTakeNewRequest() bool

CanTakeNewRequest check if conn can create new request

func (*Conn) Close

func (c *Conn) Close() error

Close close the connection

func (*Conn) Connect

func (c *Conn) Connect(addr string) (conn net.Conn, statusCode int, err error)

Connect submit connect request

like "CONNECT host:port" on http/1.1

statusCode is the http status code the server returned

c bounds to the remote host of addr

func (*Conn) Error

func (c *Conn) Error() error

Error return conn error

func (*Conn) RoundTrip

func (c *Conn) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip submit http request and return the response

func (*Conn) Run

func (c *Conn) Run()

Run run the event loop

type Transport

type Transport struct {
	TLSConfig *tls.Config
	DialTLS   func(network, addr string, cfg *tls.Config) (*tls.Conn, error)
	// contains filtered or unexported fields
}

Transport the nghttp2 RoundTripper implement

func (*Transport) RoundTrip

func (tr *Transport) RoundTrip(req *http.Request) (res *http.Response, err error)

RoundTrip send req and get res

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL