#unix-socket #unix #hyper #sockets #http #hyper-client #client-server

httproxide-hyperlocal

Unix 域套接字的超绑定

1 个不稳定版本

0.8.0 2022 年 8 月 1 日

#19 in #hyper-client


2 个 crate 中使用 (通过 httproxide-client-util)

MIT 许可证

17KB
211

🔌 ✨

hyperlocal

Hyper 客户端和服务器绑定用于 Unix 域套接字


Hyper 是一个稳固的 Rust HTTP 客户端和服务器工具包。 Unix 域套接字 提供了主机本地进程间通信的机制。 hyperlocal 基于 Hyper 的接口,并补充了构建 Unix 域套接字 HTTP 客户端和服务器。

这在您想限制对当前主机的访问时很有用,在这种情况下,不需要打开和公开 tcp 端口。 提供此类主机本地接口的 Unix 守护程序示例包括 Docker,一个进程容器管理器。

安装

将以下内容添加到您的 Cargo.toml 文件中

[dependencies]
hyperlocal = "0.8"

用法

服务器

一个典型的服务器可以使用 hyperlocal::server::UnixServerExt 构建。

use std::{error::Error, fs, path::Path};
use hyper::{
    service::{make_service_fn, service_fn},
    Body, Response, Server,
};
use hyperlocal::UnixServerExt;

const PHRASE: &str = "It's a Unix system. I know this.";

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
    let path = Path::new("/tmp/hyperlocal.sock");

    if path.exists() {
        fs::remove_file(path)?;
    }

    let make_service = make_service_fn(|_| async {
        Ok::<_, hyper::Error>(service_fn(|_req| async {
            Ok::<_, hyper::Error>(Response::new(Body::from(PHRASE)))
        }))
    });

    Server::bind_unix(path)?.serve(make_service).await?;

    Ok(())
}

要测试您的服务器是否正常工作,您可以使用现成的工具,如 curl

$ curl --unix-socket /tmp/hyperlocal.sock localhost

It's a Unix system. I know this.

客户端

hyperlocal 还提供了使用 Hyper 的原生 Client 接口编写基于 Unix 域套接字的 HTTP 客户端的绑定。

使用 hyper::Client::builder() 配置您的 Hyper 客户端。

Hyper的客户端接口使用工厂方法,如GETPOSTDELETE等,使得发送典型HTTP方法变得简单,包括getpostdelete等。这些方法需要一个可以转换为hyper::Uri的参数。

由于Unix域套接字不是用解析到IP地址和网络端口的域名表示的,所以标准URL字符串不适用。相反,使用hyperlocal::Uri,它表示域套接字的文件路径以及资源URI路径和查询字符串。

use std::error::Error;
use hyper::{body::HttpBody, Client};
use hyperlocal::{UnixClientExt, Uri};
use tokio::io::{self, AsyncWriteExt as _};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
    let url = Uri::new("/tmp/hyperlocal.sock", "/").into();

    let client = Client::unix();

    let mut response = client.get(url).await?;

    while let Some(next) = response.data().await {
        let chunk = next?;
        io::stdout().write_all(&chunk).await?;
    }

    Ok(())
}

Doug Tangren (softprops) 2015-2020

依赖项

~4–13MB
~139K SLoC