Skip to content

add Method & StatusCode to azure_core #852

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions sdk/core/src/error/http_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ impl HttpError {
pub async fn new(response: Response) -> Self {
let status = response.status();
let mut error_code = get_error_code_from_header(&response);
let mut headers = HashMap::new();

for (name, value) in response.headers().iter() {
headers.insert(name.as_str().to_string(), value.as_str().to_string());
}

let headers: HashMap<String, String> = response
.headers()
.iter()
.map(|(name, value)| (name.as_str().to_owned(), value.as_str().to_owned()))
.collect();
let body = response.into_body().await;
error_code = error_code.or_else(|| get_error_code_from_body(&body));
HttpError {
Expand Down
34 changes: 0 additions & 34 deletions sdk/core/src/error/hyperium_http.rs

This file was deleted.

1 change: 0 additions & 1 deletion sdk/core/src/error/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::borrow::Cow;
use std::fmt::{Debug, Display};
mod http_error;
mod hyperium_http;
mod macros;
pub use http_error::HttpError;

Expand Down
18 changes: 1 addition & 17 deletions sdk/core/src/headers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
mod utilities;

use crate::error::{Error, ErrorKind, ResultExt};
use std::{collections::HashMap, fmt::Debug, str::FromStr};
use std::{fmt::Debug, str::FromStr};
pub use utilities::*;

/// A trait for converting a type into request headers
Expand Down Expand Up @@ -152,22 +152,6 @@ impl From<std::collections::HashMap<HeaderName, HeaderValue>> for Headers {
}
}

impl From<&http::HeaderMap> for Headers {
fn from(map: &http::HeaderMap) -> Self {
let map = map
.into_iter()
.map(|(k, v)| {
let key = k.as_str().to_owned();
let value = std::str::from_utf8(v.as_bytes())
.expect("non-UTF8 header value")
.to_owned();
(key.into(), value.into())
})
.collect::<HashMap<HeaderName, HeaderValue>>();
Self(map)
}
}

/// A header name
#[derive(Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
pub struct HeaderName(std::borrow::Cow<'static, str>);
Expand Down
61 changes: 7 additions & 54 deletions sdk/core/src/http_client.rs → sdk/core/src/http_client/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
#[cfg(any(feature = "enable_reqwest", feature = "enable_reqwest_rustls"))]
#[cfg(not(target_arch = "wasm32"))]
mod reqwest;

#[cfg(any(feature = "enable_reqwest", feature = "enable_reqwest_rustls"))]
#[cfg(not(target_arch = "wasm32"))]
pub use self::reqwest::*;
#[allow(unused_imports)]
use crate::error::{Error, ErrorKind, ResultExt};
#[allow(unused_imports)]
Expand All @@ -10,13 +17,6 @@ use bytes::Bytes;
use futures::TryStreamExt;
use serde::Serialize;

/// Construct a new `HttpClient` with the `reqwest` backend.
#[cfg(any(feature = "enable_reqwest", feature = "enable_reqwest_rustls"))]
#[cfg(not(target_arch = "wasm32"))]
pub fn new_http_client() -> std::sync::Arc<dyn HttpClient> {
std::sync::Arc::new(reqwest::Client::new())
}

/// An HTTP client which can send requests.
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
Expand Down Expand Up @@ -45,53 +45,6 @@ pub trait HttpClient: Send + Sync + std::fmt::Debug {
}
}

#[cfg(any(feature = "enable_reqwest", feature = "enable_reqwest_rustls"))]
#[cfg(not(target_arch = "wasm32"))]
#[async_trait]
impl HttpClient for reqwest::Client {
async fn execute_request(&self, request: &crate::Request) -> crate::Result<crate::Response> {
let url = request.url().clone();
let mut reqwest_request = self.request(request.method().clone(), url);
for (name, value) in request.headers().iter() {
reqwest_request = reqwest_request.header(name.as_str(), value.as_str());
}

let body = request.body().clone();

let reqwest_request = match body {
Body::Bytes(bytes) => reqwest_request
.body(bytes)
.build()
.context(ErrorKind::Other, "failed to build request")?,
Body::SeekableStream(mut seekable_stream) => {
seekable_stream.reset().await.unwrap(); // TODO: remove unwrap when `HttpError` has been removed

reqwest_request
.body(reqwest::Body::wrap_stream(seekable_stream))
.build()
.context(ErrorKind::Other, "failed to build request")?
}
};

let reqwest_response = self
.execute(reqwest_request)
.await
.context(ErrorKind::Io, "failed to execute request")?;

let status = reqwest_response.status();
let headers = Headers::from(reqwest_response.headers());
let body: PinnedStream = Box::pin(reqwest_response.bytes_stream().map_err(|error| {
Error::full(
ErrorKind::Io,
error,
"error converting `reqwest` request into a byte stream",
)
}));

Ok(crate::Response::new(status, headers, body))
}
}

/// Serialize a type to json.
pub fn to_json<T>(value: &T) -> crate::Result<Bytes>
where
Expand Down
67 changes: 67 additions & 0 deletions sdk/core/src/http_client/reqwest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use super::*;
use std::collections::HashMap;

/// Construct a new `HttpClient` with the `reqwest` backend.
pub fn new_http_client() -> std::sync::Arc<dyn HttpClient> {
std::sync::Arc::new(::reqwest::Client::new())
}

#[async_trait]
impl HttpClient for ::reqwest::Client {
async fn execute_request(&self, request: &crate::Request) -> crate::Result<crate::Response> {
let url = request.url().clone();
let mut req = self.request(request.method().clone(), url);
for (name, value) in request.headers().iter() {
req = req.header(name.as_str(), value.as_str());
}

let body = request.body().clone();

let reqwest_request = match body {
Body::Bytes(bytes) => req.body(bytes).build(),
Body::SeekableStream(mut seekable_stream) => {
seekable_stream.reset().await.unwrap(); // TODO: remove unwrap when `HttpError` has been removed
req.body(::reqwest::Body::wrap_stream(seekable_stream))
.build()
}
}
.context(ErrorKind::Other, "failed to build `reqwest` request")?;

let rsp = self
.execute(reqwest_request)
.await
.context(ErrorKind::Io, "failed to execute `reqwest` request")?;

let status = rsp.status();
let headers = to_headers(rsp.headers())?;
let body: PinnedStream = Box::pin(rsp.bytes_stream().map_err(|error| {
Error::full(
ErrorKind::Io,
error,
"error converting `reqwest` request into a byte stream",
)
}));

Ok(crate::Response::new(status, headers, body))
}
}

fn to_headers(map: &::reqwest::header::HeaderMap) -> crate::Result<crate::headers::Headers> {
let map = map
.iter()
.filter_map(|(k, v)| {
let key = k.as_str();
match std::str::from_utf8(v.as_bytes()) {
Ok(value) => Some((
crate::headers::HeaderName::from(key.to_owned()),
crate::headers::HeaderValue::from(value.to_owned()),
)),
Err(_) => {
log::warn!("header value for `{key}` is not utf8");
None
}
}
})
.collect::<HashMap<_, _>>();
Ok(crate::headers::Headers::from(map))
}
3 changes: 3 additions & 0 deletions sdk/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ pub use response::*;
pub use seekable_stream::*;
pub use sleep::sleep;

// re-export important types at crate level
pub use http::Method;
pub use http::StatusCode;
pub use url::Url;

/// A unique identifier for a request.
Expand Down
2 changes: 1 addition & 1 deletion sdk/core/src/mock/mock_request.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::Method;
use crate::{Body, Request};
use http::Method;
use serde::de::Visitor;
use serde::ser::{Serialize, SerializeStruct, Serializer};
use serde::{Deserialize, Deserializer};
Expand Down
10 changes: 4 additions & 6 deletions sdk/core/src/mock/mock_response.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use bytes::Bytes;
use http::StatusCode;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;

use crate::{
collect_pinned_stream, error,
headers::{HeaderName, HeaderValue, Headers},
BytesStream, Response,
BytesStream, Response, StatusCode,
};
use bytes::Bytes;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;

#[derive(Debug, Clone, PartialEq)]
pub(crate) struct MockResponse {
Expand Down
4 changes: 1 addition & 3 deletions sdk/core/src/policies/retry_policies/retry_policy.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use crate::error::{Error, ErrorKind, HttpError};
use crate::policies::{Policy, PolicyResult, Request};
use crate::sleep::sleep;
use crate::Context;

use crate::{Context, StatusCode};
use chrono::{DateTime, Local};
use http::StatusCode;
use std::sync::Arc;
use std::time::Duration;

Expand Down
3 changes: 1 addition & 2 deletions sdk/core/src/request.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::headers::{AsHeaders, Headers};
use crate::SeekableStream;
use crate::{Method, SeekableStream};
use bytes::Bytes;
use http::Method;
use std::fmt::Debug;
use url::Url;

Expand Down
2 changes: 1 addition & 1 deletion sdk/core/src/response.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::headers::Headers;
use crate::StatusCode;
use bytes::Bytes;
use futures::Stream;
use futures::StreamExt;
use http::StatusCode;
use std::pin::Pin;

pub type PinnedStream = Pin<Box<dyn Stream<Item = crate::Result<Bytes>> + Send + Sync>>;
Expand Down
1 change: 0 additions & 1 deletion sdk/data_cosmos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ async-trait = "0.1"
azure_core = { path = "../core", version = "0.3" }
base64 = "0.13"
chrono = "0.4"
http = "0.2"
futures = "0.3"
log = "0.4"
serde = { version = "1.0", features = ["derive"] }
Expand Down
Loading