braid_http_session/
lib.rs1use std::sync::{Arc, RwLock};
5use strand_bui_backend_session::HttpSession;
6use tracing::{debug, error};
7
8#[derive(thiserror::Error, Debug)]
9pub enum Error {
10 #[error("{0}")]
11 FlydraTypesError(#[from] braid_types::FlydraTypesError),
12 #[error("{0}")]
13 JsonError(#[from] serde_json::Error),
14 #[error("{0}")]
15 HyperError(#[from] hyper::Error),
16 #[error("{0}")]
17 BuiBackendSession(#[from] strand_bui_backend_session::Error),
18 #[error("HTTP error {0} when calling {1}")]
19 HttpError(hyper::StatusCode, String),
20}
21
22#[tracing::instrument(level = "info")]
24pub async fn create_mainbrain_session(
25 dest: strand_bui_backend_session_types::BuiServerAddrInfo,
26 jar: Arc<RwLock<cookie_store::CookieStore>>,
27) -> Result<MainbrainSession, strand_bui_backend_session::Error> {
28 debug!("requesting session with mainbrain at {:?}", dest);
29 let inner = strand_bui_backend_session::create_session(&dest, jar).await?;
30 Ok(MainbrainSession { inner })
31}
32
33fn body_from_buf(body_buf: &[u8]) -> axum::body::Body {
34 axum::body::Body::new(http_body_util::Full::new(bytes::Bytes::from(
35 body_buf.to_vec(),
36 )))
37}
38
39#[derive(Clone, Debug)]
44pub struct MainbrainSession {
45 inner: HttpSession,
46}
47
48impl MainbrainSession {
49 #[tracing::instrument(skip_all)]
50 async fn do_post(&mut self, bytes: Vec<u8>) -> Result<(), Error> {
51 let body = body_from_buf(&bytes);
52
53 debug!("calling mainbrain callback handler");
54 let _resp = self.inner.post("callback", body).await?;
55 Ok(())
56 }
57
58 pub async fn get_remote_info(
59 &mut self,
60 raw_cam_name: &braid_types::RawCamName,
61 ) -> Result<braid_types::RemoteCameraInfoResponse, Error> {
62 let path = format!(
63 "{}/{}",
64 braid_types::braid_http::REMOTE_CAMERA_INFO_PATH,
65 braid_types::braid_http::encode_cam_name(raw_cam_name)
66 );
67
68 debug!(
69 "Getting remote camera info for camera \"{}\".",
70 raw_cam_name.as_str()
71 );
72
73 let resp = self.inner.get(&path).await?;
74
75 if !resp.status().is_success() {
76 error!("error: GET was not a success {}:{}", file!(), line!());
77 return Err(Error::HttpError(resp.status(), path));
78 };
79
80 let body = resp.into_body();
82 let chunks: Result<http_body_util::Collected<bytes::Bytes>, hyper::Error> = {
83 use http_body_util::BodyExt;
84 body.collect().await
85 };
86 let data = chunks?.to_bytes();
87
88 Ok(serde_json::from_slice::<
90 braid_types::RemoteCameraInfoResponse,
91 >(&data)?)
92 }
93
94 #[tracing::instrument(skip_all)]
95 pub async fn post_callback_message(
96 &mut self,
97 msg: braid_types::BraidHttpApiCallback,
98 ) -> Result<(), Error> {
99 let bytes = serde_json::to_vec(&msg).unwrap();
100 self.do_post(bytes).await
101 }
102}