هذا تطبيق لبروتوكول نقل النص التشعبي الإصدار 2 في لغة C.
يتم تنفيذ طبقة الإطارات الخاصة بـ HTTP/2 كمكتبة C قابلة لإعادة الاستخدام. علاوة على ذلك، قمنا بتنفيذ عميل وخادم ووكيل HTTP/2. لقد قمنا أيضًا بتطوير أدوات اختبار التحميل وقياس الأداء لـ HTTP/2.
يتوفر برنامج التشفير ووحدة فك التشفير HPACK كواجهة برمجة تطبيقات عامة.
تم تطوير nghttp2 في الأصل استنادًا إلى RFC 7540 HTTP/2 وRFC 7541 HPACK - ضغط الرأس لـ HTTP/2. نقوم الآن بتحديث الكود الخاص بنا لتنفيذ RFC 9113.
تم تشعب قاعدة كود nghttp2 من مشروع spdylay (https://github.com/tatsuhiro-t/spdylay).
نقاط النهاية التالية متاحة لتجربة تنفيذ nghttp2.
https://nghttp2.org/ (TLS + ALPN وHTTP/3)
تدعم نقطة النهاية هذه h2
و h2-16
و h2-14
و http/1.1
عبر ALPN وتتطلب TLSv1.2 للاتصال HTTP/2.
كما أنه يدعم HTTP/3.
http://nghttp2.org/ (ترقية HTTP وHTTP/2 المباشر)
h2c
و http/1.1
.
الحزمة التالية مطلوبة لبناء مكتبة libnghttp2:
لبناء الوثائق، تحتاج إلى تثبيت:
إذا كنت تحتاج إلى libnghttp2 (مكتبة C) فقط، فإن الحزم المذكورة أعلاه هي كل ما تحتاجه. استخدم --enable-lib-only
للتأكد من إنشاء libnghttp2 فقط. يؤدي هذا إلى تجنب خطأ البناء المحتمل المتعلق ببناء التطبيقات المجمعة.
لبناء وتشغيل برامج التطبيق ( nghttp
, nghttpd
, nghttpx
و h2load
) في دليل src
، الحزم التالية مطلوبة:
لتمكين الخيار -a
(الحصول على الأصول المرتبطة من المورد الذي تم تنزيله) في nghttp
، تكون الحزمة التالية مطلوبة:
لتمكين دعم systemd في nghttpx، تكون الحزمة التالية مطلوبة:
تتطلب أدوات HPACK الحزمة التالية:
لبناء مصادر ضمن دليل الأمثلة، مطلوب libevent:
للتخفيف من تجزئة الكومة في برامج الخادم طويلة التشغيل ( nghttpd
و nghttpx
)، يوصى باستخدام jemalloc:
jemaloc
ملحوظة
لا يدعم Alpine Linux حاليًا استبدال malloc بسبب قيود musl. وراجع التفاصيل في العدد رقم ٧٦٢.
بالنسبة إلى إصدار BoringSSL أو aws-lc، ولتمكين ضغط شهادة RFC 8879 TLS في التطبيقات، يلزم توفر المكتبة التالية:
لتمكين دعم mruby لـ nghttpx، يلزم وجود mruby. نحن بحاجة إلى إنشاء mruby مع تشغيل C++ ABI بشكل صريح، وربما نحتاج إلى mrgems أخرى، تتم إدارة mruby بواسطة git submodule ضمن دليل الطرف الثالث/mruby. حاليًا، يتم تعطيل دعم mruby لـ nghttpx افتراضيًا. لتمكين دعم mruby، استخدم خيار التكوين --with-mruby
. لاحظ أنه في وقت كتابة هذا المقال، لم تكن حزم libmruby-dev وmruby في Debian/Ubuntu قابلة للاستخدام مع nghttp2، نظرًا لأنها لا تقوم بتمكين C++ ABI. لبناء مروبي، الحزم التالية مطلوبة:
يدعم nghttpx محرك فصل الامتيازات Neverbleed لـ OpenSSL. باختصار، فهو يقلل من خطر تسرب المفتاح الخاص عند استغلال خطأ خطير مثل Heartbleed. يتم تعطيل Neverbleed بشكل افتراضي. لتمكينه، استخدم خيار التكوين --with-neverbleed
.
لتمكين دعم HTTP/3 التجريبي لـ h2load وnghttpx، يلزم توفر المكتبات التالية:
استخدم خيار التكوين --enable-http3
لتمكين ميزة HTTP/3 لـ h2load وnghttpx.
من أجل إنشاء برنامج eBPF اختياري لتوجيه مخطط بيانات QUIC UDP الوارد إلى المقبس الصحيح لـ nghttpx، يلزم توفر المكتبات التالية:
استخدم خيار التكوين --with-libbpf
لإنشاء برنامج eBPF. هناك حاجة إلى libelf-dev لبناء libbpf.
بالنسبة إلى Ubuntu 20.04، يمكنك إنشاء libbpf من الكود المصدري. يتطلب nghttpx برنامج eBPF لإعادة تحميل التكوين الخاص به والتبديل السريع للملف القابل للتنفيذ.
يتطلب تجميع كود مصدر libnghttp2 C مترجم C99. ومن المعروف أن دول مجلس التعاون الخليجي 4.8 كافية. من أجل تجميع كود مصدر C++، يلزم وجود مترجم متوافق مع C++20. من المعروف أن g++ >= 12 و clang++ >= 15 على الأقل يعملان.
ملحوظة
لتمكين دعم mruby في nghttpx، استخدم خيار التكوين --with-mruby
.
ملحوظة
قد يحتاج مستخدمو نظام التشغيل Mac OS X إلى خيار تكوين --disable-threads
لتعطيل مؤشرات الترابط المتعددة في nghttpd وnghttpx وh2load لمنعهم من التعطل. نرحب بالتصحيح لجعل مؤشرات الترابط المتعددة تعمل على نظام التشغيل Mac OS X.
ملحوظة
لتجميع التطبيقات المرتبطة (nghttp وnghttpd وnghttpx وh2load)، يجب عليك استخدام خيار تكوين --enable-app
والتأكد من استيفاء المتطلبات المحددة أعلاه. عادةً، قم بتكوين عمليات فحص البرنامج النصي للتبعيات المطلوبة لإنشاء هذه التطبيقات، وتمكين --enable-app
تلقائيًا، حتى لا تضطر إلى استخدامه بشكل صريح. ولكن إذا وجدت أن التطبيقات لم يتم إنشاؤها، فإن استخدام --enable-app
قد يجد هذا السبب، مثل التبعية المفقودة.
ملحوظة
من أجل اكتشاف مكتبات الطرف الثالث، يتم استخدام pkg-config (على الرغم من أننا لا نستخدم pkg-config لبعض المكتبات (على سبيل المثال، libev)). افتراضيًا، يبحث pkg-config عن ملف *.pc
في المواقع القياسية (على سبيل المثال، /usr/lib/pkgconfig). إذا كان من الضروري استخدام ملف *.pc
في الموقع المخصص، فحدد المسارات إلى متغير البيئة PKG_CONFIG_PATH
، وقم بتمريره لتكوين البرنامج النصي، كما يلي:
$ ./configure PKG_CONFIG_PATH=/path/to/pkgconfig
بالنسبة للمكتبات المُدارة pkg-config، يتم تعريف متغيرات البيئة *_CFLAG
و *_LIBS
(على سبيل المثال، OPENSSL_CFLAGS
، OPENSSL_LIBS
). يؤدي تحديد سلسلة غير فارغة لهذه المتغيرات إلى تجاوز pkg-config تمامًا. بمعنى آخر، إذا تم تحديدها، فلن يتم استخدام pkg-config للكشف، ويكون المستخدم مسؤولاً عن تحديد القيم الصحيحة لهذه المتغيرات. للحصول على قائمة كاملة بهذه المتغيرات، قم بتشغيل ./configure -h
.
إذا كنت تستخدم Ubuntu 22.04 LTS، فقم بتشغيل ما يلي لتثبيت الحزم المطلوبة:
sudo apt-get install g++ clang make binutils autoconf automake
autotools-dev libtool pkg-config
zlib1g-dev libssl-dev libxml2-dev libev-dev
ليبفينت ديف ليبجانسون ديف
libc-ares-dev libjemalloc-dev libsystemd-dev
روبي ديف البيسون libelf-dev
يقوم مشروع nghttp2 بإصدار أرشيفات tar بشكل منتظم والتي تتضمن كود مصدر nghttp2 وملفات البناء التي تم إنشاؤها. يمكن تنزيلها من صفحة الإصدارات.
يتطلب إنشاء nghttp2 من git حزم تطوير أدوات تلقائية. البناء من أرشيفات القطران لا يتطلب ذلك، وبالتالي فهو أسهل بكثير. خطوة البناء المعتادة هي كما يلي:
$ القطران xf nghttp2-XYZtar.bz2
$ مؤتمر نزع السلاح nghttp2-XYZ
$ ./تكوين
$ جعل
يعد البناء من git أمرًا سهلاً، ولكن يرجى التأكد من استخدام autoconf 2.68 على الأقل:
تحديث الوحدة الفرعية $ git --init
$ الإصلاح التلقائي -i
$ صناعة السيارات
$المؤتمر التلقائي
$ ./تكوين
$ جعل
أسهل طريقة لإنشاء Windows nghttp2 dll الأصلي هي استخدام cmake. الإصدار المجاني من Visual C++ Build Tools يعمل بشكل جيد.
cmake
.cmake --build
لبناء المكتبة.لاحظ أن الخطوات المذكورة أعلاه من المرجح أن تنتج مكتبة nghttp2 فقط. لا يتم تجميع أي تطبيقات المجمعة.
ضمن بيئة Mingw، يمكنك فقط تجميع المكتبة، وهي libnghttp2-X.dll
و libnghttp2.a
.
إذا كنت تريد تجميع التطبيقات ( h2load
، nghttp
، nghttpx
، nghttpd
)، فأنت بحاجة إلى استخدام بيئة Cygwin.
ضمن بيئة Cygwin، لتجميع التطبيقات، عليك تجميع وتثبيت libev أولاً.
ثانيًا، تحتاج إلى إلغاء تعريف الماكرو __STRICT_ANSI__
، وإذا لم تقم بذلك، فلن تكون الوظائف fdopen
و fileno
و strptime
متاحة.
الأمر عينة مثل هذا:
$ تصدير CFLAGS = "-U__STRICT_ANSI__ -I$libev_PREFIX/include -L$libev_PREFIX/lib"
$ تصدير CXXFLAGS=$CFLAGS
$ ./تكوين
$ جعل
إذا كنت تريد تجميع التطبيقات ضمن examples/
، فأنت بحاجة إلى إزالة event.h
.h أو إعادة تسميته من تثبيت libev، لأنه يتعارض مع تثبيت libevent.
بعد تثبيت مجموعة أدوات nghttp2 مع make install
قد يواجه المرء خطأً مماثلاً:
nghttpx: خطأ أثناء تحميل المكتبات المشتركة: libnghttp2.so.14: لا يمكن فتح ملف كائن مشترك: لا يوجد مثل هذا الملف أو الدليل
وهذا يعني أن الأداة غير قادرة على تحديد موقع المكتبة المشتركة libnghttp2.so
.
لتحديث ذاكرة التخزين المؤقت للمكتبة المشتركة، قم بتشغيل sudo ldconfig
.
ملحوظة
التوثيق لا يزال غير مكتمل.
لبناء الوثائق، قم بتشغيل:
$ جعل HTML
سيتم إنشاء المستندات ضمن doc/manual/html/
.
لن يتم تثبيت المستندات التي تم إنشاؤها باستخدام make install
.
الوثائق عبر الإنترنت متاحة على https://nghttp2.org/documentation/
لإنشاء h2load وnghttpx مع تمكين ميزة HTTP/3، قم بتشغيل البرنامج النصي للتكوين باستخدام --enable-http3
.
لكي يتمكن nghttpx من إعادة تحميل التكوينات وتبديل الملف القابل للتنفيذ أثناء إنهاء العمليات المنفذة القديمة بأمان، يلزم وجود eBPF. قم بتشغيل البرنامج النصي للتكوين باستخدام --enable-http3 --with-libbpf
لإنشاء برنامج eBPF. يجب ضبط مادة مفاتيح QUIC باستخدام --frontend-quic-secret-file
من أجل الحفاظ على الاتصالات الحالية حية أثناء إعادة التحميل.
اتبع الخطوات التفصيلية لإنشاء h2load وnghttpx الممكّنين لـ HTTP/3.
بناء aws-lc:
$ git clone - العمق 1 -b v1.39.0 https://github.com/aws/aws-lc
$ مؤتمر نزع السلاح أوس-LC
$ cmake -B build -DDISABLE_GO=ON --install-prefix=$PWD/opt
$ make -j$(nproc) -C build
$ cmake - تثبيت البناء
$ سي دي..
بناء nghttp3:
$ git clone - العمق 1 -b v1.6.0 https://github.com/ngtcp2/nghttp3
$ مؤتمر نزع السلاح nghttp3
تحديث الوحدة الفرعية $ git -init - العمق 1
$ الإصلاح التلقائي -i
$ ./configure --prefix=$PWD/build --enable-lib-only
$ جعل -j$(nproc)
$ قم بالتثبيت
$ سي دي..
بناء ngtcp2:
$ git clone - العمق 1 -b v1.9.1 https://github.com/ngtcp2/ngtcp2
$ مؤتمر نزع السلاح ngtcp2
تحديث الوحدة الفرعية $ git -init - العمق 1
$ الإصلاح التلقائي -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"
$ جعل -j$(nproc)
$ قم بالتثبيت
$ سي دي..
إذا لم يكن توزيع Linux الخاص بك يحتوي على libbpf-dev >= 0.7.0، فقم بالبناء من المصدر:
$ git clone - العمق 1 -b v1.4.6 https://github.com/libbpf/libbpf
$ قرص مضغوط libbf
$ PREFIX=$PWD/build make -C src install
$ سي دي..
بناء nghttp2:
استنساخ $ git https://github.com/nghttp2/nghttp2
$ مؤتمر نزع السلاح nghttp2
تحديث الوحدة الفرعية $ git --init
$ الإصلاح التلقائي -i
$ ./configure --with-mruby --enable-http3 --with-libbpf
CC=clang-15 CXX=clang++-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"
$ جعل -j$(nproc)
يجب العثور على برنامج eBPF reuseport_kern.o
ضمن دليل bpf. قم بتمرير خيار --quic-bpf-program-file=bpf/reuseport_kern.o
إلى nghttpx لتحميله. راجع أيضًا قسم HTTP/3 في nghttpx - وكيل HTTP/2 - الطريقة.
يتم إجراء اختبارات الوحدة بمجرد تشغيل make check
.
لدينا اختبارات التكامل لخادم وكيل nghttpx. تتم كتابة الاختبارات بلغة البرمجة Go وتستخدم إطار الاختبار الخاص بها. نعتمد على المكتبات التالية:
ستقوم وحدات Go بتنزيل هذه التبعيات تلقائيًا.
لإجراء الاختبارات، قم بتشغيل الأمر التالي ضمن دليل integration-tests
:
$ افعلها
داخل الاختبارات، نستخدم المنفذ 3009 لتشغيل خادم موضوع الاختبار.
قدم nghttp2 v1.0.0 العديد من التغييرات غير المتوافقة مع الإصدارات السابقة. في هذا القسم، نوضح هذه التغييرات وكيفية الانتقال إلى الإصدار 1.0.0.
h2
و h2c
لقد أعلنا سابقًا عن h2-14
و h2c-14
. ينفذ الإصدار 1.0.0 الإصدار النهائي من البروتوكول، وقمنا بتغيير معرف ALPN إلى h2
و h2c
. تم تحديث وحدات الماكرو NGHTTP2_PROTO_VERSION_ID
و NGHTTP2_PROTO_VERSION_ID_LEN
و NGHTTP2_CLEARTEXT_PROTO_VERSION_ID
و NGHTTP2_CLEARTEXT_PROTO_VERSION_ID_LEN
لتعكس هذا التغيير.
في الأساس، لا يتعين على التطبيقات الموجودة أن تفعل أي شيء، فقط إعادة الترجمة تكفي لهذا التغيير.
نحن نستخدم "مقدمة اتصال العميل" لتعني أول 24 بايت من مقدمة اتصال العميل. هذا غير صحيح من الناحية الفنية، نظرًا لأن مقدمة اتصال العميل تتكون من سلسلة بايت سحرية للعميل مكونة من 24 بايت متبوعة بإطار الإعدادات. للتوضيح، نسميه "سحر العميل" لهذه السلسلة المكونة من 24 بايت وواجهة برمجة التطبيقات المحدثة.
NGHTTP2_CLIENT_CONNECTION_PREFACE
بـ NGHTTP2_CLIENT_MAGIC
.NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN
بـ NGHTTP2_CLIENT_MAGIC_LEN
.NGHTTP2_BAD_PREFACE
ليصبح NGHTTP2_BAD_CLIENT_MAGIC
تمت إزالة NGHTTP2_CLIENT_CONNECTION_HEADER
و NGHTTP2_CLIENT_CONNECTION_HEADER_LEN
المهملين بالفعل.
إذا كان التطبيق يستخدم وحدات الماكرو هذه، فما عليك سوى استبدال وحدات الماكرو القديمة بأخرى جديدة. منذ الإصدار 1.0.0، يتم إرسال سحر العميل عن طريق المكتبة (راجع القسم الفرعي التالي)، لذلك قد يقوم تطبيق العميل بإزالة استخدام الماكرو هذا فقط.
في السابق، لم تكن مكتبة nghttp2 ترسل سحر العميل، وهو أول سلسلة بايت مكونة من 24 بايت من مقدمة اتصال العميل، ويجب على تطبيقات العميل إرسالها بنفسها. منذ الإصدار 1.0.0، يتم إرسال سحر العميل بواسطة المكتبة عبر الاستدعاء الأول لـ nghttp2_session_send()
أو nghttp2_session_mem_send2()
.
يجب على تطبيقات العميل التي ترسل سحر العميل إزالة الكود ذي الصلة.
لم يتم الانتهاء من مواصفات Alt-Svc بعد. لجعل واجهة برمجة التطبيقات الخاصة بنا مستقرة، قررنا إزالة جميع واجهات برمجة التطبيقات ذات الصلة بـ Alt-Svc من nghttp2.
NGHTTP2_EXT_ALTSVC
.nghttp2_ext_altsvc
.لقد قمنا بالفعل بإزالة وظيفة Alt-Svc في سلسلة v0.7 وأصبحت في الأساس noop. التطبيق الذي يستخدم هذه الماكرو والبنية، قم بإزالة هذه الخطوط.
في السابق، كان nghttp2_on_invalid_frame_recv_cb_called
يأخذ رمز error_code
، المحدد في nghttp2_error_code
، كمعلمة. لكنها ليست مفصلة بما يكفي لتصحيح الأخطاء. ولذلك، قررنا استخدام قيم nghttp2_error
أكثر تفصيلاً بدلاً من ذلك.
يجب أن يقوم التطبيق الذي يستخدم رد الاتصال هذا بتحديث توقيع رد الاتصال. إذا كان يعامل error_code
على أنه رمز خطأ HTTP/2، فقم بتحديث الرمز بحيث يتم التعامل معه على أنه nghttp2_error
.
في السابق، لم يكن nghttp2 يعالج سحر العميل (سلسلة بايت بحجم 24 بايت). للتعامل معها، كان علينا استخدام nghttp2_option_set_recv_client_preface()
. منذ الإصدار 1.0.0، يقوم nghttp2 بمعالجة سحر العميل افتراضيًا وتمت إزالة nghttp2_option_set_recv_client_preface()
.
قد ترغب بعض التطبيقات في تعطيل هذا السلوك، لذلك أضفنا nghttp2_option_set_no_recv_client_magic()
لتحقيق ذلك.
التطبيق الذي يستخدم nghttp2_option_set_recv_client_preface()
بقيمة غير صفرية، ما عليك سوى إزالته.
التطبيق الذي يستخدم nghttp2_option_set_recv_client_preface()
بقيمة صفر أو لا يستخدمه يجب أن يستخدم nghttp2_option_set_no_recv_client_magic()
بقيمة غير صفرية.
يحتوي دليل src
على برامج العميل والخادم والوكيل HTTP/2.
nghttp
هو عميل HTTP/2. يمكنه الاتصال بخادم HTTP/2 بمعرفة مسبقة وترقية HTTP وامتداد ALPN TLS.
يحتوي على وضع إخراج مطول لتأطير المعلومات. فيما يلي نموذج لإخراج عميل nghttp
:
$ nghttp -nv https://nghttp2.org
[ 0.190] متصل
البروتوكول الذي تم التفاوض عليه: h2
[ 0.212] إطار إعدادات ريكف <الطول=12، الأعلام=0x00، Stream_id=0>
(نيف = 2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[0.212] إرسال إطار الإعدادات <الطول=12، الأعلام=0x00،stream_id=0>
(نيف = 2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[0.212] إرسال إطار الإعدادات <الطول=0، الأعلام=0x01،stream_id=0>
; أك
(نيف = 0)
[0.212] إرسال إطار الأولوية
(dep_stream_id=0، الوزن=201، الحصري=0)
[0.212] إرسال إطار الأولوية
(dep_stream_id=0، الوزن=101، الحصري=0)
[0.212] إرسال إطار الأولوية
(dep_stream_id=0، الوزن=1، الحصري=0)
[0.212] إرسال إطار الأولوية
(dep_stream_id=7، الوزن=1، الحصري=0)
[0.212] إرسال إطار الأولوية
(dep_stream_id=3، الوزن=1، الحصري=0)
[0.212] إرسال إطار رؤوس <الطول=39، الأعلام=0x25،stream_id=13>
; END_STREAM | END_HEADERS | أولوية
(padlen=0، dep_stream_id=11، الوزن=16، الحصري=0)
; فتح تيار جديد
:الطريقة: احصل على
:طريق: /
:المخطط: https
:السلطة: nghttp2.org
يقبل: */*
قبول الترميز: gzip، انكماش
وكيل المستخدم: nghttp2/1.0.1-DEV
[ 0.221] إطار إعدادات ريكف <الطول=0، الأعلام=0x01، Stream_id=0>
; أك
(نيف = 0)
[ 0.221] ريكف (stream_id=13) :الطريقة: الحصول على
[ 0.221] ريكف (stream_id=13): المخطط: https
[ 0.221] ريكف (stream_id=13): المسار: /stylesheets/screen.css
[ 0.221] ريكف (stream_id=13) :authority: nghttp2.org
[0.221]ريكف (stream_id=13) قبول التشفير: gzip، انكماش
[ 0.222]ريكف (stream_id=13) وكيل المستخدم: nghttp2/1.0.1-DEV
[ 0.222] إطار RECV PUSH_PROMISE <الطول=50، الأعلام=0x04، Stream_id=13>
; END_HEADERS
(بادلين = 0، وعد_ستريم_id = 2)
[ 0.222] ريكف (stream_id=13) :الحالة: 200
[ 0.222] تاريخ التسجيل (stream_id=13): الخميس، 21 مايو 2015 الساعة 16:38:14 بتوقيت جرينتش
[0.222]ريكف (stream_id=13) نوع المحتوى: نص/html
[ 0.222]ريكف (stream_id=13) آخر تعديل: الجمعة، 15 مايو 2015 15:38:06 بتوقيت جرينتش
[ 0.222] ريكف (stream_id=13) العلامة: W/"555612de-19f6"
[ 0.222] رابط ريكف (stream_id=13): ؛ rel=preload; as=stylesheet
[ 0.222]ريكف (stream_id=13) ترميز المحتوى: gzip
[ 0.222] خادم ريكف (stream_id=13) الخادم: nghttpx nghttp2/1.0.1-DEV
[ 0.222] ريكف (stream_id=13) عبر: 1.1 nghttpx
[0.222]ريكف (معرف_البث=13) أمان النقل الصارم: الحد الأقصى للعمر=31536000
[ 0.222] إطار رؤوس التسجيل
; END_HEADERS
(بادلين=0)
; رأس الرد الأول
[0.222] إطار بيانات ريكف <الطول=2601، الأعلام=0x01، تيار_id=13>
; END_STREAM
[ 0.222] ريكف (stream_id=2):الحالة: 200
[ 0.222] تاريخ التسجيل (stream_id=2): الخميس، 21 مايو 2015 الساعة 16:38:14 بتوقيت جرينتش
[ 0.222]ريكف (stream_id=2) نوع المحتوى: نص/CSS
[ 0.222]ريكف (stream_id=2) آخر تعديل: الجمعة، 15 مايو 2015 15:38:06 بتوقيت جرينتش
[ 0.222] ريكف (stream_id=2) العلامة: W/"555612de-9845"
[0.222]ريكف (stream_id=2) ترميز المحتوى: gzip
[ 0.222] خادم ريكف (stream_id=2) الخادم: nghttpx nghttp2/1.0.1-DEV
[ 0.222] ريكف (stream_id=2) عبر: 1.1 nghttpx
[0.222]ريكف (stream_id=2) أمان النقل الصارم: الحد الأقصى للعمر=31536000
[ 0.222] إطار رؤوس التسجيل
; END_HEADERS
(بادلين=0)
; رأس استجابة الدفع الأول
[0.228] إطار بيانات ريكف <الطول=8715، الأعلام=0x01، Stream_id=2>
; END_STREAM
[0.228] إرسال إطار GOAWAY <الطول=8، الأعلام=0x00،stream_id=0>
(last_stream_id=2، error_code=NO_ERROR(0x00)، opaque_data(0)=[])
يتم تنفيذ ترقية HTTP على النحو التالي:
$ nghttp -nvu http://nghttp2.org
[ 0.011] متصل
[0.011] طلب ترقية HTTP
الحصول على / HTTP/1.1
المضيف: nghttp2.org
الاتصال: الترقية، إعدادات HTTP2
الترقية: h2c
إعدادات HTTP2: AAMAAABkAAQAAP__
يقبل: */*
وكيل المستخدم: nghttp2/1.0.1-DEV
[0.018] استجابة ترقية HTTP
HTTP/1.1 101 بروتوكولات التبديل
الاتصال: الترقية
الترقية: h2c
[ 0.018] نجاح ترقية HTTP
[ 0.018] إطار إعدادات ريكف <الطول=12، الأعلام=0x00، Stream_id=0>
(نيف = 2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[0.018] إرسال إطار الإعدادات <الطول=12، الأعلام=0x00،stream_id=0>
(نيف = 2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[0.018] إرسال إطار الإعدادات <الطول=0، الأعلام=0x01،stream_id=0>
; أك
(نيف = 0)
[0.018] إرسال إطار الأولوية
(dep_stream_id=0، الوزن=201، الحصري=0)
[0.018] إرسال إطار الأولوية
(dep_stream_id=0، الوزن=101، الحصري=0)
[0.018] إرسال إطار الأولوية
(dep_stream_id=0، الوزن=1، الحصري=0)
[0.018] إرسال إطار الأولوية
(dep_stream_id=7، الوزن=1، الحصري=0)
[0.018] إرسال إطار الأولوية
(dep_stream_id=3، الوزن=1، الحصري=0)
[0.018] إرسال إطار الأولوية
(dep_stream_id=11، الوزن=16، الحصري=0)
[ 0.019] ريكف (stream_id=1) :الطريقة: الحصول على
[ 0.019] ريكف (stream_id=1): المخطط: http
[ 0.019] ريكف (stream_id=1): المسار: /stylesheets/screen.css
[ 0.019] مضيف ريكف (stream_id=1): nghttp2.org
[ 0.019]ريكف (stream_id=1) وكيل المستخدم: nghttp2/1.0.1-DEV
[ 0.019] إطار RECV PUSH_PROMISE <الطول=49، الأعلام=0x04، Stream_id=1>
; END_HEADERS
(بادلين = 0، وعد_تيار_id = 2)
[ 0.019] ريكف (stream_id=1) :الحالة: 200
[ 0.019] تاريخ التسجيل (stream_id=1): الخميس، 21 مايو 2015 الساعة 16:39:16 بتوقيت جرينتش
[0.019]ريكف (stream_id=1) نوع المحتوى: نص/html
[ 0.019] طول المحتوى (stream_id=1) : 6646
[ 0.019]ريكف (stream_id=1) آخر تعديل: الجمعة، 15 مايو 2015 15:38:06 بتوقيت جرينتش
[ 0.019] علامة التسجيل (stream_id=1): "555612de-19f6"
[ 0.019] رابط ريكف (stream_id=1): ؛ rel=preload; as=stylesheet
[ 0.019] قبول النطاقات (stream_id=1) : بايت
[ 0.019] خادم ريكف (stream_id=1): nghttpx nghttp2/1.0.1-DEV
[ 0.019] ريكف (stream_id=1) عبر: 1.1 nghttpx
[ 0.019] إطار رؤوس RECV <طول = 157، أعلام = 0x04، Stream_id = 1>
; END_HEADERS
(بادلين=0)
; رأس الرد الأول
[ 0.019] إطار بيانات ريكف <الطول=6646، الأعلام=0x01، Stream_id=1>
; END_STREAM
[ 0.019] ريكف (stream_id=2) :الحالة: 200
[ 0.019] تاريخ التسجيل (stream_id=2): الخميس، 21 مايو 2015 الساعة 16:39:16 بتوقيت جرينتش
[ 0.019]ريكف (stream_id=2) نوع المحتوى: نص/CSS
[ 0.019] طول المحتوى (stream_id=2) : 38981
[ 0.019]ريكف (stream_id=2) آخر تعديل: الجمعة، 15 مايو 2015 15:38:06 بتوقيت جرينتش
[ 0.019] علامة التسجيل (stream_id=2): "555612de-9845"
[ 0.019] قبول النطاقات (stream_id=2) : بايت
[ 0.019] خادم ريكف (stream_id=2) الخادم: nghttpx nghttp2/1.0.1-DEV
[ 0.019] ريكف (stream_id=2) عبر: 1.1 nghttpx
[ 0.019] إطار رؤوس التسجيل
; END_HEADERS
(بادلين=0)
; رأس استجابة الدفع الأول
[ 0.026] إطار بيانات ريكف <الطول=16384، الأعلام=0x00، تيار_id=2>
[ 0.027] إطار بيانات ريكف <الطول=7952، الأعلام=0x00، Stream_id=2>
[0.027] إرسال إطار WINDOW_UPDATE <الطول=4، الأعلام=0x00، Stream_id=0>
(window_size_increment=33343)
[0.032] إرسال إطار WINDOW_UPDATE <الطول=4، الأعلام=0x00،stream_id=2>
(window_size_increment=33707)
[0.032] إطار بيانات ريكف <الطول=14645، الأعلام=0x01، Stream_id=2>
; END_STREAM
[ 0.032] إطار إعدادات ريكف <الطول=0، الأعلام=0x01، Stream_id=0>
; أك
(نيف = 0)
[0.032] إرسال إطار GOAWAY <الطول=8، الأعلام=0x00،stream_id=0>
(last_stream_id=2، error_code=NO_ERROR(0x00)، opaque_data(0)=[])
باستخدام الخيار -s
، يقوم nghttp
بطباعة بعض معلومات التوقيت للطلبات، مرتبة حسب وقت الانتهاء:
$ nghttp -nas https://nghttp2.org/
***** إحصائيات *****
توقيت الطلب:
ResponseEnd: الوقت الذي تم فيه استلام البايت الأخير من الاستجابة
نسبة إلى ConnectEnd
requestStart: الوقت الذي يسبق إرسال البايت الأول من الطلب مباشرةً
نسبة إلى ConnectEnd. إذا تم عرض "*"، فهذا كان
يدفعها الخادم.
العملية: نهاية الاستجابة - بداية الطلب
الرمز: رمز حالة HTTP
الحجم: عدد البايتات المستلمة كنص استجابة بدون
تضخم اقتصادي.
URI: طلب URI
راجع http://www.w3.org/TR/resource-timing/#processing-model
مرتبة حسب "كاملة"
استجابة المعرف، نهاية الطلب، مسار طلب حجم رمز العملية
13 +37.19 مللي ثانية +280us 36.91 مللي ثانية 200 2K /
2 +72.65 مللي ثانية * +36.38 مللي ثانية 36.26 مللي ثانية 200 8K /stylesheets/screen.css
17 +77.43 مللي ثانية +38.67 مللي ثانية 38.75 مللي ثانية 200 3K /javascripts/octopress.js
15 +78.12 مللي ثانية +38.66 مللي ثانية 39.46 مللي ثانية 200 3K /javascripts/modernizr-2.0.js
باستخدام الخيار -r
، يكتب nghttp
بيانات توقيت أكثر تفصيلاً إلى الملف المحدد بتنسيق HAR.
nghttpd
هو خادم ويب ثابت متعدد الخيوط.
بشكل افتراضي، يستخدم اتصال SSL/TLS. استخدم خيار --no-tls
لتعطيله.
يقبل nghttpd
فقط اتصالات HTTP/2 عبر ALPN أو اتصالات HTTP/2 المباشرة. لا يتم دعم ترقية HTTP.
يسمح الخيار -p
للمستخدمين بتكوين دفع الخادم.
تمامًا مثل nghttp
، فهو يحتوي على وضع إخراج مطول لتأطير المعلومات. فيما يلي عينة من الإخراج من nghttpd
:
$ nghttpd --no-tls -v 8080
IPv4: استمع 0.0.0.0:8080
IPv6: استمع :::8080
[id=1] [1.521] إرسال إطار الإعدادات
(نيف = 1)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[id=1] [1.521] إطار إعدادات ريكف <الطول=12، الأعلام=0x00،stream_id=0>
(نيف = 2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[id=1] [1.521] إطار إعدادات ريكف <الطول=0، الأعلام=0x01،stream_id=0>
; أك
(نيف = 0)
[id=1] [1.521] إطار أولوية ريكف
(dep_stream_id=0، الوزن=201، الحصري=0)
[id=1] [1.521] إطار أولوية ريكف
(dep_stream_id=0، الوزن=101، الحصري=0)
[id=1] [1.521] إطار أولوية ريكف
(dep_stream_id=0، الوزن=1، الحصري=0)
[id=1] [1.521] إطار أولوية ريكف
(dep_stream_id=7، الوزن=1، الحصري=0)
[id=1] [1.521] إطار الأولوية لريكف
(dep_stream_id=3، الوزن=1، الحصري=0)
[المعرف=1] [1.521] ريكف (stream_id=13) :الطريقة: الحصول على
[id=1] [ 1.521] ريكف (stream_id=13) :المسار: /
[id=1] [ 1.521] ريكف (stream_id=13) :مخطط: http
[المعرف=1] [ 1.521] ريكف (stream_id=13) :السلطة: المضيف المحلي:8080
[id=1] [ 1.521] قبول ريكف (stream_id=13): */*
[id=1] [ 1.521]ريكف (stream_id=13) قبول الترميز: gzip، انكماش
[id=1] [ 1.521]ريكف (stream_id=13) وكيل المستخدم: nghttp2/1.0.0-DEV
[id=1] [ 1.521] إطار رؤوس التسجيل < length=41, flags=0x25,stream_id=13>
; END_STREAM | END_HEADERS | أولوية
(padlen=0، dep_stream_id=11، الوزن=16، الحصري=0)
; فتح تيار جديد
[id=1] [1.521] إرسال إعدادات الإطار
; أك
(نيف = 0)
[id=1] [1.521] إرسال إطار رؤوس
; END_HEADERS
(بادلين=0)
; رأس الرد الأول
:الحالة: 200
الخادم: nghttpd nghttp2/1.0.0-DEV
طول المحتوى: 10
التحكم في ذاكرة التخزين المؤقت: الحد الأقصى للعمر = 3600
التاريخ: الجمعة 15 مايو 2015 الساعة 14:49:04 بتوقيت جرينتش
آخر تعديل: الثلاثاء، 30 سبتمبر 2014 12:40:52 بتوقيت جرينتش
[id=1] [1.522] إرسال إطار بيانات
; END_STREAM
[id=1] [ 1.522]stream_id=13 مغلق
[id=1] [ 1.522] إطار ريكف GOAWAY <الطول=8، الأعلام=0x00، Stream_id=0>
(last_stream_id=0، error_code=NO_ERROR(0x00)، opaque_data(0)=[])
[id=1] [ 1.522] مغلق
nghttpx
هو وكيل عكسي متعدد الخيوط لـ HTTP/3 وHTTP/2 وHTTP/1.1، ويعمل على تشغيل http://nghttp2.org ويدعم دفع خادم HTTP/2.
لقد قمنا بإعادة صياغة واجهة سطر الأوامر nghttpx
، ونتيجة لذلك، هناك العديد من العناصر غير المتوافقة من الإصدار 1.8.0 أو الإصدارات السابقة. يعد هذا ضروريًا لتوسيع قدراته وتأمين تحسينات الميزات الإضافية في الإصدار المستقبلي. يرجى قراءة الترحيل من nghttpx v1.8.0 أو الإصدارات الأقدم لمعرفة كيفية الترحيل من الإصدارات السابقة.
ينفذ nghttpx
ميزات مهمة موجهة نحو الأداء في TLS، مثل معرفات الجلسة، وتذاكر الجلسة (مع التدوير التلقائي للمفاتيح)، وتدبيس OCSP، وتغيير حجم السجل الديناميكي، وALPN، وسرية إعادة التوجيه، وHTTP/2. يوفر nghttpx
أيضًا وظيفة مشاركة ذاكرة التخزين المؤقت للجلسة ومفاتيح التذاكر بين مثيلات nghttpx
المتعددة عبر memcached.
يحتوي nghttpx
على وضعين للتشغيل:
خيار الوضع | الواجهة الأمامية | الخلفية | ملحوظة |
---|---|---|---|
الوضع الافتراضي | HTTP/3، HTTP/2، HTTP/1.1 | HTTP/1.1، HTTP/2 | الوكيل العكسي |
--http2-proxy | HTTP/3، HTTP/2، HTTP/1.1 | HTTP/1.1، HTTP/2 | الوكيل إلى الأمام |
الوضع المثير للاهتمام في الوقت الحالي هو الوضع الافتراضي. إنه يعمل مثل الوكيل العكسي ويستمع إلى HTTP/3 وHTTP/2 وHTTP/1.1 ويمكن نشره باعتباره فاصل SSL/TLS لخادم الويب الحالي.
في جميع الأوضاع، يتم تشفير اتصالات الواجهة الأمامية بواسطة SSL/TLS افتراضيًا. لتعطيل التشفير، استخدم الكلمة الأساسية no-tls
في خيار --frontend
. إذا تم تعطيل التشفير، فيمكن ترقية اتصالات HTTP/1.1 الواردة إلى HTTP/2 من خلال ترقية HTTP. ومن ناحية أخرى، لا يتم تشفير الاتصالات الخلفية بشكل افتراضي. لتشفير اتصالات الواجهة الخلفية، استخدم الكلمة الأساسية tls
في خيار --backend
.
يدعم nghttpx
ملف التكوين. راجع خيار --conf
ونموذج ملف التكوين nghttpx.conf.sample
.
في الوضع الافتراضي، يعمل nghttpx
كوكيل عكسي لخادم الواجهة الخلفية:
العميل <-- (HTTP/3, HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/1.1, HTTP/2) --> خادم الويب
[وكيل عكسي]
مع خيار --http2-proxy
، يعمل كوكيل أمامي، ويسمى وكيل HTTP/2 الآمن:
العميل <-- (HTTP/3, HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> الوكيل
[الوكيل الآمن] (على سبيل المثال، Squid، ATS)
يحتاج Client
في المثال أعلاه إلى التهيئة لاستخدام nghttpx
كوكيل آمن.
في وقت كتابة هذه السطور، يدعم كل من Chrome وFirefox وكيل HTTP/2 الآمن. تتمثل إحدى طرق تكوين Chrome لاستخدام وكيل آمن في إنشاء برنامج نصي proxy.pac مثل هذا:
function FindProxyForURL ( url , host ) {
return "HTTPS SERVERADDR:PORT" ;
}
SERVERADDR
و PORT
هو اسم المضيف/العنوان والمنفذ الخاص بالجهاز الذي يعمل عليه nghttpx. يرجى ملاحظة أن Chrome يتطلب شهادة صالحة للخادم الوكيل الآمن.
ثم قم بتشغيل Chrome باستخدام الوسائط التالية:
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
يمكن توجيه اتصالات الواجهة الخلفية HTTP/2 عبر وكيل HTTP. يتم تحديد الوكيل باستخدام --backend-http-proxy-uri
. يوضح الشكل التالي كيفية اتصال nghttpx مع وكيل HTTP/2 الخارجي من خلال وكيل HTTP:
العميل <-- (HTTP/3، HTTP/2، HTTP/1.1) --> nghttpx <-- (HTTP/2) -
--============== HTTP/2 الوكيل
(نفق وكيل HTTP) (على سبيل المثال، nghttpx -s)
يعد برنامج h2load
أداة قياس أداء لـ HTTP/3، وHTTP/2، وHTTP/1.1. واجهة المستخدم الخاصة بـ h2load
مستوحاة بشكل كبير من weighttp
(https://github.com/lighttpd/weighttp). الاستخدام النموذجي هو كما يلي:
$ h2load -n100000 -c100 -m100 https://localhost:8443/
بداية المعيار...
سلسلة النشر رقم 0: 100 عميل متزامن، 100000 إجمالي الطلبات
البروتوكول: TLSv1.2
التشفير: ECDHE-RSA-AES128-GCM-SHA256
مفتاح درجة حرارة الخادم: ECDH P-256 256 بت
التقدم: تم إنجاز 10%
التقدم: تم إنجاز 20%
التقدم: تم إنجاز 30%
التقدم: تم إنجاز 40%
التقدم: تم الانتهاء من 50%
التقدم: تم إنجاز 60%
التقدم: تم إنجاز 70%
التقدم: تم إنجاز 80%
التقدم: تم إنجاز 90%
التقدم: تم إنجازه بنسبة 100%
تم الانتهاء منه في 771.26 مللي ثانية، 129658 طلب/ثانية، 4.71 ميجابايت/ثانية
الطلبات: إجمالي 100000، بدأ 100000، تم تنفيذ 100000، نجح 100000، 0 فشل، 0 خطأ
رموز الحالة: 100000 2xx، 0 3xx، 0 4xx، 0 5xx
حركة المرور: إجمالي 3812300 بايت، 1009900 بايت رؤوس، 1000000 بايت بيانات
الحد الأدنى والحد الأقصى يعني sd +/- sd
وقت الطلب: 25.12 مللي ثانية 124.55 مللي ثانية 51.07 مللي ثانية 15.36 مللي ثانية 84.87%
وقت الاتصال: 208.94 مللي ثانية 254.67 مللي ثانية 241.38 مللي ثانية 7.95 مللي ثانية 63.00%
الوقت حتى البايت الأول: 209.11 مللي ثانية 254.80 مللي ثانية 241.51 مللي ثانية 7.94 مللي ثانية 63.00%
أصدر المثال أعلاه إجمالي 100000 طلب، باستخدام 100 عميل متزامن (بمعنى آخر، 100 جلسة HTTP/2)، وبحد أقصى 100 تدفق لكل عميل. باستخدام الخيار -t
، سيستخدم h2load
عدة سلاسل رسائل أصلية لتجنب تشبع نواة واحدة من جانب العميل.
تحذير
لا تستخدم هذه الأداة ضد الخوادم المتاحة للعامة. ويعتبر هذا هجوم DOS. يرجى استخدامه فقط ضد خوادمك الخاصة.
إذا تم تمكين HTTP/3 التجريبي، فيمكن لـ h2load إرسال الطلبات إلى خادم HTTP/3. للقيام بذلك، حدد خيار h3
إلى --alpn-list
كما يلي:
$ h2load --alpn-list h3 https://127.0.0.1:4433
بالنسبة إلى nghttp2 v1.58 أو الإصدارات الأقدم، استخدم --npn-list
بدلاً من --alpn-list
.
يحتوي دليل src
على أدوات HPACK. برنامج deflatehd
هو أداة لضغط رأس سطر الأوامر. برنامج inflatehd
هو أداة لضغط رأس سطر الأوامر. تقوم كلتا الأداتين بقراءة المدخلات من stdin وكتابة الإخراج إلى stdout. تتم كتابة الأخطاء إلى stderr. يأخذون JSON كمدخل ومخرج. نحن (في الغالب) نستخدم نفس تنسيق بيانات JSON الموضح في https://github.com/http2jp/hpack-test-case.
يقرأ برنامج deflatehd
بيانات JSON أو حقول رأس HTTP/1 على الطراز من stdin وتخرج كتلة رأس مضغوطة في JSON.
بالنسبة لمدخلات JSON ، يجب أن يتضمن كائن Root JSON مفتاح cases
. يجب أن تشمل قيمتها تسلسل مجموعة رأس الإدخال. يشتركون في نفس سياق الضغط ويتم معالجتهم بالترتيب الذي يظهرون فيه. كل عنصر في التسلسل هو كائن JSON ويجب أن يتضمن مفتاح headers
. قيمتها هي مجموعة من كائنات JSON ، والتي تتضمن بالضبط اسم/قيمة واحدة.
مثال:
{
"cases" :
[
{
"headers" : [
{ ":method" : " GET " },
{ ":path" : " / " }
]
},
{
"headers" : [
{ ":method" : " POST " },
{ ":path" : " / " }
]
}
]
}
مع خيار -t
، يمكن للبرنامج قبول المزيد من كتل حقل HTTP/1 HETSLER STYLE. يتم تحديد كل مجموعة رأس بواسطة خط فارغ:
مثال:
: الطريقة: الحصول على
: مخطط: https
:طريق: /
: الطريقة: post
عامل المستخدم: NGHTTP2
الإخراج في كائن JSON. يجب أن يتضمن مفتاح cases
وقيمته هي مجموعة من كائنات JSON ، والتي تحتوي على الأقل على المفاتيح التالية:
output_length
/ input_length
* 100أمثلة:
{
"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
}
]
}
يمكن استخدام المخرجات كمدخل لـ inflatehd
و deflatehd
.
مع خيار -d
، تتم إضافة مفتاح header_table
الإضافي وتتضمن القيمة المرتبطة به حالة جدول الرأس الديناميكي بعد معالجة مجموعة الرأس المقابلة. تتضمن القيمة على الأقل المفاتيح التالية:
referenced
true
، فهو في المجموعة المرجعية. ويشمل size
النفقات العامة (32 بايت). يتوافق index
مع فهرس جدول الرأس. name
هو اسم حقل الرأس value
هي قيمة حقل الرأس.max_deflate_size
.max_size
. في هذه الحالة ، يستخدم المشفر فقط لأعلى إلى First max_deflate_size
Buffer. نظرًا لأن حجم جدول الرأس لا يزال max_size
، يجب على المشفر تتبع الإدخالات خارج max_deflate_size
ولكن داخل max_size
وتأكد من عدم الرجوع إليها.مثال:
{
"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
}