1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-elton

Клонировать/Скачать
http2_http3.md 8.5 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 04.06.2025 23:59 7f2703a
description
Поддержка HTTP2 и HTTP3

Большинство современных браузеров поддерживают HTTP2. Для поддержки HTTP2 на серверной стороне достаточно обновить версию Nginx и настроить конфигурацию. Модуль HTTP в GoLang уже поддерживает обработку HTTP2, поэтому далее будет рассмотрено, как использовать Elton для поддержки HTTP2.

Генерация сертификатов

Браузеры поддерживают использование HTTP2 только через HTTPS. Для удобства разработки можно сгенерировать сертификаты для разработки, используя mkcert. Для генерации сертификатов для нескольких доменов требуется всего несколько команд.

# Генерация сертификатов
mkcert me.dev localhost 127.0.0.1 ::1
# Установка сертификатов
mkcert -install

Запуск сервиса

Так как модуль HTTP в GoLang уже поддерживает HTTP2, достаточно запустить сервис через HTTPS.

package main

import (
	"bytes"

	"github.com/vicanso/elton"
)

func main() {
	e := elton.New()
	e.GET("/", func(c *elton.Context) error {
		c.BodyBuffer = bytes.NewBufferString("Hello, World!")
		return nil
	})

	certFile := "/tmp/me.dev+3.pem"
	keyFile := "/tmp/me.dev+3-key.pem"
	err := e.ListenAndServeTLS(":3000", certFile, keyFile)
	if err != nil {
		panic(err)
	}
}

В приведенном выше примере сертификаты хранятся в виде файлов. В реальных условиях сертификаты обычно хранятся централизованно и зашифрованы (например, в базе данных). В следующем примере показано, как инициализировать TLS с использованием []byte:

package main```markdown
## h2c

По умолчанию GoLang поддерживает HTTP2 только через HTTPS. Для внутренних системных вызовов, если требуется использовать HTTP2 через HTTP, можно использовать h2c. Ниже приведен пример кода, который показывает, как использовать h2c для использования HTTP2 через HTTP как на серверной, так и на клиентской стороне.

```go
package main

import (
	"crypto/tls"
	"fmt"
	"net"
	"net/http"
	"time"

	"github.com/vicanso/elton"
	"github.com/vicanso/elton/middleware"
	"golang.org/x/net/http2"
	"golang.org/x/net/http2/h2c"
)

var http2Client = &http.Client{
	// Принудительно использовать http2
	Transport: &http2.Transport{
		// Разрешить использование http-метода
		AllowHTTP: true,
		// Замена tls.Dial
		DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) {
			return net.Dial(network, addr)
		},
	},
}

func main() {
	go func() {
		time.Sleep(time.Second)
		resp, err := http2Client.Get("http://127.0.0.1:3000/")
		if err != nil {
			panic(err)
		}
		fmt.Println(resp.Proto)
	}()
}
package main

import (
	"bytes"
	"crypto/tls"
	"log"
	"net/http"
	"time"

	"github.com/lucas-clemente/quic-go/http3"
	"github.com/vicanso/elton"
)

const listenAddr = ":4000"

// Получение содержимого сертификата
func getCert() (cert []byte, key []byte, err error) {
	// Здесь просто чтение из файла, в реальном использовании сертификаты берутся из базы данных
	cert, err = os.ReadFile("/tmp/me.dev+3.pem")
	if err != nil {
		return
	}
	key, err = os.ReadFile("/tmp/me.dev+3-key.pem")
	if err != nil {
		return
	}
	return
}

func http3Get() {
	client := &http.Client{
		Transport: &http3.RoundTripper{},
	}
	resp, err := client.Get("https://127.0.0.1" + listenAddr + "/")
	if err != nil {
		log.Fatalln("http3 get fail ", err)
		return
	}
	log.Println("http3 get success", resp.Proto, resp.Status, resp.Header)
}
```

```
curl -v --http3-prior-knowledge http://127.0.0.1:4000/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 4000 (#0)
* Using HTTP3, server supports multi-use
* Connection state changed (HTTP/3 confirmed)
* Copying HTTP/3 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7f8d9a804600)
> GET / HTTP/3
> Host: 127.0.0.1:4000
> User-Agent: curl/7.54.0
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/3 200
```

## http3

http3 в настоящее время поддерживается только браузерами Chrome Canary и Firefox последней версии. Несмотря на то, что стандартный вариант http3 уже определен, следует учитывать, что модули http3 используются не так широко, и не рекомендуется использовать их в массовом порядке в рабочей среде. Ниже приведен пример использования http3 с использованием [quic-go](https://github.com/lucas-clemente/quic-go):

```go
package main

import (
	"bytes"
	"crypto/tls"
	"log"
	"net/http"
	"time"

	"github.com/lucas-clemente/quic-go/http3"
	"github.com/vicanso/elton"
)

const listenAddr = ":4000"

// Получение содержимого сертификата
func getCert() (cert []byte, key []byte, err error) {
	// Здесь просто чтение из файла, в реальном использовании сертификаты берутся из базы данных
	cert, err = os.ReadFile("/tmp/me.dev+3.pem")
	if err != nil {
		return
	}
	key, err = os.ReadFile("/tmp/me.dev+3-key.pem")
	if err != nil {
		return
	}
	return
}

func http3Get() {
	client := &http.Client{
		Transport: &http3.RoundTripper{},
	}
	resp, err := client.Get("https://127.0.0.1" + listenAddr + "/")
	if err != nil {
		log.Fatalln("http3 get fail ", err)
		return
	}
	log.Println("http3 get success", resp.Proto, resp.Status, resp.Header)
}
``````go
func main() {
	// Задержка в одну секунду перед выполнением запроса http3
	go func() {
		time.Sleep(time.Second)
		http3Get()
	}()

	e := elton.New()

	cert, key, err := getCert()
	if err != nil {
		panic(err)
	}
	// Инициализация конфигурации TLS и создание сертификата
	tlsConfig := &tls.Config{}
	tlsConfig.Certificates = make([]tls.Certificate, 1)
	tlsConfig.Certificates[0], err = tls.X509KeyPair(cert, key)
	if err != nil {
		panic(err)
	}
	e.Server.TLSConfig = tlsConfig.Clone()

	// Инициализация сервера http3
	http3Server := http3.Server{
		Server: &http.Server{
			Handler: e,
			Addr:    listenAddr,
		},
	}
	http3Server.TLSConfig = tlsConfig.Clone()

	e.Use(func(c *elton.Context) error {
		http3Server.SetQuicHeaders(c.Header())
		return c.Next()
	})

	e.GET("/", func(c *elton.Context) error {
		c.BodyBuffer = bytes.NewBufferString("hello " + c.Request.Proto + "!")
		return nil
	})

	go func() {
		// http3
		err := http3Server.ListenAndServe()
		if err != nil {
			panic(err)
		}
	}()

	// https
	err = e.ListenAndServeTLS(listenAddr, "", "")
	if err != nil {
		panic(err)
	}
}
```

Команду `curl` можно собрать самостоятельно, поддерживая протокол HTTP/3. Метод сборки описан в [документации curl](https://github.com/curl/curl/blob/master/docs/HTTP3.md). Ниже приведен пример использования `curl`:

```
curl --http3 'https://me.dev:4000/' -v
*   Trying 127.0.0.1:4000...
* Sent QUIC client Initial, ALPN: h3-24h3-23
* h3 [:method: GET]
* h3 [:path: /]
* h3 [:scheme: https]
* h3 [:authority: me.dev:4000]
* h3 [user-agent: curl/7.68.0-DEV]
* h3 [accept: */*]
* Using HTTP/3 Stream ID: 0 (easy handle 0x7fad4f011e00)
> GET / HTTP/3
> Host: me.dev:4000
> user-agent: curl/7.68.0-DEV
> accept: */*
>
< HTTP/3 200
< content-length: 13
< alt-srv: h3-24=":4000"; ma=86400
<
* Connection #0 to host me.dev left intact
hello HTTP/3!
```

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors-elton.git
git@api.gitlife.ru:oschina-mirror/mirrors-elton.git
oschina-mirror
mirrors-elton
mirrors-elton
master