mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-07 10:38:53 +08:00
Refactor ALPN/NPN protocol selection and introduce NGHTTP2_PROTO_ALPN macro
This commit is contained in:
@@ -49,6 +49,24 @@ extern "C" {
|
||||
*/
|
||||
#define NGHTTP2_PROTO_VERSION_ID_LEN 5
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* The seriazlied form of ALPN protocol identifier this library
|
||||
* supports. Notice that first byte is the length of following
|
||||
* protocol identifier. This is the same wire format of `TLS ALPN
|
||||
* extension <https://tools.ietf.org/html/rfc7301>`_. This is useful
|
||||
* to process incoming ALPN tokens in wire format.
|
||||
*/
|
||||
#define NGHTTP2_PROTO_ALPN "\x5h2-14"
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* The length of :macro:`NGHTTP2_PROTO_ALPN`.
|
||||
*/
|
||||
#define NGHTTP2_PROTO_ALPN_LEN (sizeof(NGHTTP2_PROTO_ALPN) - 1)
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
|
||||
@@ -26,29 +26,32 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static int select_next_protocol(unsigned char **out, unsigned char *outlen,
|
||||
const unsigned char *in, unsigned int inlen,
|
||||
const char *key, unsigned int keylen) {
|
||||
unsigned int i;
|
||||
for (i = 0; i + keylen <= inlen; i += in [i] + 1) {
|
||||
if (memcmp(&in[i], key, keylen) == 0) {
|
||||
*out = (unsigned char *)&in[i + 1];
|
||||
*outlen = in[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define NGHTTP2_HTTP_1_1_ALPN "\x8http/1.1"
|
||||
#define NGHTTP2_HTTP_1_1_ALPN_LEN (sizeof(NGHTTP2_HTTP_1_1_ALPN) - 1)
|
||||
|
||||
int nghttp2_select_next_protocol(unsigned char **out, unsigned char *outlen,
|
||||
const unsigned char *in, unsigned int inlen) {
|
||||
int http_selected = 0;
|
||||
unsigned int i = 0;
|
||||
for (; i < inlen; i += in [i] + 1) {
|
||||
if (in[i] == NGHTTP2_PROTO_VERSION_ID_LEN && i + 1 + in[i] <= inlen &&
|
||||
memcmp(&in[i + 1], NGHTTP2_PROTO_VERSION_ID, in[i]) == 0) {
|
||||
*out = (unsigned char *)&in[i + 1];
|
||||
*outlen = in[i];
|
||||
return 1;
|
||||
}
|
||||
if (in[i] == 8 && i + 1 + in[i] <= inlen &&
|
||||
memcmp(&in[i + 1], "http/1.1", in[i]) == 0) {
|
||||
http_selected = 1;
|
||||
*out = (unsigned char *)&in[i + 1];
|
||||
*outlen = in[i];
|
||||
/* Go through to the next iteration, because "HTTP/2" may be
|
||||
there */
|
||||
}
|
||||
if (select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_ALPN,
|
||||
NGHTTP2_PROTO_ALPN_LEN) == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (http_selected) {
|
||||
if (select_next_protocol(out, outlen, in, inlen, NGHTTP2_HTTP_1_1_ALPN,
|
||||
NGHTTP2_HTTP_1_1_ALPN_LEN) == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user