Skip to content

Commit 74a2ad6

Browse files
committed
Use new hpack library
1 parent df19f53 commit 74a2ad6

10 files changed

+65
-55
lines changed

lib/client_connection.ml

+9-7
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ let handle_headers_block
402402
t.receiving_headers_for_stream <- None;
403403
let parse_state' = AB.feed parse_state' `Eof in
404404
match parse_state' with
405-
| Done (_, Ok headers) ->
405+
| Done (_, headers) ->
406406
if not is_trailers then
407407
(* `handle_headers` will take care of transitioning the stream state *)
408408
let end_stream = partial_headers.end_stream in
@@ -425,7 +425,7 @@ let handle_headers_block
425425
(* From RFC7540§4.3:
426426
* A decoding error in a header block MUST be treated as a connection
427427
* error (Section 5.4.1) of type COMPRESSION_ERROR. *)
428-
| Done (_, Error _) | Partial _ ->
428+
| Partial _ ->
429429
report_connection_error t Error.CompressionError
430430
| Fail (_, _, message) ->
431431
report_connection_error
@@ -451,7 +451,7 @@ let create_partial_headers t flags headers_block =
451451
{ Stream.parse_state =
452452
AB.parse
453453
~initial_buffer_size
454-
(Hpack.Decoder.decode_headers t.hpack_decoder)
454+
(Hpack.Decoder.headers t.hpack_decoder)
455455
; end_stream = Flags.test_end_stream flags
456456
}
457457

@@ -493,7 +493,7 @@ let process_trailer_headers t respd active_response frame_header headers_block =
493493
else
494494
let partial_headers =
495495
{ Stream.parse_state =
496-
AB.parse (Hpack.Decoder.decode_headers t.hpack_decoder)
496+
AB.parse (Hpack.Decoder.headers t.hpack_decoder)
497497
(* obviously true at this point. *)
498498
; end_stream
499499
}
@@ -846,7 +846,8 @@ let process_settings_frame t { Frame.frame_header; _ } settings =
846846
* size of the header compression table used to decode header
847847
* blocks, in octets. *)
848848
t.settings.header_table_size <- x;
849-
Hpack.Encoder.set_capacity t.hpack_encoder x
849+
let table_size = min t.config.encoder_table_size x in
850+
Hpack.Encoder.change_table_size t.hpack_encoder table_size
850851
| EnablePush, x ->
851852
(* We've already verified that this setting is either 0 or 1 in the
852853
* call to `Settings.check_settings_list` above. *)
@@ -1164,6 +1165,7 @@ let create ?(config = Config.default) ?push_handler ~error_handler =
11641165
(* If the caller is not going to process PUSH_PROMISE frames, just
11651166
* disable it. *)
11661167
config.enable_server_push && push_handler != default_push_handler
1168+
; header_table_size = config.decoder_table_size
11671169
}
11681170
in
11691171
let rec connection_preface_handler recv_frame settings_list =
@@ -1243,8 +1245,8 @@ let create ?(config = Config.default) ?push_handler ~error_handler =
12431245
(* From RFC7540§4.3:
12441246
* Header compression is stateful. One compression context and one
12451247
* decompression context are used for the entire connection. *)
1246-
; hpack_encoder = Hpack.Encoder.(create settings.header_table_size)
1247-
; hpack_decoder = Hpack.Decoder.(create settings.header_table_size)
1248+
; hpack_encoder = Hpack.Encoder.create ~max_size:(min Settings.default_settings.header_table_size config.encoder_table_size) ()
1249+
; hpack_decoder = Hpack.Decoder.create ~max_size_limit:config.decoder_table_size ()
12481250
}
12491251
in
12501252
let t = Lazy.force t in

lib/config.ml

+4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ type t =
3939
; enable_server_push : bool
4040
; max_concurrent_streams : int
4141
; initial_window_size : int
42+
; encoder_table_size : int
43+
; decoder_table_size : int
4244
}
4345

4446
let default =
@@ -71,4 +73,6 @@ let default =
7173
* Indicates the sender's initial window size (in octets) for
7274
* stream-level flow control. *)
7375
; initial_window_size = Settings.WindowSize.default_initial_window_size
76+
; encoder_table_size = 0x1000
77+
; decoder_table_size = 0x1000
7478
}

lib/h2.mli

+10-8
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,10 @@ module Headers : sig
268268
(** [to_rev_list t] is the association list of header fields contained in [t]
269269
in {i reverse} transmission order. *)
270270

271-
val add : t -> ?sensitive:bool -> name -> value -> t
272-
(** [add t ?sensitive name value] is a collection of header fields that is
271+
val add : t -> ?never_index:bool -> name -> value -> t
272+
(** [add t ?never_index name value] is a collection of header fields that is
273273
the same as [t] except with [(name, value)] added at the end of the
274-
trasmission order. Additionally, [sensitive] specifies whether this
274+
trasmission order. Additionally, [never_index] specifies whether this
275275
header field should not be compressed by HPACK and instead encoded as a
276276
never-indexed literal (see
277277
{{:https://tools.ietf.org/html/rfc7541#section-7.1.3} RFC7541§7.1.3} for
@@ -281,10 +281,10 @@ module Headers : sig
281281
282282
- [get (add t name value) name = Some value] *)
283283

284-
val add_unless_exists : t -> ?sensitive:bool -> name -> value -> t
285-
(** [add_unless_exists t ?sensitive name value] is a collection of header
284+
val add_unless_exists : t -> ?never_index:bool -> name -> value -> t
285+
(** [add_unless_exists t ?never_index name value] is a collection of header
286286
fields that is the same as [t] if [t] already inclues [name], and
287-
otherwise is equivalent to [add t ?sensitive name value]. *)
287+
otherwise is equivalent to [add t ?never_index name value]. *)
288288

289289
val add_list : t -> (name * value) list -> t
290290
(** [add_list t assoc] is a collection of header fields that is the same as
@@ -312,8 +312,8 @@ add_multi t ["name1", ["x", "y"]; "name2", ["p", "q"]] = add_list
312312
equal to [name]. If [t] contains multiple header fields whose name is
313313
[name], they will all be removed. *)
314314

315-
val replace : t -> ?sensitive:bool -> name -> value -> t
316-
(** [replace t ?sensitive name value] is a collection of header fields that
315+
val replace : t -> ?never_index:bool -> name -> value -> t
316+
(** [replace t ?never_index name value] is a collection of header fields that
317317
is the same as [t] except with all header fields with a name equal to
318318
[name] removed and replaced with a single header field whose name is
319319
[name] and whose value is [value]. This new header field will appear in
@@ -588,6 +588,8 @@ module Config : sig
588588
; initial_window_size : int
589589
(** [initial_window_size] specifies the initial window size for flow
590590
control tokens. Defaults to [65535] *)
591+
; encoder_table_size : int (** Defaults to [4096] *)
592+
; decoder_table_size : int (** Defaults to [4096] *)
591593
}
592594

593595
val default : t

lib/headers.ml

+9-9
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,18 @@ type name = string
3636

3737
type value = string
3838

39-
type header = Hpack.header =
39+
type header = Hpack.Header.t = private
4040
{ name : name
4141
; value : value
42-
; sensitive : bool
42+
; never_index : bool
4343
}
4444

4545
type t = header list
4646

4747
let empty : t = []
4848

4949
let of_rev_list hs =
50-
List.map (fun (name, value) -> { name; value; sensitive = false }) hs
50+
List.map (fun (name, value) -> Hpack.Header.make name value) hs
5151

5252
let of_list t = of_rev_list (List.rev t)
5353

@@ -108,7 +108,7 @@ let rec mem t name =
108108
false
109109

110110
(* TODO: do we need to keep a list of never indexed fields? *)
111-
let add t ?(sensitive = false) name value = { name; value; sensitive } :: t
111+
let add t ?(never_index = false) name value = Hpack.Header.make ~never_index name value :: t
112112

113113
let add_list t ls = of_rev_list ls @ t (* XXX(seliopou): do better here *)
114114

@@ -120,17 +120,17 @@ let add_multi =
120120
| [] ->
121121
loop_outer t lss
122122
| v :: vs' ->
123-
loop_inner ({ name = n; value = v; sensitive = false } :: t) n vs' lss
123+
loop_inner (Hpack.Header.make n v :: t) n vs' lss
124124
in
125125
loop_outer
126126

127-
let add_unless_exists t ?(sensitive = false) name value =
127+
let add_unless_exists t ?(never_index = false) name value =
128128
if mem t name then
129129
t
130130
else
131-
{ name; value; sensitive } :: t
131+
Hpack.Header.make ~never_index name value :: t
132132

133-
let replace t ?(sensitive = false) name value =
133+
let replace t ?(never_index = false) name value =
134134
let rec loop t n nv seen =
135135
match t with
136136
| [] ->
@@ -144,7 +144,7 @@ let replace t ?(sensitive = false) name value =
144144
else
145145
nv' :: loop t n nv false
146146
in
147-
try loop t name { name; value; sensitive } false with Local -> t
147+
try loop t name (Hpack.Header.make ~never_index name value) false with Local -> t
148148

149149
let remove t name =
150150
let rec loop s n seen =

lib/serialize.ml

+4-10
Original file line numberDiff line numberDiff line change
@@ -481,21 +481,18 @@ module Writer = struct
481481
Hpack.Encoder.encode_header
482482
hpack_encoder
483483
faraday
484-
{ Headers.name = ":method"
485-
; value = Httpaf.Method.to_string meth
486-
; sensitive = false
487-
};
484+
(Hpack.Header.make ":method" (Httpaf.Method.to_string meth));
488485
if meth <> `CONNECT then (
489486
(* From RFC7540§8.3:
490487
* The :scheme and :path pseudo-header fields MUST be omitted. *)
491488
Hpack.Encoder.encode_header
492489
hpack_encoder
493490
faraday
494-
{ Headers.name = ":path"; value = target; sensitive = false };
491+
(Hpack.Header.make ":path" target);
495492
Hpack.Encoder.encode_header
496493
hpack_encoder
497494
faraday
498-
{ Headers.name = ":scheme"; value = scheme; sensitive = false });
495+
(Hpack.Header.make ":scheme" scheme));
499496
encode_headers hpack_encoder faraday headers;
500497
chunk_header_block_fragments t frame_info ~write_frame faraday
501498

@@ -518,10 +515,7 @@ module Writer = struct
518515
Hpack.Encoder.encode_header
519516
hpack_encoder
520517
faraday
521-
{ Headers.name = ":status"
522-
; value = Status.to_string status
523-
; sensitive = false
524-
};
518+
(Hpack.Header.make ":status" (Status.to_string status));
525519
encode_headers hpack_encoder faraday headers;
526520
let has_priority = match priority with Some _ -> true | None -> false in
527521
chunk_header_block_fragments

lib/server_connection.ml

+9-7
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ let handle_headers_block
328328
t.receiving_headers_for_stream <- None;
329329
let parse_state' = AB.feed parse_state' `Eof in
330330
match parse_state' with
331-
| Done (_, Ok headers) ->
331+
| Done (_, headers) ->
332332
if not is_trailers then (
333333
(* Note:
334334
* the highest stream identifier that the server has seen is set here
@@ -364,7 +364,7 @@ let handle_headers_block
364364
(* From RFC7540§4.3:
365365
* A decoding error in a header block MUST be treated as a connection
366366
* error (Section 5.4.1) of type COMPRESSION_ERROR. *)
367-
| Done (_, Error _) | Partial _ ->
367+
| Partial _ ->
368368
report_connection_error t Error.CompressionError
369369
| Fail (_, _, message) ->
370370
report_connection_error
@@ -436,7 +436,7 @@ let open_stream t frame_header ?priority headers_block =
436436
{ Stream.parse_state =
437437
AB.parse
438438
~initial_buffer_size
439-
(Hpack.Decoder.decode_headers t.hpack_decoder)
439+
(Hpack.Decoder.headers t.hpack_decoder)
440440
; end_stream = Flags.test_end_stream flags
441441
}
442442
in
@@ -472,7 +472,7 @@ let process_trailer_headers t reqd active_stream frame_header headers_block =
472472
else
473473
let partial_headers =
474474
{ Stream.parse_state =
475-
AB.parse (Hpack.Decoder.decode_headers t.hpack_decoder)
475+
AB.parse (Hpack.Decoder.headers t.hpack_decoder)
476476
(* obviously true at this point. *)
477477
; end_stream
478478
}
@@ -832,7 +832,8 @@ let process_settings_frame t { Frame.frame_header; _ } settings =
832832
* size of the header compression table used to decode header
833833
* blocks, in octets. *)
834834
t.settings.header_table_size <- x;
835-
Hpack.Encoder.set_capacity t.hpack_encoder x
835+
let table_size = min t.config.encoder_table_size x in
836+
Hpack.Encoder.change_table_size t.hpack_encoder table_size
836837
| EnablePush, x ->
837838
(* We've already verified that this setting is either 0 or 1 in the
838839
* call to `Settings.check_settings_list` above. *)
@@ -1093,6 +1094,7 @@ let create
10931094
; max_concurrent_streams = config.max_concurrent_streams
10941095
; initial_window_size = config.initial_window_size
10951096
; enable_push = config.enable_server_push
1097+
; header_table_size = config.decoder_table_size
10961098
}
10971099
in
10981100
let writer = Writer.create settings.max_frame_size in
@@ -1200,8 +1202,8 @@ let create
12001202
; did_send_go_away = false
12011203
; unacked_settings = 0
12021204
; wakeup_writer = ref default_wakeup_writer
1203-
; hpack_encoder = Hpack.Encoder.(create settings.header_table_size)
1204-
; hpack_decoder = Hpack.Decoder.(create settings.header_table_size)
1205+
; hpack_encoder = Hpack.Encoder.create ~max_size:(min Settings.default_settings.header_table_size config.encoder_table_size) ()
1206+
; hpack_decoder = Hpack.Decoder.create ~max_size_limit:config.decoder_table_size ()
12051207
}
12061208
in
12071209
Lazy.force t

lib/settings.ml

+6
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,10 @@ let settings_for_the_connection settings =
211211
else
212212
settings_list
213213
in
214+
let settings_list =
215+
if settings.header_table_size <> default_settings.header_table_size then
216+
(HeaderTableSize, settings.header_table_size) :: settings_list
217+
else
218+
settings_list
219+
in
214220
settings_list

lib/stream.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ module AB = Angstrom.Buffered
3434
module Writer = Serialize.Writer
3535

3636
type partial_headers =
37-
{ mutable parse_state : (Headers.t, Hpack.error) result AB.state
37+
{ mutable parse_state : Headers.header list AB.state
3838
; end_stream : bool
3939
}
4040

lib_test/test_h2_client.ml

+7-7
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ module Client_connection_tests = struct
192192

193193
(* Well-formed HEADERS + CONTINUATION frames. *)
194194
let header_and_continuation_frames =
195-
let hpack_encoder = Hpack.Encoder.create 4096 in
195+
let hpack_encoder = Hpack.Encoder.create () in
196196
let headers =
197197
{ Frame.frame_header =
198198
{ payload_length = 0
@@ -303,7 +303,7 @@ module Client_connection_tests = struct
303303
true
304304
(Flags.test_end_stream frame.frame_header.flags);
305305
report_write_result t (`Ok lenv);
306-
let hpack_encoder = Hpack.Encoder.create 4096 in
306+
let hpack_encoder = Hpack.Encoder.create () in
307307
write_response t hpack_encoder (Response.create `OK);
308308
Alcotest.(check bool) "Response handler called" true !handler_called
309309

@@ -350,7 +350,7 @@ module Client_connection_tests = struct
350350
true
351351
(Flags.test_end_stream frame.frame_header.flags);
352352
report_write_result t (`Ok lenv);
353-
let hpack_encoder = Hpack.Encoder.create 4096 in
353+
let hpack_encoder = Hpack.Encoder.create () in
354354
write_response
355355
t
356356
hpack_encoder
@@ -405,7 +405,7 @@ module Client_connection_tests = struct
405405
true
406406
(Flags.test_end_stream frame.frame_header.flags);
407407
report_write_result t (`Ok lenv);
408-
let hpack_encoder = Hpack.Encoder.create 4096 in
408+
let hpack_encoder = Hpack.Encoder.create () in
409409
write_response
410410
t
411411
hpack_encoder
@@ -561,7 +561,7 @@ module Client_connection_tests = struct
561561
true
562562
(Flags.test_end_stream frame.frame_header.flags);
563563
report_write_result t (`Ok lenv);
564-
let hpack_encoder = Hpack.Encoder.create 4096 in
564+
let hpack_encoder = Hpack.Encoder.create () in
565565
write_response
566566
t
567567
hpack_encoder
@@ -635,7 +635,7 @@ module Client_connection_tests = struct
635635
true
636636
(Flags.test_end_stream frame.frame_header.flags);
637637
report_write_result t (`Ok lenv);
638-
let hpack_encoder = Hpack.Encoder.create 4096 in
638+
let hpack_encoder = Hpack.Encoder.create () in
639639
write_response
640640
t
641641
hpack_encoder
@@ -763,7 +763,7 @@ module Client_connection_tests = struct
763763
body"
764764
true
765765
(not (Stream.is_open stream));
766-
let hpack_encoder = Hpack.Encoder.create 4096 in
766+
let hpack_encoder = Hpack.Encoder.create () in
767767
write_response t hpack_encoder (Response.create `OK);
768768
Alcotest.(check bool) "Response handler called" true !handler_called;
769769
Alcotest.(check bool)

0 commit comments

Comments
 (0)