Files
scryer-prolog/src/http.rs
Adrián Arroyo Calle 330e9ba4ef Multiple fixes for http libraries
* use reqwest for http_open (still uses Hyper underneath)
* use Hyper 1.0.0-rc3 for server
* Modify all internal handling of server
2023-06-29 23:43:37 +02:00

55 lines
1.5 KiB
Rust

use std::sync::{Arc, Mutex, Condvar};
use std::future::Future;
use std::pin::Pin;
use http_body_util::Full;
use bytes::Bytes;
use hyper::service::Service;
use hyper::{body::Incoming as IncomingBody, Request, Response};
pub struct HttpListener {
pub incoming: std::sync::mpsc::Receiver<HttpRequest>
}
#[derive(Debug)]
pub struct HttpRequest {
pub request: Request<IncomingBody>,
pub response: HttpResponse,
}
pub type HttpResponse = Arc<(Mutex<bool>, Mutex<Option<Response<Full<Bytes>>>>, Condvar)>;
pub struct HttpService {
pub tx: std::sync::mpsc::SyncSender<HttpRequest>,
}
impl Service<Request<IncomingBody>> for HttpService {
type Response = Response<Full<Bytes>>;
type Error = hyper::Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
fn call(&mut self, req: Request<IncomingBody>) -> Self::Future {
// new connection!
// we send the Request info to Prolog
let response = Arc::new((Mutex::new(false), Mutex::new(None), Condvar::new()));
let http_request = HttpRequest { request: req, response: Arc::clone(&response) };
self.tx.send(http_request).unwrap();
// we wait for the Response info from Prolog
{
let (ready, _response, cvar) = &*response;
let mut ready = ready.lock().unwrap();
while !*ready {
ready = cvar.wait(ready).unwrap();
}
}
{
let (_, response, _) = &*response;
let response = response.lock().unwrap().take();
let res = response.expect("Data race error in HTTP Server");
Box::pin(async move {
Ok(res)
})
}
}
}