diff --git a/capi/include/hyper.h b/capi/include/hyper.h index 2245d6a45d..7d79825865 100644 --- a/capi/include/hyper.h +++ b/capi/include/hyper.h @@ -430,6 +430,23 @@ enum hyper_code hyper_request_set_uri(struct hyper_request *req, const uint8_t *uri, size_t uri_len); +/* + Set the URI of the request with separate scheme, authority, and + path/query strings. + + Each of `scheme`, `authority`, and `path_and_query` should either be + null, to skip providing a component, or point to a UTF-8 encoded + string. If any string pointer argument is non-null, its corresponding + `len` parameter must be set to the string's length. + */ +enum hyper_code hyper_request_set_uri_parts(struct hyper_request *req, + const uint8_t *scheme, + size_t scheme_len, + const uint8_t *authority, + size_t authority_len, + const uint8_t *path_and_query, + size_t path_and_query_len); + /* Set the preferred HTTP version of the request. diff --git a/src/ffi/http_types.rs b/src/ffi/http_types.rs index e7daaeba79..c80d67fd2b 100644 --- a/src/ffi/http_types.rs +++ b/src/ffi/http_types.rs @@ -90,6 +90,54 @@ ffi_fn! { } } +ffi_fn! { + /// Set the URI of the request with separate scheme, authority, and + /// path/query strings. + /// + /// Each of `scheme`, `authority`, and `path_and_query` should either be + /// null, to skip providing a component, or point to a UTF-8 encoded + /// string. If any string pointer argument is non-null, its corresponding + /// `len` parameter must be set to the string's length. + fn hyper_request_set_uri_parts( + req: *mut hyper_request, + scheme: *const u8, + scheme_len: size_t, + authority: *const u8, + authority_len: size_t, + path_and_query: *const u8, + path_and_query_len: size_t + ) -> hyper_code { + let mut builder = Uri::builder(); + if !scheme.is_null() { + let scheme_bytes = unsafe { + std::slice::from_raw_parts(scheme, scheme_len as usize) + }; + builder = builder.scheme(scheme_bytes); + } + if !authority.is_null() { + let authority_bytes = unsafe { + std::slice::from_raw_parts(authority, authority_len as usize) + }; + builder = builder.authority(authority_bytes); + } + if !path_and_query.is_null() { + let path_and_query_bytes = unsafe { + std::slice::from_raw_parts(path_and_query, path_and_query_len as usize) + }; + builder = builder.path_and_query(path_and_query_bytes); + } + match builder.build() { + Ok(u) => { + *unsafe { &mut *req }.0.uri_mut() = u; + hyper_code::HYPERE_OK + }, + Err(_) => { + hyper_code::HYPERE_INVALID_ARG + } + } + } +} + ffi_fn! { /// Set the preferred HTTP version of the request. ///