Skip to content

Commit b7bb00e

Browse files
authored
Remove unused push promise support (#642)
Remove the HTTP/2 and HTTP/3 push promise implementation while keeping the public APIs in place as disabled stubs. Server push is no longer used, so this drops the associated state, frame generation, parsing callbacks, and stream bookkeeping. Update tests and documentation to cover the disabled behavior and the remaining HTTP/3 framing paths.
1 parent e78cf64 commit b7bb00e

22 files changed

Lines changed: 244 additions & 1472 deletions

include/lsquic.h

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,8 @@ typedef struct ssl_ctx_st * (*lsquic_lookup_cert_f)(
333333

334334
/** Do not use NSTP by default */
335335
#define LSQUIC_DF_SUPPORT_NSTP 0
336-
/** TODO: IETF QUIC clients do not support push */
337-
#define LSQUIC_DF_SUPPORT_PUSH 1
336+
/** Server push is not supported */
337+
#define LSQUIC_DF_SUPPORT_PUSH 0
338338
#define LSQUIC_DF_SUPPORT_TCID0 1
339339
/** By default, LSQUIC ignores Public Reset packets. */
340340
#define LSQUIC_DF_HONOR_PRST 0
@@ -606,16 +606,8 @@ struct lsquic_engine_settings {
606606
int es_support_srej;
607607

608608
/**
609-
* Setting this value to 0 means that
610-
*
611-
* For client:
612-
* a) we send a SETTINGS frame to indicate that we do not support server
613-
* push; and
614-
* b) All incoming pushed streams get reset immediately.
615-
* (For maximum effect, set es_max_streams_in to 0.)
616-
*
617-
* For server:
618-
* lsquic_conn_push_stream() will return -1.
609+
* Server push is not supported. lsquic_conn_is_push_enabled() returns
610+
* false and lsquic_conn_push_stream() returns 1.
619611
*/
620612
int es_support_push;
621613

src/liblsquic/lsquic_conn_public.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ struct lsquic_conn_public {
4444
struct qpack_enc_hdl *qeh;
4545
struct qpack_dec_hdl *qdh;
4646
struct hcso_writer *hcso;
47-
struct lsquic_hash *promises;
4847
} ietf;
4948
} u;
5049
enum {

src/liblsquic/lsquic_ev_log.c

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -522,25 +522,6 @@ lsquic_ev_log_generated_http_headers (const lsquic_cid_t *cid,
522522
}
523523

524524

525-
void
526-
lsquic_ev_log_generated_http_push_promise (const lsquic_cid_t *cid,
527-
lsquic_stream_id_t stream_id, lsquic_stream_id_t promised_stream_id,
528-
const struct lsquic_http_headers *headers)
529-
{
530-
int i;
531-
532-
LCID("generated HTTP PUSH_PROMISE for stream %"PRIu64"; promised stream %"
533-
PRIu64, stream_id, promised_stream_id);
534-
535-
for (i = 0; i < headers->count; ++i)
536-
if (headers->headers[i].buf)
537-
LCID(" %.*s: %.*s",
538-
(int) headers->headers[i].name_len,
539-
lsxpack_header_get_name(&headers->headers[i]),
540-
(int) headers->headers[i].val_len,
541-
lsxpack_header_get_value(&headers->headers[i]));
542-
}
543-
544525
void
545526
lsquic_ev_log_create_connection (const lsquic_cid_t *cid,
546527
const struct sockaddr *local_sa,

src/liblsquic/lsquic_ev_log.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -278,16 +278,6 @@ lsquic_ev_log_generated_http_headers (const lsquic_cid_t *, lsquic_stream_id_t,
278278
lsquic_ev_log_generated_http_headers(__VA_ARGS__); \
279279
} while (0)
280280

281-
void
282-
lsquic_ev_log_generated_http_push_promise (const lsquic_cid_t *,
283-
lsquic_stream_id_t stream_id, lsquic_stream_id_t promised_stream_id,
284-
const struct lsquic_http_headers *headers);
285-
286-
#define EV_LOG_GENERATED_HTTP_PUSH_PROMISE(...) do { \
287-
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
288-
lsquic_ev_log_generated_http_push_promise(__VA_ARGS__); \
289-
} while (0)
290-
291281
void
292282
lsquic_ev_log_create_connection (const lsquic_cid_t *, const struct sockaddr *,
293283
const struct sockaddr *);

src/liblsquic/lsquic_frame_common.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,6 @@ struct http_prio_frame /* RFC 7540, Section 6.3 */
6666
};
6767

6868

69-
struct http_push_promise_frame /* RFC 7540, Section 6.6 */
70-
{
71-
unsigned char hppf_promised_id[4]; /* High bit is reserved */
72-
};
73-
74-
7569
struct lsquic_http2_setting
7670
{
7771
uint16_t id;

src/liblsquic/lsquic_frame_reader.c

Lines changed: 13 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,23 @@
3131
#include "lsquic_logger.h"
3232

3333

34-
/* headers_state is used by HEADERS, PUSH_PROMISE, and CONTINUATION frames */
34+
/* headers_state is used by HEADERS and CONTINUATION frames */
3535
struct headers_state
3636
{
3737
enum http_frame_type
3838
frame_type;
3939
unsigned nread; /* Not counting pesw, only payload and padding */
4040

4141
/* Values parsed out from pesw buffer: */
42-
uint32_t oth_stream_id; /* For HEADERS: ID of stream we depend on;
43-
* for PUSH_PROMISE: promised stream ID.
44-
*/
42+
uint32_t oth_stream_id; /* For HEADERS: ID of stream we depend on */
4543
unsigned short weight; /* HEADERS only */
4644
signed char exclusive; /* HEADERS only */
4745
unsigned char pad_length;
4846

4947
unsigned char pseh;
5048

5149
/* PESW: Pad length, Exclusive, Stream Dependency, Weight. This is at
52-
* most six bytes for HEADERS frame (RFC 7540, page 33) and five bytes
53-
* for PUSH_PROMISE frame (Ibid, p. 40).
50+
* most six bytes for HEADERS frame (RFC 7540, page 33).
5451
*/
5552
unsigned char pesw_size;
5653
unsigned char pesw_nread;
@@ -88,7 +85,6 @@ struct reader_state
8885
enum {
8986
READER_SKIP,
9087
READER_HEADERS,
91-
READER_PUSH_PROMISE,
9288
READER_CONTIN,
9389
READER_SETTINGS,
9490
READER_PRIORITY,
@@ -115,8 +111,8 @@ struct lsquic_frame_reader
115111
const struct lsquic_hset_if *fr_hsi_if;
116112
void *fr_hsi_ctx;
117113
struct http1x_ctor_ctx fr_h1x_ctor_ctx;
118-
/* The the header block is shared between HEADERS, PUSH_PROMISE, and
119-
* CONTINUATION frames. It gets added to as block fragments come in.
114+
/* The header block is shared between HEADERS and CONTINUATION frames.
115+
* It gets added to as block fragments come in.
120116
*/
121117
unsigned char *fr_header_block;
122118
#if LSQUIC_CONN_STATS
@@ -258,7 +254,6 @@ prepare_for_payload (struct lsquic_frame_reader *fr)
258254
if (fr->fr_state.header.hfh_type != HTTP_FRAME_CONTINUATION &&
259255
(fr->fr_flags & FRF_HAVE_PREV) &&
260256
(fr->fr_prev_frame_type == HTTP_FRAME_HEADERS ||
261-
fr->fr_prev_frame_type == HTTP_FRAME_PUSH_PROMISE ||
262257
fr->fr_prev_frame_type == HTTP_FRAME_CONTINUATION ) &&
263258
0 == (fr->fr_prev_hfh_flags & HFHF_END_HEADERS))
264259
{
@@ -307,47 +302,17 @@ prepare_for_payload (struct lsquic_frame_reader *fr)
307302
fr->fr_state.reader_type = READER_HEADERS;
308303
break;
309304
case HTTP_FRAME_PUSH_PROMISE:
310-
if (fr->fr_flags & FRF_SERVER)
311-
{
312-
LSQ_INFO("clients should not push promised");
313-
fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id,
305+
LSQ_INFO("received PUSH_PROMISE but push promises are not supported");
306+
fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id,
314307
FR_ERR_UNEXPECTED_PUSH);
315-
return -1;
316-
}
317-
if (fr->fr_max_headers_sz &&
318-
fr->fr_state.payload_length > fr->fr_max_headers_sz)
319-
goto headers_too_large;
320-
fr->fr_state.by_type.headers_state.frame_type = HTTP_FRAME_PUSH_PROMISE;
321-
fr->fr_state.by_type.headers_state.nread = 0;
322-
fr->fr_state.by_type.headers_state.pesw_nread = 0;
323-
fr->fr_state.by_type.headers_state.pseh = 0;
324-
if (fr->fr_state.header.hfh_flags & HFHF_PADDED)
325-
fr->fr_state.by_type.headers_state.pesw_size = 5;
326-
else
327-
{
328-
fr->fr_state.by_type.headers_state.pad_length = 0;
329-
fr->fr_state.by_type.headers_state.pesw_size = 4;
330-
}
331-
LSQ_DEBUG("pesw size: %u; payload length: %u; flags: 0x%X",
332-
fr->fr_state.by_type.headers_state.pesw_size,
333-
fr->fr_state.payload_length, fr->fr_state.header.hfh_flags);
334-
if (fr->fr_state.by_type.headers_state.pesw_size >
335-
fr->fr_state.payload_length)
336-
{
337-
LSQ_INFO("Invalid headers frame: payload length too small");
338-
errno = EBADMSG;
339-
return -1;
340-
}
341-
fr->fr_state.reader_type = READER_PUSH_PROMISE;
342-
break;
308+
return -1;
343309
case HTTP_FRAME_CONTINUATION:
344310
if (0 == (fr->fr_flags & FRF_HAVE_PREV))
345311
{
346312
LSQ_INFO("Framing error: unexpected CONTINUATION");
347313
return -1;
348314
}
349315
if (!(fr->fr_prev_frame_type == HTTP_FRAME_HEADERS ||
350-
fr->fr_prev_frame_type == HTTP_FRAME_PUSH_PROMISE ||
351316
fr->fr_prev_frame_type == HTTP_FRAME_CONTINUATION))
352317
{
353318
LSQ_INFO("Framing error: unexpected CONTINUATION");
@@ -591,7 +556,7 @@ decode_and_pass_payload (struct lsquic_frame_reader *fr)
591556
}
592557
}
593558
hset = fr->fr_hsi_if->hsi_create_header_set(fr->fr_hsi_ctx, target_stream,
594-
READER_PUSH_PROMISE == fr->fr_state.reader_type);
559+
0);
595560
if (!hset)
596561
{
597562
err = FR_ERR_OTHER_ERROR;
@@ -658,31 +623,17 @@ decode_and_pass_payload (struct lsquic_frame_reader *fr)
658623
sizeof(stream_id32));
659624
uh->uh_stream_id = ntohl(stream_id32);
660625
uh->uh_oth_stream_id = hs->oth_stream_id;
661-
if (HTTP_FRAME_HEADERS == fr->fr_state.by_type.headers_state.frame_type)
662-
{
663-
uh->uh_weight = hs->weight;
664-
uh->uh_exclusive = hs->exclusive;
665-
uh->uh_flags = 0;
666-
}
667-
else
668-
{
669-
assert(HTTP_FRAME_PUSH_PROMISE ==
670-
fr->fr_state.by_type.headers_state.frame_type);
671-
uh->uh_weight = 0; /* Zero unused value */
672-
uh->uh_exclusive = 0; /* Zero unused value */
673-
uh->uh_flags = UH_PP;
674-
}
626+
uh->uh_weight = hs->weight;
627+
uh->uh_exclusive = hs->exclusive;
628+
uh->uh_flags = 0;
675629
if (fr->fr_state.header.hfh_flags & HFHF_END_STREAM)
676630
uh->uh_flags |= UH_FIN;
677631
if (fr->fr_hsi_if == lsquic_http1x_if)
678632
uh->uh_flags |= UH_H1H;
679633
uh->uh_hset = hset;
680634

681635
EV_LOG_HTTP_HEADERS_IN(LSQUIC_LOG_CONN_ID, fr->fr_flags & FRF_SERVER, uh);
682-
if (HTTP_FRAME_HEADERS == fr->fr_state.by_type.headers_state.frame_type)
683-
fr->fr_callbacks->frc_on_headers(fr->fr_cb_ctx, uh);
684-
else
685-
fr->fr_callbacks->frc_on_push_promise(fr->fr_cb_ctx, uh);
636+
fr->fr_callbacks->frc_on_headers(fr->fr_cb_ctx, uh);
686637
#if LSQUIC_CONN_STATS
687638
fr->fr_conn_stats->in.headers_comp += fr->fr_header_block_sz;
688639
#endif
@@ -802,48 +753,6 @@ read_headers (struct lsquic_frame_reader *fr)
802753
}
803754

804755

805-
static int
806-
read_push_promise_pesw (struct lsquic_frame_reader *fr)
807-
{
808-
struct headers_state *hs = &fr->fr_state.by_type.headers_state;
809-
ssize_t nr = fr->fr_read(fr->fr_stream, hs->pesw + hs->pesw_nread,
810-
hs->pesw_size - hs->pesw_nread);
811-
if (nr <= 0)
812-
RETURN_ERROR(nr);
813-
hs->pesw_nread += nr;
814-
if (hs->pesw_nread == hs->pesw_size)
815-
{
816-
unsigned char *p = hs->pesw;
817-
if (fr->fr_state.header.hfh_flags & HFHF_PADDED)
818-
hs->pad_length = *p++;
819-
p[0] &= ~0x80; /* Clear reserved bit. Note: modifying pesw buffer. */
820-
memcpy(&hs->oth_stream_id, p, sizeof(hs->oth_stream_id));
821-
hs->oth_stream_id = ntohl(hs->oth_stream_id);
822-
p += 4;
823-
assert(p - hs->pesw == hs->pesw_size);
824-
if (hs->pesw_size + hs->pad_length > fr->fr_state.payload_length)
825-
{
826-
LSQ_INFO("Invalid PUSH_PROMISE frame: pesw length and padding length "
827-
"are larger than the payload length");
828-
errno = EBADMSG;
829-
return -1;
830-
}
831-
}
832-
return 0;
833-
}
834-
835-
836-
static int
837-
read_push_promise (struct lsquic_frame_reader *fr)
838-
{
839-
struct headers_state *hs = &fr->fr_state.by_type.headers_state;
840-
if (hs->pesw_nread < hs->pesw_size)
841-
return read_push_promise_pesw(fr);
842-
else
843-
return read_headers_block_fragment_and_padding(fr);
844-
}
845-
846-
847756
static int
848757
read_contin (struct lsquic_frame_reader *fr)
849758
{
@@ -954,8 +863,6 @@ read_payload (struct lsquic_frame_reader *fr)
954863
{
955864
case READER_HEADERS:
956865
return read_headers(fr);
957-
case READER_PUSH_PROMISE:
958-
return read_push_promise(fr);
959866
case READER_CONTIN:
960867
return read_contin(fr);
961868
case READER_SETTINGS:

src/liblsquic/lsquic_frame_reader.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ enum frame_reader_error
5656
struct frame_reader_callbacks
5757
{
5858
void (*frc_on_headers) (void *frame_cb_ctx, struct uncompressed_headers *);
59-
void (*frc_on_push_promise) (void *frame_cb_ctx, struct uncompressed_headers *);
6059
void (*frc_on_settings) (void *frame_cb_ctx, uint16_t setting_id,
6160
uint32_t setting_value);
6261
void (*frc_on_priority) (void *frame_cb_ctx, lsquic_stream_id_t stream_id,

src/liblsquic/lsquic_frame_writer.c

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -487,58 +487,6 @@ lsquic_frame_writer_write_headers (struct lsquic_frame_writer *fw,
487487
}
488488

489489

490-
int
491-
lsquic_frame_writer_write_promise (struct lsquic_frame_writer *fw,
492-
lsquic_stream_id_t stream_id64, lsquic_stream_id_t promised_stream_id64,
493-
const struct lsquic_http_headers *headers)
494-
{
495-
uint32_t stream_id = stream_id64;
496-
uint32_t promised_stream_id = promised_stream_id64;
497-
struct header_framer_ctx hfc;
498-
struct http_push_promise_frame push_frame;
499-
unsigned char *buf;
500-
int s;
501-
502-
fiu_return_on("frame_writer/writer_promise", -1);
503-
504-
if (fw->fw_max_header_list_sz && 0 != check_headers_size(fw, headers))
505-
return -1;
506-
507-
if (0 != check_headers_case(fw, headers))
508-
return -1;
509-
510-
if (have_oversize_strings(headers))
511-
return -1;
512-
513-
hfc_init(&hfc, fw, fw->fw_max_frame_sz, HTTP_FRAME_PUSH_PROMISE,
514-
stream_id, 0);
515-
516-
promised_stream_id = htonl(promised_stream_id);
517-
memcpy(push_frame.hppf_promised_id, &promised_stream_id, 4);
518-
s = hfc_write(&hfc, &push_frame, sizeof(struct http_push_promise_frame));
519-
if (s < 0)
520-
return s;
521-
522-
buf = malloc(MAX_COMP_HEADER_FIELD_SIZE);
523-
if (!buf)
524-
return -1;
525-
526-
s = write_headers(fw, headers, &hfc, buf, MAX_COMP_HEADER_FIELD_SIZE);
527-
if (s != 0)
528-
{
529-
free(buf);
530-
return -1;
531-
}
532-
533-
free(buf);
534-
535-
EV_LOG_GENERATED_HTTP_PUSH_PROMISE(LSQUIC_LOG_CONN_ID, stream_id,
536-
htonl(promised_stream_id), headers);
537-
hfc_terminate_frame(&hfc, HFHF_END_HEADERS);
538-
return lsquic_frame_writer_flush(fw);
539-
}
540-
541-
542490
void
543491
lsquic_frame_writer_max_header_list_size (struct lsquic_frame_writer *fw,
544492
uint32_t max_size)

src/liblsquic/lsquic_frame_writer.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,6 @@ lsquic_frame_writer_write_priority (struct lsquic_frame_writer *,
5656
lsquic_stream_id_t stream_id, int exclusive,
5757
lsquic_stream_id_t stream_dep_id, unsigned priority);
5858

59-
int
60-
lsquic_frame_writer_write_promise (struct lsquic_frame_writer *,
61-
lsquic_stream_id_t stream_id, lsquic_stream_id_t promised_stream_id,
62-
const struct lsquic_http_headers *headers);
63-
6459
void
6560
lsquic_frame_writer_max_header_list_size (struct lsquic_frame_writer *,
6661
uint32_t max_size);

0 commit comments

Comments
 (0)