Skip to content

Commit 359c5e3

Browse files
committed
Introduce hyper::ext::Http1RawMessage
1 parent 4899703 commit 359c5e3

File tree

14 files changed

+195
-145
lines changed

14 files changed

+195
-145
lines changed

capi/include/hyper.h

-26
Original file line numberDiff line numberDiff line change
@@ -391,17 +391,6 @@ void hyper_clientconn_options_exec(struct hyper_clientconn_options *opts,
391391
*/
392392
enum hyper_code hyper_clientconn_options_http2(struct hyper_clientconn_options *opts, int enabled);
393393

394-
/*
395-
Set the whether to include a copy of the raw headers in responses
396-
received on this connection.
397-
398-
Pass `0` to disable, `1` to enable.
399-
400-
If enabled, see `hyper_response_headers_raw()` for usage.
401-
*/
402-
enum hyper_code hyper_clientconn_options_headers_raw(struct hyper_clientconn_options *opts,
403-
int enabled);
404-
405394
/*
406395
Frees a `hyper_error`.
407396
*/
@@ -557,21 +546,6 @@ const uint8_t *hyper_response_reason_phrase(const struct hyper_response *resp);
557546
*/
558547
size_t hyper_response_reason_phrase_len(const struct hyper_response *resp);
559548

560-
/*
561-
Get a reference to the full raw headers of this response.
562-
563-
You must have enabled `hyper_clientconn_options_headers_raw()`, or this
564-
will return NULL.
565-
566-
The returned `hyper_buf *` is just a reference, owned by the response.
567-
You need to make a copy if you wish to use it after freeing the
568-
response.
569-
570-
The buffer is not null-terminated, see the `hyper_buf` functions for
571-
getting the bytes and length.
572-
*/
573-
const struct hyper_buf *hyper_response_headers_raw(const struct hyper_response *resp);
574-
575549
/*
576550
Get the HTTP version used by this response.
577551

src/client/conn.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,7 @@ pub struct Builder {
192192
h1_preserve_header_order: bool,
193193
h1_read_buf_exact_size: Option<usize>,
194194
h1_max_buf_size: Option<usize>,
195-
#[cfg(feature = "ffi")]
196-
h1_headers_raw: bool,
195+
h1_raw_message: bool,
197196
#[cfg(feature = "http2")]
198197
h2_builder: proto::h2::client::Config,
199198
version: Proto,
@@ -603,8 +602,7 @@ impl Builder {
603602
#[cfg(feature = "ffi")]
604603
h1_preserve_header_order: false,
605604
h1_max_buf_size: None,
606-
#[cfg(feature = "ffi")]
607-
h1_headers_raw: false,
605+
h1_raw_message: false,
608606
#[cfg(feature = "http2")]
609607
h2_builder: Default::default(),
610608
#[cfg(feature = "http1")]
@@ -811,9 +809,16 @@ impl Builder {
811809
self
812810
}
813811

814-
#[cfg(feature = "ffi")]
815-
pub(crate) fn http1_headers_raw(&mut self, enabled: bool) -> &mut Self {
816-
self.h1_headers_raw = enabled;
812+
/// Set whether to include the raw bytes of HTTP/1 responses.
813+
///
814+
/// This will store a [`Http1RawMessage`](crate::ext::Http1RawMessage)
815+
/// in extensions of HTTP/1 responses.
816+
///
817+
/// Note that this setting does not affect HTTP/2.
818+
///
819+
/// Default is false.
820+
pub fn http1_raw_message(&mut self, enabled: bool) -> &mut Self {
821+
self.h1_raw_message = enabled;
817822
self
818823
}
819824

@@ -1033,8 +1038,9 @@ impl Builder {
10331038
conn.set_h09_responses();
10341039
}
10351040

1036-
#[cfg(feature = "ffi")]
1037-
conn.set_raw_headers(opts.h1_headers_raw);
1041+
if opts.h1_raw_message {
1042+
conn.set_h1_raw_message();
1043+
}
10381044

10391045
if let Some(sz) = opts.h1_read_buf_exact_size {
10401046
conn.set_read_buf_exact_size(sz);

src/ext.rs

+36
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use http::HeaderMap;
1010
use std::collections::HashMap;
1111
#[cfg(feature = "http2")]
1212
use std::fmt;
13+
use std::ops::Deref;
1314

1415
#[cfg(any(feature = "http1", feature = "ffi"))]
1516
mod h1_reason_phrase;
@@ -131,6 +132,41 @@ impl HeaderCaseMap {
131132
}
132133
}
133134

135+
/// Raw bytes of HTTP/1 requests and responses.
136+
///
137+
/// Included in HTTP/1 requests and responses when `http1_raw_message` is set
138+
/// to true.
139+
#[derive(Clone, Debug, PartialEq, PartialOrd, Hash)]
140+
pub struct Http1RawMessage {
141+
pub(crate) buf: Bytes,
142+
}
143+
144+
impl Deref for Http1RawMessage {
145+
type Target = [u8];
146+
147+
fn deref(&self) -> &Self::Target {
148+
&self.buf
149+
}
150+
}
151+
152+
impl AsRef<Bytes> for Http1RawMessage {
153+
fn as_ref(&self) -> &Bytes {
154+
&self.buf
155+
}
156+
}
157+
158+
impl AsRef<[u8]> for Http1RawMessage {
159+
fn as_ref(&self) -> &[u8] {
160+
&self
161+
}
162+
}
163+
164+
impl From<Http1RawMessage> for Bytes {
165+
fn from(message: Http1RawMessage) -> Self {
166+
message.buf
167+
}
168+
}
169+
134170
#[cfg(feature = "ffi")]
135171
#[derive(Clone, Debug)]
136172
/// Hashmap<Headername, numheaders with that name>

src/ffi/client.rs

-14
Original file line numberDiff line numberDiff line change
@@ -166,17 +166,3 @@ ffi_fn! {
166166
}
167167
}
168168
}
169-
170-
ffi_fn! {
171-
/// Set the whether to include a copy of the raw headers in responses
172-
/// received on this connection.
173-
///
174-
/// Pass `0` to disable, `1` to enable.
175-
///
176-
/// If enabled, see `hyper_response_headers_raw()` for usage.
177-
fn hyper_clientconn_options_headers_raw(opts: *mut hyper_clientconn_options, enabled: c_int) -> hyper_code {
178-
let opts = non_null! { &mut *opts ?= hyper_code::HYPERE_INVALID_ARG };
179-
opts.builder.http1_headers_raw(enabled != 0);
180-
hyper_code::HYPERE_OK
181-
}
182-
}

src/ffi/http_types.rs

+1-24
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use bytes::Bytes;
22
use libc::{c_int, size_t};
33
use std::ffi::c_void;
44

5-
use super::body::{hyper_body, hyper_buf};
5+
use super::body::hyper_body;
66
use super::error::hyper_code;
77
use super::task::{hyper_task_return_type, AsTaskType};
88
use super::{UserDataPointer, HYPER_ITER_CONTINUE};
@@ -25,8 +25,6 @@ pub struct hyper_headers {
2525
orig_order: OriginalHeaderOrder,
2626
}
2727

28-
pub(crate) struct RawHeaders(pub(crate) hyper_buf);
29-
3028
pub(crate) struct OnInformational {
3129
func: hyper_request_on_informational_callback,
3230
data: UserDataPointer,
@@ -278,27 +276,6 @@ ffi_fn! {
278276
}
279277
}
280278

281-
ffi_fn! {
282-
/// Get a reference to the full raw headers of this response.
283-
///
284-
/// You must have enabled `hyper_clientconn_options_headers_raw()`, or this
285-
/// will return NULL.
286-
///
287-
/// The returned `hyper_buf *` is just a reference, owned by the response.
288-
/// You need to make a copy if you wish to use it after freeing the
289-
/// response.
290-
///
291-
/// The buffer is not null-terminated, see the `hyper_buf` functions for
292-
/// getting the bytes and length.
293-
fn hyper_response_headers_raw(resp: *const hyper_response) -> *const hyper_buf {
294-
let resp = non_null!(&*resp ?= std::ptr::null());
295-
match resp.0.extensions().get::<RawHeaders>() {
296-
Some(raw) => &raw.0,
297-
None => std::ptr::null(),
298-
}
299-
} ?= std::ptr::null()
300-
}
301-
302279
ffi_fn! {
303280
/// Get the HTTP version used by this response.
304281
///

src/proto/h1/conn.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ where
6666
h09_responses: false,
6767
#[cfg(feature = "ffi")]
6868
on_informational: None,
69-
#[cfg(feature = "ffi")]
70-
raw_headers: false,
69+
h1_raw_message: false,
7170
notify_read: false,
7271
reading: Reading::Init,
7372
writing: Writing::Init,
@@ -135,9 +134,8 @@ where
135134
self.state.allow_half_close = true;
136135
}
137136

138-
#[cfg(feature = "ffi")]
139-
pub(crate) fn set_raw_headers(&mut self, enabled: bool) {
140-
self.state.raw_headers = enabled;
137+
pub(crate) fn set_h1_raw_message(&mut self) {
138+
self.state.h1_raw_message = true;
141139
}
142140

143141
pub(crate) fn into_inner(self) -> (I, Bytes) {
@@ -210,8 +208,7 @@ where
210208
h09_responses: self.state.h09_responses,
211209
#[cfg(feature = "ffi")]
212210
on_informational: &mut self.state.on_informational,
213-
#[cfg(feature = "ffi")]
214-
raw_headers: self.state.raw_headers,
211+
h1_raw_message: self.state.h1_raw_message,
215212
}
216213
)) {
217214
Ok(msg) => msg,
@@ -838,8 +835,7 @@ struct State {
838835
/// received.
839836
#[cfg(feature = "ffi")]
840837
on_informational: Option<crate::ffi::OnInformational>,
841-
#[cfg(feature = "ffi")]
842-
raw_headers: bool,
838+
h1_raw_message: bool,
843839
/// Set to true when the Dispatcher should poll read operations
844840
/// again. See the `maybe_notify` method for more.
845841
notify_read: bool,

src/proto/h1/io.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,7 @@ where
200200
h09_responses: parse_ctx.h09_responses,
201201
#[cfg(feature = "ffi")]
202202
on_informational: parse_ctx.on_informational,
203-
#[cfg(feature = "ffi")]
204-
raw_headers: parse_ctx.raw_headers,
203+
h1_raw_message: parse_ctx.h1_raw_message,
205204
},
206205
)? {
207206
Some(msg) => {
@@ -745,8 +744,7 @@ mod tests {
745744
h09_responses: false,
746745
#[cfg(feature = "ffi")]
747746
on_informational: &mut None,
748-
#[cfg(feature = "ffi")]
749-
raw_headers: false,
747+
h1_raw_message: false,
750748
};
751749
assert!(buffered
752750
.parse::<ClientTransaction>(cx, parse_ctx)

src/proto/h1/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ pub(crate) struct ParseContext<'a> {
8888
h09_responses: bool,
8989
#[cfg(feature = "ffi")]
9090
on_informational: &'a mut Option<crate::ffi::OnInformational>,
91-
#[cfg(feature = "ffi")]
92-
raw_headers: bool,
91+
h1_raw_message: bool,
9392
}
9493

9594
/// Passed to Http1Transaction::encode

0 commit comments

Comments
 (0)