fussybeaver / bollard

Docker daemon API in Rust
Apache License 2.0
907 stars 134 forks source link

Uri parse error #466

Closed BenLocal closed 1 month ago

BenLocal commented 1 month ago

I used HTTP to reverse proxy the Docker Unix socket and added a prefix path /proxy. when use the client to connect to the HTTP service, the URL accessed has the prefix /proxy removed.

eg: http reverse proxy server http://x.x.x.x/proxy/info for get docker info

  let docker = Docker::connect_with_http("http://localhost:4000/proxy/",4,bollard::API_DEFAULT_VERSION).unwrap();
  let res = docker.info().await;

The path currently being accessed is http://localhost:4000/info. I looked at the code and found that it is caused by https://github.com/fussybeaver/bollard/blob/e4deff62c6c83ee6fbdf79d030329e9f79bbecee/src/uri.rs#L44

BenLocal commented 1 month ago

I found that using Docker::connect_with_custom_transport can solve this problem

 let docker = Docker::connect_with_custom_transport(
            move |req: BollardRequest| {
                let http_client = std::sync::Arc::clone(&http_client);
                Box::pin(async move {
                    let (mut p, b) = req.into_parts();
                    // let _prev = p.headers.insert("host", host);
                    let mut uri = p.uri.into_parts();
                    uri.path_and_query = uri
                        .path_and_query
                        .map(|paq| {
                            println!("paq: {:?}", paq);
                            axum::http::uri::PathAndQuery::try_from(
                                "/proxy".to_owned() + paq.as_str(),
                            )
                        })
                        .transpose()
                        .map_err(bollard::errors::Error::from)?;
                    p.uri = uri.try_into().map_err(bollard::errors::Error::from)?;
                    let req = BollardRequest::from_parts(p, b);
                    http_client
                        .request(req)
                        .await
                        .map_err(bollard::errors::Error::from)
                })
            },
            Some("http://localhost:4000"),
            4,
            bollard::API_DEFAULT_VERSION,
        ) .unwrap();