Is auxm or tower is not really cocurrent? or chrome?

⚓ rust    📅 2025-06-09    👤 surdeus    👁️ 2      

surdeus

Hi, I wrote a web application using axum and tower, and to speed up the source downloading, I tried downloading the file by bytes range and finally find the trying failed, the picture below shows seems the downloading still happens one after the other.

flow

the picture is in http/1.1, but even in http2, things don't change.

I don't know what is the root cause. I use axum and tower, and the browser is chrome.

the relative code is

            let route = Router::new()
                .route(
                    "/ws",
                    get(async |ws: WebSocketUpgrade| {
                        ws.on_failed_upgrade(|e| {
                            error!("ws upgrade failed: {e}");
                        })
                        .on_upgrade(move |socket| handle_socket(socket, pool.clone()))
                    }),
                )
                .fallback_service(
                    get(async move |uri: Uri, headers: HeaderMap| file_handler(uri, headers, dir).await)
                        .route_layer(axum::middleware::from_fn_with_state(
                            cloned_dir,
                            async |State(state): State<String>, req, next| {
                                check_modify(&state, req, next).await
                            },
                        )),
                );

 // ------------------------------------------------------


async fn check_modify(dir: &str, req: Request<Body>, next: Next) -> Response<Body> {
    use httpdate;

    if req.uri().path() == "/" || req.uri().path().contains("index.html") {
        let mut headers = String::new();
        for (k, v) in req.headers() {
            let s = format!("{}: {} ", k, v.to_str().unwrap_or("???"));
            headers.push_str(&s);
        }
        info!("request {} with header {}", req.uri().path(), &headers);
    }

    if let Some(value) = req.headers().get("If-Modified-Since") {
        if let Ok(st1) = httpdate::parse_http_date(value.to_str().unwrap_or("")) {
            if let Ok(ts1) = st1.duration_since(UNIX_EPOCH) {
                let path = format!("{}{}", dir, req.uri().path());
                if let Ok(Ok(st2)) = std::fs::metadata(path).map(|x| x.modified()) {
                    if let Ok(ts2) = st2.duration_since(UNIX_EPOCH) {
                        if ts1.as_secs() == ts2.as_secs() {
                            return StatusCode::NOT_MODIFIED.into_response();
                        }
                    }
                }
            }
        }
    }
    next.run(req).await
}


async fn file_handler(
    uri: Uri, headers: HeaderMap, dir: &str,
) -> Result<(HeaderMap, Response<Body>), StatusCode> {
    let b = uri.path().contains("yah.woff2")
        || uri.path().contains(".gif")
        || uri.path().contains("skwasm.wasm")
        || uri.path().contains("skwasm_st.wasm")
        || uri.path().contains("canvaskit.wasm")
        || uri.path().contains(".js.symbols");

    let mut builder = Request::builder().uri(uri);
    for (k, v) in headers {
        let Some(k) = k else {
            continue;
        };
        builder = builder.header(k, v);
    }

    let req = builder.body(()).unwrap();
    let fsvc = ServeDir::new(dir);
    match fsvc.oneshot(req).await {
        Ok(res) => {
            let mut headers = HeaderMap::new();
            if b {
                headers.insert(
                    axum::http::header::CACHE_CONTROL,
                    axum::http::header::HeaderValue::from_static("max-age=31536000, immutable, public"),
                );
            } else {
                headers.insert(
                    axum::http::header::CACHE_CONTROL,
                    axum::http::header::HeaderValue::from_static("no-cache"),
                );
            }
            Ok((headers, res.map(|x| Body::new(x))))
        }
        Err(_) => Err(StatusCode::INTERNAL_SERVER_ERROR),
    }
}

The js log shows it is indeed runs cocurrently at my js level, out of the browser fetch API

The picure shows the request hangs at connection stage, only the previous fetch finished, the hanged connection continues

2 posts - 1 participant

Read full topic

🏷️ rust_feed