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 )