chiark / gitweb /
check mtu
[hippotat.git] / src / bin / server.rs
index 1fd6695127ae2a2d3531856f0555632a8332bc47..4900e9778559d546035082cad82a1de1798786e2 100644 (file)
@@ -24,6 +24,7 @@ struct ClientHandles {
 
 /// Sent from hyper worker pool task to client task
 #[allow(dead_code)] // xxx
+#[derive(Debug)]
 struct WebRequest {
   // initial part of body
   // used up to and including first 2 lines of metadata
@@ -39,6 +40,7 @@ struct WebRequest {
 
 /// Reply from client task to hyper worker pool task
 #[allow(dead_code)] // xxx
+#[derive(Debug)]
 struct WebResponse {
   warnings: Warnings,
   data: Result<WebResponseData, AE>,
@@ -183,6 +185,7 @@ async fn handle(
     // boundary, start, &comp.name, &client.ic);
 
     let (reply_to, reply_recv) = tokio::sync::oneshot::channel();
+    trace!("{} request xxx={}", &client.ic, initial.len());
     let wreq = WebRequest {
       initial,
       initial_remaining,
@@ -192,7 +195,6 @@ async fn handle(
       warnings: mem::take(&mut warnings),
       reply_to
     };
-    trace!("{} request", &client.ic);
 
     client.web.try_send(wreq)
       .map_err(|_| anyhow!("client task shut down!"))?;
@@ -215,13 +217,18 @@ async fn handle(
 }
 
 #[allow(unused_variables)] // xxx
+#[allow(unused_mut)] // xxx
 async fn run_client(ic: Arc<InstanceConfig>,
                     mut web: mpsc::Receiver<WebRequest>)
                     -> Result<Void, AE>
 {
   struct Outstanding {
     reply_to: tokio::sync::oneshot::Sender<WebResponse>,
-    max_requests_outstanding: u32,
+    oi: OutstandingInner,
+  }
+  #[derive(Debug)]
+  struct OutstandingInner {
+    target_requests_outstanding: u32,
   }
   let mut outstanding: VecDeque<Outstanding> = default();
   let  downbound: VecDeque<(/*xxx*/)> = default();
@@ -239,7 +246,7 @@ async fn run_client(ic: Arc<InstanceConfig>,
       if ! downbound.is_empty() {
         outstanding.pop_front()
       } else if let Some((i,_)) = outstanding.iter().enumerate().find({
-        |(_,o)| outstanding.len() > o.max_requests_outstanding.sat()
+        |(_,o)| outstanding.len() > o.oi.target_requests_outstanding.sat()
       }) {
         Some(outstanding.remove(i).unwrap())
       } else {
@@ -251,6 +258,7 @@ async fn run_client(ic: Arc<InstanceConfig>,
         warnings: default(),
       };
 
+      dbg!(&response);
       try_send_response(ret.reply_to, response);
     }
 
@@ -260,11 +268,13 @@ async fn run_client(ic: Arc<InstanceConfig>,
         let WebRequest {
           initial, initial_remaining, length_hint, mut body,
           boundary_finder,
-          reply_to, warnings,
+          reply_to, mut warnings,
         } = req.ok_or_else(|| anyhow!("webservers all shut down!"))?;
 
         match async {
 
+          let initial_used = initial.len() - initial_remaining;
+
           let whole_request = read_limited_bytes(
             ic.max_batch_up.sat(),
             initial,
@@ -272,20 +282,71 @@ async fn run_client(ic: Arc<InstanceConfig>,
             &mut body
           ).await.context("read request body")?;
 
-          dbg!(whole_request.len());
-
-/*          
-
-          multipart::ComponentIterator::resume_mid_component(
-            &initial[initial_remaining..],
-  */          
-
-          Ok::<_,AE>(())
+          let (meta, mut comps) =
+            multipart::ComponentIterator::resume_mid_component(
+              &whole_request[initial_used..],
+              boundary_finder
+            ).context("resume parsing body, after auth checks")?;
+
+          let mut meta = MetadataFieldIterator::new(&meta);
+
+          macro_rules! meta {
+            { $v:ident, ( $( $badcmp:tt )? ), $ret:expr,
+              let $server:ident, $client:ident $($code:tt)*
+            } => {
+              let $v = (||{
+                let $server = ic.$v;
+                let $client $($code)*
+                $(
+                  if $client $badcmp $server {
+                    throw!(anyhow!("mismatch: client={:?} {} server={:?}",
+                                   $client, stringify!($badcmp), $server));
+                  }
+                )?
+                Ok::<_,AE>($ret)
+              })().context(stringify!($v))?;
+              dbg!(&$v);
+            }
+          }
+
+          meta!{
+            target_requests_outstanding, ( != ), client,
+            let server, client: u32 = meta.need_parse()?;
+          }
+
+          meta!{
+            http_timeout, ( > ), client,
+            let server, client = Duration::from_secs(meta.need_parse()?);
+          }
+
+          meta!{
+            mtu, ( != ), client,
+            let server, client: u32 = meta.parse()?.unwrap_or(server);
+          }
+
+          meta!{
+            max_batch_down, (), min(client, server),
+            let server, client: u32 = meta.parse()?.unwrap_or(server);
+          }
+
+          meta!{
+            max_batch_up, ( > ), client,
+            let server, client = meta.parse()?.unwrap_or(server);
+          }
+
+          while let Some(comp) = comps.next(&mut warnings, PartName::d)? {
+            if comp.name != PartName::d {
+              warnings.add(&format_args!("unexpected part {:?}", comp.name))?;
+            }
+            dbg!(comp.name, DumpHex(comp.payload));
+          }
+
+          let oi = OutstandingInner {
+            target_requests_outstanding,
+          };
+          Ok::<_,AE>(oi)
         }.await {
-          Ok(()) => outstanding.push_back(Outstanding {
-            reply_to: reply_to,
-            max_requests_outstanding: 42, // xxx
-          }),
+          Ok(oi) => outstanding.push_back(Outstanding { reply_to, oi }),
           Err(e) => {
             try_send_response(reply_to, WebResponse {
               data: Err(e),