Ini merupakan implementasi dari Hypertext Transfer Protocol versi 2 di C.
Lapisan pembingkaian HTTP/2 diimplementasikan sebagai pustaka C yang dapat digunakan kembali. Selain itu, kami telah mengimplementasikan klien, server, dan proxy HTTP/2. Kami juga telah mengembangkan alat uji beban dan benchmarking untuk HTTP/2.
Encoder dan decoder HPACK tersedia sebagai API publik.
nghttp2 awalnya dikembangkan berdasarkan RFC 7540 HTTP/2 dan RFC 7541 HPACK - Kompresi Header untuk HTTP/2. Sekarang kami memperbarui kode kami untuk mengimplementasikan RFC 9113.
Basis kode nghttp2 diambil dari proyek spdylay (https://github.com/tatsuhiro-t/spdylay).
Titik akhir berikut tersedia untuk mencoba implementasi nghttp2 kami.
https://nghttp2.org/ (TLS + ALPN dan HTTP/3)
Titik akhir ini mendukung h2
, h2-16
, h2-14
, dan http/1.1
melalui ALPN dan memerlukan TLSv1.2 untuk koneksi HTTP/2.
Ini juga mendukung HTTP/3.
http://nghttp2.org/ (Peningkatan HTTP dan HTTP/2 Langsung)
h2c
dan http/1.1
.
Paket berikut diperlukan untuk membangun perpustakaan libnghttp2:
Untuk membuat dokumentasi, Anda perlu menginstal:
Jika Anda hanya memerlukan libnghttp2 (perpustakaan C), maka hanya paket di atas yang Anda perlukan. Gunakan --enable-lib-only
untuk memastikan bahwa hanya libnghttp2 yang dibuat. Hal ini untuk menghindari potensi kesalahan build terkait dengan pembuatan aplikasi yang dibundel.
Untuk membangun dan menjalankan program aplikasi ( nghttp
, nghttpd
, nghttpx
dan h2load
) di direktori src
, diperlukan paket-paket berikut:
Untuk mengaktifkan opsi -a
(mendapatkan aset tertaut dari sumber daya yang diunduh) di nghttp
, diperlukan paket berikut:
Untuk mengaktifkan dukungan systemd di nghttpx, diperlukan paket berikut:
Alat HPACK memerlukan paket berikut:
Untuk membangun sumber di bawah direktori contoh, libevent diperlukan:
Untuk mengurangi fragmentasi heap dalam program server yang berjalan lama ( nghttpd
dan nghttpx
), jemalloc disarankan:
jemaloc
Catatan
Alpine Linux saat ini tidak mendukung penggantian malloc karena keterbatasan musl. Lihat detailnya di edisi #762.
Untuk BoringSSL atau aws-lc build, untuk mengaktifkan Kompresi Sertifikat RFC 8879 TLS dalam aplikasi, diperlukan pustaka berikut:
Untuk mengaktifkan dukungan mruby untuk nghttpx, diperlukan mruby. Kita perlu membangun mruby dengan C++ ABI diaktifkan secara eksplisit, dan mungkin memerlukan mrgem lain, mruby dikelola oleh submodul git di bawah direktori pihak ketiga/mruby. Saat ini, dukungan mruby untuk nghttpx dinonaktifkan secara default. Untuk mengaktifkan dukungan mruby, gunakan opsi konfigurasi --with-mruby
. Perhatikan bahwa pada saat penulisan ini, paket libmruby-dev dan mruby di Debian/Ubuntu tidak dapat digunakan untuk nghttp2, karena paket tersebut tidak mengaktifkan C++ ABI. Untuk membangun mruby, diperlukan paket-paket berikut:
nghttpx mendukung mesin pemisahan hak istimewa yang tidak pernah ada untuk OpenSSL. Singkatnya, ini meminimalkan risiko kebocoran kunci pribadi ketika bug serius seperti Heartbleed dieksploitasi. Neverbleed dinonaktifkan secara default. Untuk mengaktifkannya, gunakan opsi konfigurasi --with-neverbleed
.
Untuk mengaktifkan dukungan HTTP/3 eksperimental untuk h2load dan nghttpx, diperlukan pustaka berikut:
Gunakan opsi konfigurasi --enable-http3
untuk mengaktifkan fitur HTTP/3 untuk h2load dan nghttpx.
Untuk membangun program eBPF opsional untuk mengarahkan datagram QUIC UDP yang masuk ke soket yang benar untuk nghttpx, diperlukan pustaka berikut:
Gunakan opsi konfigurasi --with-libbpf
untuk membuat program eBPF. libelf-dev diperlukan untuk membangun libbpf.
Untuk Ubuntu 20.04, Anda dapat membuat libbpf dari kode sumber. nghttpx memerlukan program eBPF untuk memuat ulang konfigurasinya dan hot swapping yang dapat dieksekusi.
Mengkompilasi kode sumber libnghttp2 C memerlukan kompiler C99. gcc 4.8 diketahui memadai. Untuk mengkompilasi kode sumber C++, diperlukan kompiler yang sesuai dengan C++20. Setidaknya g++ >= 12 dan clang++ >= 15 diketahui berfungsi.
Catatan
Untuk mengaktifkan dukungan mruby di nghttpx, dan gunakan opsi konfigurasi --with-mruby
.
Catatan
Pengguna Mac OS X mungkin memerlukan opsi konfigurasi --disable-threads
untuk menonaktifkan multi-threading di nghttpd, nghttpx, dan h2load untuk mencegahnya mogok. Sebuah patch dipersilakan untuk membuat multi threading berfungsi pada platform Mac OS X.
Catatan
Untuk mengkompilasi aplikasi terkait (nghttp, nghttpd, nghttpx dan h2load), Anda harus menggunakan opsi konfigurasi --enable-app
dan memastikan bahwa persyaratan yang ditentukan di atas terpenuhi. Biasanya, konfigurasikan pemeriksaan skrip yang memerlukan dependensi untuk membangun aplikasi ini, dan aktifkan --enable-app
secara otomatis, sehingga Anda tidak perlu menggunakannya secara eksplisit. Namun jika Anda menemukan bahwa aplikasi tidak dibuat, maka penggunaan --enable-app
dapat menemukan penyebabnya, seperti hilangnya ketergantungan.
Catatan
Untuk mendeteksi perpustakaan pihak ketiga, pkg-config digunakan (namun kami tidak menggunakan pkg-config untuk beberapa perpustakaan (misalnya, libev)). Secara default, pkg-config mencari file *.pc
di lokasi standar (misalnya, /usr/lib/pkgconfig). Jika perlu menggunakan file *.pc
di lokasi khusus, tentukan jalur ke variabel lingkungan PKG_CONFIG_PATH
, dan teruskan ke skrip konfigurasi, seperti:
$ ./configure PKG_CONFIG_PATH=/path/ke/pkgconfig
Untuk pustaka terkelola pkg-config, variabel lingkungan *_CFLAG
dan *_LIBS
ditentukan (misalnya, OPENSSL_CFLAGS
, OPENSSL_LIBS
). Menentukan string yang tidak kosong ke variabel-variabel ini sepenuhnya mengesampingkan pkg-config. Dengan kata lain, jika ditentukan, pkg-config tidak digunakan untuk deteksi, dan pengguna bertanggung jawab untuk menentukan nilai yang benar untuk variabel-variabel ini. Untuk daftar lengkap variabel-variabel ini, jalankan ./configure -h
.
Jika Anda menggunakan Ubuntu 22.04 LTS, jalankan perintah berikut untuk menginstal paket yang diperlukan:
sudo apt-get install g++ dentang make binutils autoconf automake
autotools-dev libtool pkg-config
zlib1g-dev libssl-dev libxml2-dev libev-dev
libevent-dev libjansson-dev
libc-ares-dev libjemalloc-dev libsystemd-dev
ruby-dev bison libelf-dev
Proyek nghttp2 secara teratur merilis arsip tar yang mencakup kode sumber nghttp2, dan file build yang dihasilkan. Mereka dapat diunduh dari halaman Rilis.
Membangun nghttp2 dari git memerlukan paket pengembangan autotools. Membangun dari arsip tar tidak memerlukannya, sehingga jauh lebih mudah. Langkah pembuatan yang biasa dilakukan adalah sebagai berikut:
$ tar xf nghttp2-XYZtar.bz2
$cdnghttp2-XYZ
$ ./konfigurasi
$ membuat
Membangun dari git itu mudah, tapi pastikan setidaknya autoconf 2.68 digunakan:
$ git pembaruan submodul --init
$autoreconf -i
$ pembuatan otomatis
$konferensi otomatis
$ ./konfigurasi
$ membuat
Cara termudah untuk membangun Windows asli nghttp2 dll adalah menggunakan cmake. Versi gratis dari Visual C++ Build Tools berfungsi dengan baik.
cmake
.cmake --build
untuk membangun perpustakaan.Perhatikan bahwa langkah di atas kemungkinan besar hanya menghasilkan perpustakaan nghttp2 saja. Tidak ada aplikasi yang dibundel yang dikompilasi.
Di bawah lingkungan Mingw, Anda hanya dapat mengkompilasi perpustakaan, yaitu libnghttp2-X.dll
dan libnghttp2.a
.
Jika Anda ingin mengkompilasi aplikasi ( h2load
, nghttp
, nghttpx
, nghttpd
), Anda perlu menggunakan lingkungan Cygwin.
Di bawah lingkungan Cygwin, untuk mengkompilasi aplikasi Anda perlu mengkompilasi dan menginstal libev terlebih dahulu.
Kedua, Anda perlu membatalkan definisi makro __STRICT_ANSI__
, jika tidak, fungsi fdopen
, fileno
dan strptime
tidak akan tersedia.
contoh perintahnya seperti ini:
$ ekspor CFLAGS="-U__STRICT_ANSI__ -I$libev_PREFIX/termasuk -L$libev_PREFIX/lib"
$ ekspor CXXFLAGS=$CFLAGS
$ ./konfigurasi
$ membuat
Jika Anda ingin mengkompilasi aplikasi di bawah examples/
, Anda perlu menghapus atau mengganti nama event.h
dari instalasi libev, karena bertentangan dengan instalasi libevent.
Setelah menginstal rangkaian alat nghttp2 dengan make install
seseorang mungkin mengalami kesalahan serupa:
nghttpx: kesalahan saat memuat perpustakaan bersama: libnghttp2.so.14: tidak dapat membuka file objek bersama: Tidak ada file atau direktori seperti itu
Ini berarti alat tersebut tidak dapat menemukan perpustakaan bersama libnghttp2.so
.
Untuk memperbarui cache perpustakaan bersama, jalankan sudo ldconfig
.
Catatan
Dokumentasi masih belum lengkap.
Untuk membuat dokumentasi, jalankan:
$ membuat html
Dokumen akan dibuat di bawah doc/manual/html/
.
Dokumen yang dihasilkan tidak akan diinstal dengan make install
.
Dokumentasi online tersedia di https://nghttp2.org/documentation/
Untuk membangun h2load dan nghttpx dengan fitur HTTP/3 diaktifkan, jalankan skrip konfigurasi dengan --enable-http3
.
Agar nghttpx dapat memuat ulang konfigurasi dan menukar file yang dapat dieksekusi sambil menghentikan proses pekerja lama dengan baik, diperlukan eBPF. Jalankan skrip konfigurasi dengan --enable-http3 --with-libbpf
untuk membuat program eBPF. Materi kunci QUIC harus disetel dengan --frontend-quic-secret-file
untuk menjaga koneksi yang ada tetap hidup selama memuat ulang.
Ikuti langkah-langkah mendetail untuk membuat h2load dan nghttpx yang mengaktifkan HTTP/3.
Bangun aws-lc:
$ git clone --kedalaman 1 -b v1.39.0 https://github.com/aws/aws-lc
$ cd aws-lc
$ cmake -B build -DDISABLE_GO=ON --install-prefix=$PWD/opt
$ membuat -j$(nproc) -C membangun
$ cmake --instal build
$cd..
Bangun nghttp3:
$ git clone --kedalaman 1 -b v1.6.0 https://github.com/ngtcp2/nghttp3
$cdnghttp3
$ git pembaruan submodul --init --kedalaman 1
$autoreconf -i
$ ./configure --prefix=$PWD/build --enable-lib-only
$ membuat -j$(nproc)
$ buat instal
$cd..
Bangun ngtcp2:
$ git clone --kedalaman 1 -b v1.9.1 https://github.com/ngtcp2/ngtcp2
$cdngtcp2
$ git pembaruan submodul --init --kedalaman 1
$autoreconf -i
$ ./configure --prefix=$PWD/build --enable-lib-only --with-boringssl
BORINGSSL_CFLAGS="-I$PWD/../aws-lc/opt/include"
BORINGSSL_LIBS="-L$PWD/../aws-lc/opt/lib -lssl -lcrypto"
$ membuat -j$(nproc)
$ buat instal
$cd..
Jika distribusi Linux Anda tidak memiliki libbpf-dev >= 0.7.0, buatlah dari sumber:
$ git clone --kedalaman 1 -b v1.4.6 https://github.com/libbpf/libbpf
$cd libbpf
$ PREFIX=$PWD/build make -C src instal
$cd..
Bangun nghttp2:
$ git klon https://github.com/nghttp2/nghttp2
$cdnghttp2
$ git pembaruan submodul --init
$autoreconf -i
$ ./configure --with-mruby --enable-http3 --with-libbpf
CC=dentang-15 CXX=dentang++-15
PKG_CONFIG_PATH="$PWD/../aws-lc/opt/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig:$PWD/../ngtcp2/build/lib/pkgconfig:$PWD/ ../libbpf/build/lib64/pkgconfig"
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/../aws-lc/opt/lib -Wl,-rpath,$PWD/../libbpf/build/lib64"
$ membuat -j$(nproc)
Program eBPF reuseport_kern.o
dapat ditemukan di direktori bpf. Berikan opsi --quic-bpf-program-file=bpf/reuseport_kern.o
ke nghttpx untuk memuatnya. Lihat juga bagian HTTP/3 di nghttpx - Proksi HTTP/2 - CARANYA.
Tes unit dilakukan hanya dengan menjalankan make check
.
Kami memiliki tes integrasi untuk server proxy nghttpx. Tes ditulis dalam bahasa pemrograman Go dan menggunakan kerangka pengujiannya. Kami bergantung pada perpustakaan berikut:
Modul Go akan mengunduh dependensi ini secara otomatis.
Untuk menjalankan pengujian, jalankan perintah berikut di bawah direktori integration-tests
:
$ buatlah
Di dalam pengujian, kami menggunakan port 3009 untuk menjalankan server subjek pengujian.
nghttp2 v1.0.0 memperkenalkan beberapa perubahan yang tidak kompatibel. Di bagian ini, kami menjelaskan perubahan ini dan cara bermigrasi ke v1.0.0.
h2
dan h2c
Sebelumnya kami mengumumkan h2-14
dan h2c-14
. v1.0.0 mengimplementasikan versi protokol final, dan kami mengubah ID ALPN menjadi h2
dan h2c
. Makro NGHTTP2_PROTO_VERSION_ID
, NGHTTP2_PROTO_VERSION_ID_LEN
, NGHTTP2_CLEARTEXT_PROTO_VERSION_ID
, dan NGHTTP2_CLEARTEXT_PROTO_VERSION_ID_LEN
telah diperbarui untuk mencerminkan perubahan ini.
Pada dasarnya aplikasi yang sudah ada tidak perlu melakukan apapun, cukup melakukan kompilasi ulang saja untuk perubahan ini.
Kami menggunakan "kata pengantar koneksi klien" yang berarti 24 byte pertama kata pengantar koneksi klien. Ini secara teknis tidak benar, karena kata pengantar koneksi klien terdiri dari 24 byte string byte ajaib klien diikuti dengan bingkai SETTINGS. Untuk klarifikasi, kami menyebut "klien ajaib" untuk string byte 24 byte ini dan API yang diperbarui.
NGHTTP2_CLIENT_CONNECTION_PREFACE
diganti dengan NGHTTP2_CLIENT_MAGIC
.NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN
diganti dengan NGHTTP2_CLIENT_MAGIC_LEN
.NGHTTP2_BAD_PREFACE
diubah namanya menjadi NGHTTP2_BAD_CLIENT_MAGIC
NGHTTP2_CLIENT_CONNECTION_HEADER
dan NGHTTP2_CLIENT_CONNECTION_HEADER_LEN
yang sudah tidak digunakan lagi telah dihapus.
Jika aplikasi menggunakan makro tersebut, ganti saja yang lama dengan yang baru. Sejak v1.0.0, keajaiban klien dikirim oleh perpustakaan (lihat subbagian berikutnya), jadi aplikasi klien mungkin menghapus penggunaan makro ini.
Sebelumnya perpustakaan nghttp2 tidak mengirimkan sihir klien, yang merupakan string 24 byte pertama dari kata pengantar koneksi klien, dan aplikasi klien harus mengirimkannya sendiri. Sejak v1.0.0, keajaiban klien dikirim oleh perpustakaan melalui panggilan pertama nghttp2_session_send()
atau nghttp2_session_mem_send2()
.
Aplikasi klien yang mengirimkan keajaiban klien harus menghapus kode yang relevan.
Spesifikasi Alt-Svc belum selesai. Untuk membuat API kami stabil, kami memutuskan untuk menghapus semua API terkait Alt-Svc dari nghttp2.
NGHTTP2_EXT_ALTSVC
telah dihapus.nghttp2_ext_altsvc
telah dihapus.Kami telah menghapus fungsi Alt-Svc di seri v0.7 dan pada dasarnya fungsi tersebut adalah noop. Aplikasi yang menggunakan makro dan struct ini, hapus baris-baris itu.
Sebelumnya nghttp2_on_invalid_frame_recv_cb_called
mengambil error_code
, yang didefinisikan dalam nghttp2_error_code
, sebagai parameter. Namun mereka tidak cukup detail untuk di-debug. Oleh karena itu, kami memutuskan untuk menggunakan nilai nghttp2_error
yang lebih detail.
Aplikasi yang menggunakan panggilan balik ini harus memperbarui tanda tangan panggilan balik. Jika ia memperlakukan error_code
sebagai kode kesalahan HTTP/2, perbarui kode tersebut sehingga diperlakukan sebagai nghttp2_error
.
Sebelumnya nghttp2 tidak memproses sihir klien (string byte 24 byte). Untuk mengatasinya, kami harus menggunakan nghttp2_option_set_recv_client_preface()
. Sejak v1.0.0, nghttp2 memproses keajaiban klien secara default dan nghttp2_option_set_recv_client_preface()
telah dihapus.
Beberapa aplikasi mungkin ingin menonaktifkan perilaku ini, jadi kami menambahkan nghttp2_option_set_no_recv_client_magic()
untuk mencapai hal ini.
Aplikasi menggunakan nghttp2_option_set_recv_client_preface()
dengan nilai bukan nol, hapus saja.
Aplikasi yang menggunakan nghttp2_option_set_recv_client_preface()
dengan nilai nol atau tidak menggunakannya harus menggunakan nghttp2_option_set_no_recv_client_magic()
dengan nilai bukan nol.
Direktori src
berisi program klien, server, dan proxy HTTP/2.
nghttp
adalah klien HTTP/2. Itu dapat terhubung ke server HTTP/2 dengan pengetahuan sebelumnya, Peningkatan HTTP dan ekstensi ALPN TLS.
Ini memiliki mode keluaran verbose untuk membingkai informasi. Berikut ini contoh keluaran dari klien nghttp
:
$nghttp-nvhttps://nghttp2.org
[0.190] Terhubung
Protokol yang dinegosiasikan: h2
[ 0.212] PENGATURAN penerimaan bingkai
(niv=2)
[SETTINGS_MAX_CONCURRENT_STRREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[ 0.212] kirim SETTINGS bingkai
(niv=2)
[SETTINGS_MAX_CONCURRENT_STRREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[ 0.212] kirim bingkai SETTINGS
; ACK
(niv=0)
[ 0.212] kirim bingkai PRIORITAS
(dep_stream_id=0, bobot=201, eksklusif=0)
[ 0.212] kirim bingkai PRIORITAS
(dep_stream_id=0, bobot=101, eksklusif=0)
[ 0.212] kirim bingkai PRIORITAS
(dep_stream_id=0, bobot=1, eksklusif=0)
[ 0.212] kirim bingkai PRIORITAS
(dep_stream_id=7, bobot=1, eksklusif=0)
[ 0.212] kirim bingkai PRIORITAS
(dep_stream_id=3, bobot=1, eksklusif=0)
[ 0,212] kirim bingkai HEADERS
; END_STREAM | END_HEADERS | PRIORITAS
(padlen=0, dep_stream_id=11, bobot=16, eksklusif=0)
; Buka aliran baru
:metode: DAPATKAN
:jalur: /
:skema: https
:otoritas: nghttp2.org
menerima: */*
menerima pengkodean: gzip, mengempis
agen pengguna: nghttp2/1.0.1-DEV
[ 0.221] PENGATURAN penerimaan bingkai
; ACK
(niv=0)
[ 0.221] penerimaan (stream_id=13) :metode: DAPATKAN
[ 0.221] penerimaan (stream_id=13) :skema: https
[ 0.221] penerimaan (stream_id=13):jalur: /stylesheets/screen.css
[ 0.221] penerimaan (stream_id=13): otoritas: nghttp2.org
[ 0.221] recv (stream_id=13) menerima pengkodean: gzip, mengempis
[ 0.222] penerimaan (stream_id=13) agen pengguna: nghttp2/1.0.1-DEV
[ 0,222] menerima bingkai PUSH_PROMISE
; END_HEADERS
(padlen=0, janji_stream_id=2)
[ 0.222] penerimaan (stream_id=13) :status: 200
[ 0.222] penerimaan (stream_id=13) tanggal: Kam, 21 Mei 2015 16:38:14 GMT
[ 0.222] recv (stream_id=13) tipe konten: teks/html
[ 0.222] recv (stream_id=13) terakhir diubah: Jum, 15 Mei 2015 15:38:06 GMT
[ 0.222] penerimaan (stream_id=13) etag: W/"555612de-19f6"
[ 0.222] tautan penerimaan (stream_id=13): ; rel=pramuat; sebagai=lembar gaya
[ 0.222] recv (stream_id=13) pengkodean konten: gzip
[ 0.222] server penerimaan (stream_id=13): nghttpx nghttp2/1.0.1-DEV
[ 0.222] penerimaan (stream_id=13) melalui: 1.1 nghttpx
[ 0.222] penerimaan (stream_id=13) keamanan transportasi ketat: max-age=31536000
[ 0.222] menerima bingkai HEADERS
; END_HEADERS
(padlen=0)
; Header respons pertama
[ 0,222] menerima bingkai DATA
; END_STREAM
[ 0.222] penerimaan (stream_id=2) :status: 200
[ 0.222] penerimaan (stream_id=2) tanggal: Kam, 21 Mei 2015 16:38:14 GMT
[ 0.222] recv (stream_id=2) tipe konten: teks/css
[ 0.222] recv (stream_id=2) terakhir diubah: Jum, 15 Mei 2015 15:38:06 GMT
[ 0.222] penerimaan (stream_id=2) etag: W/"555612de-9845"
[ 0.222] recv (stream_id=2) pengkodean konten: gzip
[ 0.222] server penerimaan (stream_id=2): nghttpx nghttp2/1.0.1-DEV
[ 0.222] penerimaan (stream_id=2) melalui: 1.1 nghttpx
[ 0.222] penerimaan (stream_id=2) keamanan transportasi ketat: max-age=31536000
[ 0.222] menerima bingkai HEADERS
; END_HEADERS
(padlen=0)
; Header respons push pertama
[ 0,228] menerima bingkai DATA
; END_STREAM
[ 0,228] kirim bingkai GOAWAY
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
Peningkatan HTTP dilakukan seperti ini:
$nghttp -nvu http://nghttp2.org
[0,011] Terhubung
[ 0,011] Permintaan Peningkatan HTTP
DAPATKAN / HTTP/1.1
Tuan rumah: nghttp2.org
Koneksi: Peningkatan, Pengaturan HTTP2
Peningkatan: h2c
Pengaturan HTTP2: AAMAAABkAAQAAP__
Menerima: */*
Agen-Pengguna: nghttp2/1.0.1-DEV
[0,018] Respons Peningkatan HTTP
HTTP/1.1 101 Protokol Pengalihan
Koneksi: Tingkatkan
Peningkatan: h2c
[0,018] Peningkatan HTTP berhasil
[ 0,018] PENGATURAN penerimaan bingkai
(niv=2)
[SETTINGS_MAX_CONCURRENT_STRREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[ 0,018] kirim bingkai SETTINGS
(niv=2)
[SETTINGS_MAX_CONCURRENT_STRREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[ 0,018] kirim bingkai SETTINGS
; ACK
(niv=0)
[ 0,018] kirim bingkai PRIORITAS
(dep_stream_id=0, bobot=201, eksklusif=0)
[ 0,018] kirim bingkai PRIORITAS
(dep_stream_id=0, bobot=101, eksklusif=0)
[ 0,018] kirim bingkai PRIORITAS
(dep_stream_id=0, bobot=1, eksklusif=0)
[ 0,018] kirim bingkai PRIORITAS
(dep_stream_id=7, bobot=1, eksklusif=0)
[ 0,018] kirim bingkai PRIORITAS
(dep_stream_id=3, bobot=1, eksklusif=0)
[ 0,018] kirim bingkai PRIORITAS
(dep_stream_id=11, bobot=16, eksklusif=0)
[ 0,019] penerimaan (stream_id=1) :metode: DAPATKAN
[ 0,019] penerimaan (stream_id=1) :skema: http
[ 0,019] penerimaan (stream_id=1):jalur: /stylesheets/screen.css
[ 0,019] penerimaan (stream_id=1) host: nghttp2.org
[ 0,019] recv (stream_id=1) agen pengguna: nghttp2/1.0.1-DEV
[ 0,019] menerima bingkai PUSH_PROMISE
; END_HEADERS
(padlen=0, janji_stream_id=2)
[ 0,019] penerimaan (stream_id=1) :status: 200
[ 0.019] penerimaan (stream_id=1) tanggal: Kam, 21 Mei 2015 16:39:16 GMT
[ 0,019] recv (stream_id=1) tipe konten: teks/html
[ 0,019] recv (stream_id=1) panjang konten: 6646
[ 0.019] recv (stream_id=1) terakhir diubah: Jum, 15 Mei 2015 15:38:06 GMT
[ 0,019] penerimaan (stream_id=1) etag: "555612de-19f6"
[ 0,019] tautan penerimaan (stream_id=1): ; rel=pramuat; sebagai=lembar gaya
[ 0,019] recv (stream_id=1) rentang penerimaan: byte
[ 0,019] server penerimaan (stream_id=1): nghttpx nghttp2/1.0.1-DEV
[ 0.019] penerimaan (stream_id=1) melalui: 1.1 nghttpx
[ 0,019] menerima bingkai HEADERS
; END_HEADERS
(padlen=0)
; Header respons pertama
[ 0,019] menerima bingkai DATA
; END_STREAM
[ 0,019] penerimaan (stream_id=2) :status: 200
[ 0.019] penerimaan (stream_id=2) tanggal: Kam, 21 Mei 2015 16:39:16 GMT
[ 0,019] recv (stream_id=2) tipe konten: teks/css
[ 0,019] recv (stream_id=2) panjang konten: 38981
[ 0.019] recv (stream_id=2) terakhir diubah: Jum, 15 Mei 2015 15:38:06 GMT
[ 0,019] penerimaan (stream_id=2) etag: "555612de-9845"
[ 0,019] recv (stream_id=2) rentang penerimaan: byte
[ 0,019] server penerimaan (stream_id=2): nghttpx nghttp2/1.0.1-DEV
[ 0.019] penerimaan (stream_id=2) melalui: 1.1 nghttpx
[ 0,019] menerima bingkai HEADERS
; END_HEADERS
(padlen=0)
; Header respons push pertama
[ 0,026] menerima bingkai DATA
[ 0,027] menerima bingkai DATA
[ 0,027] kirim bingkai WINDOW_UPDATE
(jendela_ukuran_kenaikan=33343)
[ 0,032] kirim bingkai WINDOW_UPDATE
(jendela_ukuran_kenaikan=33707)
[ 0,032] menerima bingkai DATA
; END_STREAM
[ 0,032] PENGATURAN penerimaan bingkai
; ACK
(niv=0)
[ 0,032] kirim bingkai GOAWAY
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
Menggunakan opsi -s
, nghttp
mencetak beberapa informasi waktu untuk permintaan, diurutkan berdasarkan waktu penyelesaian:
$nghttp -nas https://nghttp2.org/
***** Statistik *****
Waktu permintaan:
responEnd: waktu ketika byte terakhir respons diterima
relatif terhadap connectEnd
requestStart: waktu sebelum byte pertama permintaan dikirim
relatif terhadap connectEnd. Jika '*' ditampilkan, ini adalah
didorong oleh server.
proses: responEnd - permintaanMulai
kode: kode status HTTP
ukuran: jumlah byte yang diterima sebagai badan respons tanpa
inflasi.
URI: minta URI
lihat http://www.w3.org/TR/resource-timing/#processing-model
diurutkan berdasarkan 'lengkap'
id responEnd requestMulai jalur permintaan ukuran kode proses
13 +37,19 md +280us 36,91 md 200 2K /
2 +72,65 md * +36,38 md 36,26 md 200 8K /stylesheets/screen.css
17 +77,43 md +38,67 md 38,75 md 200 3K /javascripts/octopress.js
15 +78,12 md +38,66 md 39,46 md 200 3K /javascripts/modernizr-2.0.js
Menggunakan opsi -r
, nghttp
menulis data waktu yang lebih detail ke file tertentu dalam format HAR.
nghttpd
adalah server web statis multi-utas.
Secara default, ini menggunakan koneksi SSL/TLS. Gunakan opsi --no-tls
untuk menonaktifkannya.
nghttpd
hanya menerima koneksi HTTP/2 melalui ALPN atau koneksi HTTP/2 langsung. Tidak ada Peningkatan HTTP yang didukung.
Opsi -p
memungkinkan pengguna untuk mengonfigurasi server push.
Sama seperti nghttp
, ia memiliki mode keluaran verbose untuk membingkai informasi. Berikut ini contoh keluaran dari nghttpd
:
$nghttpd --tidak-tls -v 8080
IPv4: dengarkan 0.0.0.0:8080
IPv6: dengarkan :::8080
[id=1] [ 1.521] kirim SETTINGS frame
(niv=1)
[SETTINGS_MAX_CONCURRENT_STRREAMS(0x03):100]
[id=1] [ 1.521] recv SETTINGS bingkai
(niv=2)
[SETTINGS_MAX_CONCURRENT_STRREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[id=1] [ 1.521] recv SETTINGS bingkai
; ACK
(niv=0)
[id=1] [ 1.521] menerima bingkai PRIORITAS
(dep_stream_id=0, bobot=201, eksklusif=0)
[id=1] [ 1.521] menerima bingkai PRIORITAS
(dep_stream_id=0, bobot=101, eksklusif=0)
[id=1] [ 1.521] menerima bingkai PRIORITAS
(dep_stream_id=0, bobot=1, eksklusif=0)
[id=1] [ 1.521] menerima bingkai PRIORITAS
(dep_stream_id=7, bobot=1, eksklusif=0)
[id=1] [ 1.521] menerima bingkai PRIORITAS
(dep_stream_id=3, bobot=1, eksklusif=0)
[id=1] [ 1.521] penerimaan (stream_id=13) :metode: DAPATKAN
[id=1] [ 1.521] penerimaan (stream_id=13) :jalur: /
[id=1] [ 1.521] penerimaan (stream_id=13):skema: http
[id=1] [ 1.521] penerimaan (stream_id=13) :otoritas: localhost:8080
[id=1] [ 1.521] penerimaan (stream_id=13) diterima: */*
[id=1] [ 1.521] recv (stream_id=13) menerima pengkodean: gzip, mengempis
[id=1] [ 1.521] penerimaan (stream_id=13) agen pengguna: nghttp2/1.0.0-DEV
[id=1] [ 1.521] menerima bingkai HEADERS
; END_STREAM | END_HEADERS | PRIORITAS
(padlen=0, dep_stream_id=11, bobot=16, eksklusif=0)
; Buka aliran baru
[id=1] [ 1.521] kirim SETTINGS frame
; ACK
(niv=0)
[id=1] [ 1.521] kirim bingkai HEADERS
; END_HEADERS
(padlen=0)
; Header respons pertama
:status: 200
server: nghttpd nghttp2/1.0.0-DEV
panjang konten: 10
kontrol cache: usia maks=3600
tanggal: Jum, 15 Mei 2015 14:49:04 GMT
terakhir diubah: Sel, 30 Sep 2014 12:40:52 GMT
[id=1] [ 1.522] kirim bingkai DATA
; END_STREAM
[id=1] [ 1.522] stream_id=13 ditutup
[id=1] [ 1.522] menerima bingkai GOAWAY
(last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])
[id=1] [ 1.522] ditutup
nghttpx
adalah proksi terbalik multi-utas untuk HTTP/3, HTTP/2, dan HTTP/1.1, dan mendukung http://nghttp2.org dan mendukung server push HTTP/2.
Kami mengerjakan ulang antarmuka baris perintah nghttpx
, dan sebagai hasilnya, ada beberapa yang tidak kompatibel dari versi 1.8.0 atau lebih lama. Hal ini diperlukan untuk memperluas kemampuannya, dan mengamankan peningkatan fitur lebih lanjut di rilis mendatang. Silakan baca Migrasi dari nghttpx v1.8.0 atau versi lebih lama untuk mengetahui cara melakukan migrasi dari rilis sebelumnya.
nghttpx
mengimplementasikan fitur-fitur penting yang berorientasi pada kinerja di TLS, seperti ID sesi, tiket sesi (dengan rotasi kunci otomatis), stapel OCSP, ukuran catatan dinamis, ALPN, kerahasiaan penerusan, dan HTTP/2. nghttpx
juga menawarkan fungsionalitas untuk berbagi cache sesi dan kunci tiket di antara beberapa instance nghttpx
melalui memcached.
nghttpx
memiliki 2 mode operasi:
Pilihan modus | Bagian depan | Bagian belakang | Catatan |
---|---|---|---|
modus bawaan | HTTP/3, HTTP/2, HTTP/1.1 | HTTP/1.1, HTTP/2 | Proksi terbalik |
--http2-proxy | HTTP/3, HTTP/2, HTTP/1.1 | HTTP/1.1, HTTP/2 | Proksi penerusan |
Mode yang menarik saat ini adalah mode default. Ia bekerja seperti proxy terbalik dan mendengarkan HTTP/3, HTTP/2, dan HTTP/1.1 dan dapat digunakan sebagai terminator SSL/TLS untuk server web yang ada.
Di semua mode, koneksi frontend dienkripsi oleh SSL/TLS secara default. Untuk menonaktifkan enkripsi, gunakan kata kunci no-tls
di opsi --frontend
. Jika enkripsi dinonaktifkan, koneksi HTTP/1.1 masuk dapat ditingkatkan ke HTTP/2 melalui Peningkatan HTTP. Di sisi lain, koneksi backend tidak dienkripsi secara default. Untuk mengenkripsi koneksi backend, gunakan kata kunci tls
di opsi --backend
.
nghttpx
mendukung file konfigurasi. Lihat opsi --conf
dan contoh file konfigurasi nghttpx.conf.sample
.
Dalam mode default, nghttpx
berfungsi sebagai proksi terbalik ke server backend:
Klien <-- (HTTP/3, HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/1.1, HTTP/2) --> Server Web
[proksi terbalik]
Dengan opsi --http2-proxy
, ini berfungsi sebagai proksi penerusan, dan disebut proksi HTTP/2 aman:
Klien <-- (HTTP/3, HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Proksi
[proksi aman] (misalnya, Squid, ATS)
Client
dalam contoh di atas perlu dikonfigurasi untuk menggunakan nghttpx
sebagai proxy aman.
Pada saat penulisan ini, Chrome dan Firefox mendukung proxy HTTP/2 yang aman. Salah satu cara mengonfigurasi Chrome agar menggunakan proxy aman adalah dengan membuat skrip proxy.pac seperti ini:
function FindProxyForURL ( url , host ) {
return "HTTPS SERVERADDR:PORT" ;
}
SERVERADDR
dan PORT
adalah nama host/alamat dan port mesin tempat nghttpx dijalankan. Harap perhatikan bahwa Chrome memerlukan sertifikat yang valid untuk proxy yang aman.
Kemudian jalankan Chrome dengan argumen berikut:
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
Koneksi HTTP/2 backend dapat disalurkan melalui proksi HTTP. Proksi ditentukan menggunakan --backend-http-proxy-uri
. Gambar berikut mengilustrasikan bagaimana nghttpx berkomunikasi dengan proksi HTTP/2 luar melalui proksi HTTP:
Klien <-- (HTTP/3, HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) --
---====---> Proksi HTTP/2
(Terowongan proksi HTTP) (misalnya, nghttpx -s)
Program h2load
adalah alat pembandingan untuk HTTP/3, HTTP/2, dan HTTP/1.1. UI h2load
sangat terinspirasi oleh weighttp
(https://github.com/lighttpd/weighttp). Penggunaan umumnya adalah sebagai berikut:
$ h2load -n100000 -c100 -m100 https://localhost:8443/
tolok ukur awal...
thread pemijahan #0: 100 klien bersamaan, 100.000 total permintaan
Protokol: TLSv1.2
Sandi: ECDHE-RSA-AES128-GCM-SHA256
Kunci Temp Server: ECDH P-256 256 bit
kemajuan: 10% selesai
kemajuan: 20% selesai
kemajuan: 30% selesai
kemajuan: 40% selesai
kemajuan: 50% selesai
kemajuan: 60% selesai
kemajuan: 70% selesai
kemajuan: 80% selesai
kemajuan: 90% selesai
kemajuan: 100% selesai
selesai dalam 771,26 ms, 129658 permintaan/dtk, 4,71MB/dtk
permintaan: total 100.000, 100.000 dimulai, 100.000 selesai, 100.000 berhasil, 0 gagal, 0 kesalahan
kode status: 100000 2xx, 0 3xx, 0 4xx, 0 5xx
lalu lintas: total 3812300 byte, header 1009900 byte, data 1000000 byte
min maks berarti sd +/- sd
waktu permintaan: 25,12 md 124,55 md 51,07 md 15,36 md 84,87%
waktu untuk terhubung: 208,94 md 254,67 md 241,38 md 7,95 md 63,00%
waktu hingga byte pertama: 209,11 md 254,80 md 241,51 md 7,94 md 63,00%
Contoh di atas mengeluarkan total 100.000 permintaan, menggunakan 100 klien secara bersamaan (dengan kata lain, 100 sesi HTTP/2), dan maksimum 100 aliran per klien. Dengan opsi -t
, h2load
akan menggunakan beberapa thread asli untuk menghindari kejenuhan satu inti di sisi klien.
Peringatan
Jangan gunakan alat ini pada server yang tersedia untuk umum. Itu dianggap sebagai serangan DOS. Harap hanya menggunakannya pada server pribadi Anda.
Jika HTTP/3 eksperimental diaktifkan, h2load dapat mengirim permintaan ke server HTTP/3. Untuk melakukan ini, tentukan opsi h3
ke --alpn-list
seperti:
$ h2load --alpn-list h3 https://127.0.0.1:4433
Untuk nghttp2 v1.58 atau versi lebih lama, gunakan --npn-list
alih-alih --alpn-list
.
Direktori src
berisi alat HPACK. Program deflatehd
adalah alat kompresi header baris perintah. Program inflatehd
adalah alat dekompresi header baris perintah. Kedua alat membaca masukan dari stdin dan menulis keluaran ke stdout. Kesalahan ditulis ke stderr. Mereka mengambil JSON sebagai input dan output. Kami (kebanyakan) menggunakan format data JSON yang sama yang dijelaskan di https://github.com/http2jp/hpack-test-case.
Program deflatehd
membaca data JSON atau bidang header http/1-style dari stdin dan output blok header terkompresi di JSON.
Untuk input JSON, objek JSON root harus menyertakan kunci cases
. Nilainya harus menyertakan urutan set header input. Mereka berbagi konteks kompresi yang sama dan diproses dalam urutan yang mereka muncul. Setiap item dalam urutan adalah objek JSON dan harus menyertakan kunci headers
. Nilainya adalah array objek JSON, yang mencakup tepat satu nama/nilai pasangan.
Contoh:
{
"cases" :
[
{
"headers" : [
{ ":method" : " GET " },
{ ":path" : " / " }
]
},
{
"headers" : [
{ ":method" : " POST " },
{ ":path" : " / " }
]
}
]
}
Dengan opsi -t
, program dapat menerima blok bidang header gaya HTTP/1 yang lebih akrab. Setiap set header dibatasi oleh garis kosong:
Contoh:
: Metode: Dapatkan
: Skema: https
:jalur: /
: Metode: Posting
Pengguna-agen: nghttp2
Outputnya ada di objek JSON. Ini harus mencakup kunci cases
dan nilainya adalah array objek JSON, yang memiliki setidaknya kunci berikut:
output_length
/ input_length
* 100Contoh:
{
"cases" :
[
{
"seq" : 0 ,
"input_length" : 66 ,
"output_length" : 20 ,
"percentage_of_original_size" : 30.303030303030305 ,
"wire" : " 01881f3468e5891afcbf83868a3d856659c62e3f " ,
"headers" : [
{
":authority" : " example.org "
},
{
":method" : " GET "
},
{
":path" : " / "
},
{
":scheme" : " https "
},
{
"user-agent" : " nghttp2 "
}
],
"header_table_size" : 4096
}
,
{
"seq" : 1 ,
"input_length" : 74 ,
"output_length" : 10 ,
"percentage_of_original_size" : 13.513513513513514 ,
"wire" : " 88448504252dd5918485 " ,
"headers" : [
{
":authority" : " example.org "
},
{
":method" : " POST "
},
{
":path" : " /account "
},
{
":scheme" : " https "
},
{
"user-agent" : " nghttp2 "
}
],
"header_table_size" : 4096
}
]
}
Output dapat digunakan sebagai input untuk inflatehd
dan deflatehd
.
Dengan opsi -d
, kunci header_table
tambahan ditambahkan dan nilainya terkait mencakup status tabel header dinamis setelah set header yang sesuai diproses. Nilainya mencakup setidaknya kunci berikut:
referenced
true
, itu ada di set referensi. size
termasuk overhead (32 byte). index
sesuai dengan indeks tabel header. name
adalah nama bidang header dan value
adalah nilai bidang header.max_deflate_size
.max_size
. Dalam hal ini, encoder hanya menggunakan buffer max_deflate_size
pertama. Karena ukuran tabel header masih max_size
, encoder harus melacak entri di luar max_deflate_size
tetapi di dalam max_size
dan memastikan bahwa mereka tidak lagi dirujuk.Contoh:
{
"cases" :
[
{
"seq" : 0 ,
"input_length" : 66 ,
"output_length" : 20 ,
"percentage_of_original_size" : 30.303030303030305 ,
"wire" : " 01881f3468e5891afcbf83868a3d856659c62e3f " ,
"headers" : [
{
":authority" : " example.org "
},
{
":method" : " GET "
},
{
":path" : " / "
},
{
":scheme" : " https "
},
{
"user-agent" : " nghttp2 "
}
],
"header_table_size" : 4096 ,
"header_table" : {
"entries" : [
{
"index" : 1 ,
"name" : " user-agent " ,
"value" : " nghttp2 " ,
"referenced" : true ,
"size" : 49
},
{
"index" : 2 ,
"name" : " :scheme " ,
"value" : " https " ,
"referenced" : true ,
"size" : 44
},
{
"index" : 3 ,
"name" : " :path " ,
"value" : " / " ,
"referenced" : true ,
"size" : 38
},
{
"index" : 4 ,
"name" : " :method " ,
"value" : " GET " ,
"referenced" : true ,
"size" : 42
},
{
"index" : 5 ,
"name" : " :authority " ,
"value" : " example.org " ,
"referenced" : true ,
"size" : 53
}
],
"size" : 226 ,
"max_size" : 4096 ,
"deflate_size" : 226 ,
"max_deflate_size" : 4096
}
}
,
{
"seq" : 1 ,
"input_length" : 74 ,
"output_length" : 10 ,
"percentage_of_original_size" : 13.513513513513514 ,
"wire" : " 88448504252dd5918485 " ,
"headers" : [
{
":authority" : " example.org "
},
{
":method" : " POST "
},
{
":path" : " /account "
},
{
":scheme" : " https "
},
{
"user-agent" : " nghttp2 "
}
],
"header_table_size" : 4096 ,
"header_table" : {
"entries" : [
{
"index" : 1 ,
"name" : " :method " ,
"value" : " POST " ,
"referenced" : true ,
"size" : 43
},
{
"index" : 2 ,
"name" : " user-agent " ,
"value" : " nghttp2 " ,
"referenced" : true ,
"size" : 49
},
{
"index" : 3 ,
"name" : " :scheme " ,
"value" : " https " ,
"referenced" : true ,
"size" : 44
},
{
"index" : 4 ,
"name" : " :path " ,
"value" : " / " ,
"referenced" : false ,
"size" : 38
},
{
"index" : 5 ,
"name" : " :method " ,
"value" : " GET " ,
"referenced" : false ,
"size" : 42
},
{
"index" : 6 ,
"name" : " :authority " ,
"value" : " example.org " ,
"referenced" : true ,
"size" : 53
}