Skip to content

Commit

Permalink
Introduce hyper::ext::Http1RawMessage
Browse files Browse the repository at this point in the history
  • Loading branch information
nox committed Nov 16, 2023
1 parent 4899703 commit a7a51a9
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 133 deletions.
26 changes: 0 additions & 26 deletions capi/include/hyper.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,17 +391,6 @@ void hyper_clientconn_options_exec(struct hyper_clientconn_options *opts,
*/
enum hyper_code hyper_clientconn_options_http2(struct hyper_clientconn_options *opts, int enabled);

/*
Set the whether to include a copy of the raw headers in responses
received on this connection.
Pass `0` to disable, `1` to enable.
If enabled, see `hyper_response_headers_raw()` for usage.
*/
enum hyper_code hyper_clientconn_options_headers_raw(struct hyper_clientconn_options *opts,
int enabled);

/*
Frees a `hyper_error`.
*/
Expand Down Expand Up @@ -557,21 +546,6 @@ const uint8_t *hyper_response_reason_phrase(const struct hyper_response *resp);
*/
size_t hyper_response_reason_phrase_len(const struct hyper_response *resp);

/*
Get a reference to the full raw headers of this response.
You must have enabled `hyper_clientconn_options_headers_raw()`, or this
will return NULL.
The returned `hyper_buf *` is just a reference, owned by the response.
You need to make a copy if you wish to use it after freeing the
response.
The buffer is not null-terminated, see the `hyper_buf` functions for
getting the bytes and length.
*/
const struct hyper_buf *hyper_response_headers_raw(const struct hyper_response *resp);

/*
Get the HTTP version used by this response.
Expand Down
24 changes: 15 additions & 9 deletions src/client/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,7 @@ pub struct Builder {
h1_preserve_header_order: bool,
h1_read_buf_exact_size: Option<usize>,
h1_max_buf_size: Option<usize>,
#[cfg(feature = "ffi")]
h1_headers_raw: bool,
h1_raw_message: bool,
#[cfg(feature = "http2")]
h2_builder: proto::h2::client::Config,
version: Proto,
Expand Down Expand Up @@ -603,8 +602,7 @@ impl Builder {
#[cfg(feature = "ffi")]
h1_preserve_header_order: false,
h1_max_buf_size: None,
#[cfg(feature = "ffi")]
h1_headers_raw: false,
h1_raw_message: false,
#[cfg(feature = "http2")]
h2_builder: Default::default(),
#[cfg(feature = "http1")]
Expand Down Expand Up @@ -811,9 +809,16 @@ impl Builder {
self
}

#[cfg(feature = "ffi")]
pub(crate) fn http1_headers_raw(&mut self, enabled: bool) -> &mut Self {
self.h1_headers_raw = enabled;
/// Set whether to include the raw bytes of HTTP/1 requests and responses.
///
/// This will store a [`Http1RawMessage`](crate::ext::Http1RawMessage)
/// in extensions of HTTP/1 requests and responses.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
pub fn http1_raw_message(&mut self, enabled: bool) -> &mut Self {
self.h1_raw_message = enabled;
self
}

Expand Down Expand Up @@ -1033,8 +1038,9 @@ impl Builder {
conn.set_h09_responses();
}

#[cfg(feature = "ffi")]
conn.set_raw_headers(opts.h1_headers_raw);
if opts.h1_raw_message {
conn.set_h1_raw_message();
}

if let Some(sz) = opts.h1_read_buf_exact_size {
conn.set_read_buf_exact_size(sz);
Expand Down
36 changes: 36 additions & 0 deletions src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use http::HeaderMap;
use std::collections::HashMap;
#[cfg(feature = "http2")]
use std::fmt;
use std::ops::Deref;

#[cfg(any(feature = "http1", feature = "ffi"))]
mod h1_reason_phrase;
Expand Down Expand Up @@ -131,6 +132,41 @@ impl HeaderCaseMap {
}
}

/// Raw bytes of HTTP/1 requests and responses.
///
/// Included in HTTP/1 requests and responses when `http1_raw_message` is set
/// to true.
#[derive(Clone, Debug, PartialEq, PartialOrd, Hash)]
pub struct Http1RawMessage {
pub(crate) buf: Bytes,
}

impl Deref for Http1RawMessage {
type Target = [u8];

fn deref(&self) -> &Self::Target {
&self.buf
}
}

impl AsRef<Bytes> for Http1RawMessage {
fn as_ref(&self) -> &Bytes {
&self.buf
}
}

impl AsRef<[u8]> for Http1RawMessage {
fn as_ref(&self) -> &[u8] {
&self
}
}

impl From<Http1RawMessage> for Bytes {
fn from(message: Http1RawMessage) -> Self {
message.buf
}
}

#[cfg(feature = "ffi")]
#[derive(Clone, Debug)]
/// Hashmap<Headername, numheaders with that name>
Expand Down
14 changes: 0 additions & 14 deletions src/ffi/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,3 @@ ffi_fn! {
}
}
}

ffi_fn! {
/// Set the whether to include a copy of the raw headers in responses
/// received on this connection.
///
/// Pass `0` to disable, `1` to enable.
///
/// If enabled, see `hyper_response_headers_raw()` for usage.
fn hyper_clientconn_options_headers_raw(opts: *mut hyper_clientconn_options, enabled: c_int) -> hyper_code {
let opts = non_null! { &mut *opts ?= hyper_code::HYPERE_INVALID_ARG };
opts.builder.http1_headers_raw(enabled != 0);
hyper_code::HYPERE_OK
}
}
25 changes: 1 addition & 24 deletions src/ffi/http_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use bytes::Bytes;
use libc::{c_int, size_t};
use std::ffi::c_void;

use super::body::{hyper_body, hyper_buf};
use super::body::hyper_body;
use super::error::hyper_code;
use super::task::{hyper_task_return_type, AsTaskType};
use super::{UserDataPointer, HYPER_ITER_CONTINUE};
Expand All @@ -25,8 +25,6 @@ pub struct hyper_headers {
orig_order: OriginalHeaderOrder,
}

pub(crate) struct RawHeaders(pub(crate) hyper_buf);

pub(crate) struct OnInformational {
func: hyper_request_on_informational_callback,
data: UserDataPointer,
Expand Down Expand Up @@ -278,27 +276,6 @@ ffi_fn! {
}
}

ffi_fn! {
/// Get a reference to the full raw headers of this response.
///
/// You must have enabled `hyper_clientconn_options_headers_raw()`, or this
/// will return NULL.
///
/// The returned `hyper_buf *` is just a reference, owned by the response.
/// You need to make a copy if you wish to use it after freeing the
/// response.
///
/// The buffer is not null-terminated, see the `hyper_buf` functions for
/// getting the bytes and length.
fn hyper_response_headers_raw(resp: *const hyper_response) -> *const hyper_buf {
let resp = non_null!(&*resp ?= std::ptr::null());
match resp.0.extensions().get::<RawHeaders>() {
Some(raw) => &raw.0,
None => std::ptr::null(),
}
} ?= std::ptr::null()
}

ffi_fn! {
/// Get the HTTP version used by this response.
///
Expand Down
14 changes: 5 additions & 9 deletions src/proto/h1/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ where
h09_responses: false,
#[cfg(feature = "ffi")]
on_informational: None,
#[cfg(feature = "ffi")]
raw_headers: false,
h1_raw_message: false,
notify_read: false,
reading: Reading::Init,
writing: Writing::Init,
Expand Down Expand Up @@ -135,9 +134,8 @@ where
self.state.allow_half_close = true;
}

#[cfg(feature = "ffi")]
pub(crate) fn set_raw_headers(&mut self, enabled: bool) {
self.state.raw_headers = enabled;
pub(crate) fn set_h1_raw_message(&mut self) {
self.state.h1_raw_message = true;
}

pub(crate) fn into_inner(self) -> (I, Bytes) {
Expand Down Expand Up @@ -210,8 +208,7 @@ where
h09_responses: self.state.h09_responses,
#[cfg(feature = "ffi")]
on_informational: &mut self.state.on_informational,
#[cfg(feature = "ffi")]
raw_headers: self.state.raw_headers,
h1_raw_message: self.state.h1_raw_message,
}
)) {
Ok(msg) => msg,
Expand Down Expand Up @@ -838,8 +835,7 @@ struct State {
/// received.
#[cfg(feature = "ffi")]
on_informational: Option<crate::ffi::OnInformational>,
#[cfg(feature = "ffi")]
raw_headers: bool,
h1_raw_message: bool,
/// Set to true when the Dispatcher should poll read operations
/// again. See the `maybe_notify` method for more.
notify_read: bool,
Expand Down
6 changes: 2 additions & 4 deletions src/proto/h1/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,7 @@ where
h09_responses: parse_ctx.h09_responses,
#[cfg(feature = "ffi")]
on_informational: parse_ctx.on_informational,
#[cfg(feature = "ffi")]
raw_headers: parse_ctx.raw_headers,
h1_raw_message: parse_ctx.h1_raw_message,
},
)? {
Some(msg) => {
Expand Down Expand Up @@ -745,8 +744,7 @@ mod tests {
h09_responses: false,
#[cfg(feature = "ffi")]
on_informational: &mut None,
#[cfg(feature = "ffi")]
raw_headers: false,
h1_raw_message: false,
};
assert!(buffered
.parse::<ClientTransaction>(cx, parse_ctx)
Expand Down
3 changes: 1 addition & 2 deletions src/proto/h1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ pub(crate) struct ParseContext<'a> {
h09_responses: bool,
#[cfg(feature = "ffi")]
on_informational: &'a mut Option<crate::ffi::OnInformational>,
#[cfg(feature = "ffi")]
raw_headers: bool,
h1_raw_message: bool,
}

/// Passed to Http1Transaction::encode
Expand Down
Loading

0 comments on commit a7a51a9

Please sign in to comment.