use http::{header, HeaderMap, HeaderName, HeaderValue, Method, Request, Uri, Version};
use crate::body::BodyWriter;
use crate::client::amended::AmendedRequest;
use crate::ext::{HeaderIterExt, MethodExt};
use crate::{ArrayVec, Error};
use super::state::{Prepare, SendRequest};
use super::{BodyState, Call, CloseReason, Inner};
impl Call<Prepare> {
pub fn new(request: Request<()>) -> Result<Self, Error> {
let mut close_reason = ArrayVec::from_fn(|_| CloseReason::ClientConnectionClose);
if request.version() == Version::HTTP_10 {
close_reason.push(CloseReason::CloseDelimitedBody)
}
if request.headers().iter().has(header::CONNECTION, "close") {
close_reason.push(CloseReason::ClientConnectionClose);
}
let need_request_body = request.method().need_request_body();
let await_100_continue = request.headers().iter().has_expect_100();
let request = AmendedRequest::new(request);
let default_body_mode = if need_request_body {
BodyWriter::new_chunked()
} else {
BodyWriter::new_none()
};
let inner = Inner {
request,
analyzed: false,
state: BodyState {
writer: default_body_mode,
..Default::default()
},
close_reason,
force_send_body: false,
force_recv_body: false,
await_100_continue,
status: None,
location: None,
};
Ok(Call::wrap(inner))
}
pub fn method(&self) -> &Method {
self.inner.request.method()
}
pub fn uri(&self) -> &Uri {
self.inner.request.uri()
}
pub fn version(&self) -> Version {
self.inner.request.version()
}
pub fn headers(&self) -> &HeaderMap {
self.inner.request.original_request_headers()
}
pub fn allow_non_standard_methods(&mut self, v: bool) {
self.inner.state.allow_non_standard_methods = v;
}
pub fn header<K, V>(&mut self, key: K, value: V) -> Result<(), Error>
where
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<http::Error>,
HeaderValue: TryFrom<V>,
<HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
{
self.inner.request.set_header(key, value)
}
pub fn force_send_body(&mut self) {
self.inner.force_send_body = true;
}
pub fn proceed(self) -> Call<SendRequest> {
Call::wrap(self.inner)
}
}