Hyper Client无法查找在IPv6 Localhost上运行的服务器的地址信息



我在端口3005上使用路由器和熨斗具有简单的HTTP服务器。它没有做任何令人兴奋的事情。我相信这只是回应了请求,但细节并不重要。

我还使用了Hyper的客户端模块将请求发送到服务器。

每当我在IPv4 localhost上运行服务器时,我都不会遇到任何问题。我可以用我的客户和卷发来查询它。如果我在IPv6 localhost上启动服务器(我使用的是缩短版本::1(,我只能使用Curl访问服务器。

这表明服务器运行正常并响应,但是我的超级Client代码失败了,报告:

err(io(io(error {repr:custom {custom {chink {chink {其他,错误:stringerror((" 未能查找地址信息:名称或服务未知"(}(((}((((((((((((((( 在Err值上称为Result::unwrap()的线程" MAIN"值:io(error {repr:susta custom {custom {chind {chink {chink {chink {chind {chind,error:stringer error:"失败查找地址信息:名称或服务未知"(}(}}(}(}((}(((',/checkout/src/libcore/result.rs:860

我用来发送发布请求的代码如下:

let addr = "http://[::1]:3005/message";
let mut res = self.client.post(addr).body(s.as_str()).send().unwrap();

s是我要发送的有效载荷。

我也尝试了扩展的IPv6地址([0:0:0:0:0:0:0:1](,并且我遇到了相同的错误。

我还尝试了无括号的缩短和扩展的IPv6地址。我得到的"无效端口 - "带有扩展的地址和"空主机",缩短了。

要重现这种行为,您可以使用这些小示例(未注释的行以收到错误(:

服务器

extern crate iron;
use iron::prelude::*;
use iron::status;
fn hello_world(_: &mut Request) -> IronResult<Response> {
    println!("Recvd a request");
    Ok(Response::with((status::Ok, "Hello World!")))
}
fn main() {
    let port = 3000;
    //let addr = format!("{}:{}", "[::1]", port);
    let addr = format!("{}:{}", "localhost", port);
    println!("Server opened on {}", addr);
    Iron::new(hello_world).http(addr).unwrap();
}

客户端

// hyper 0.10.13
extern crate hyper;
use hyper::*;
use std::io::Read;
fn main() {
    let client = Client::new();
    //let mut res = client.get("http://[::1]:3000/").send().unwrap();
    let mut res = client.get("http://localhost:3000/").send().unwrap();
    let mut s = String::new();
    res.read_to_string(&mut s).unwrap();
    println!("response contained: {}", s);
}

clientv2

// For people that want to try with hyper 0.11.X
extern crate futures;
extern crate hyper;
extern crate tokio_core;
use std::io::{self, Write};
use futures::{Future, Stream};
use hyper::Client;
use tokio_core::reactor::Core;
fn main() {
    let mut core = Core::new().unwrap();
    let client = Client::new(&core.handle());
    let uri = "http://[::1]:3000/".parse().unwrap();
    let work = client.get(uri).and_then(|res| {
        println!("Response: {}", res.status());
        res.body().for_each(|chunk| {
            io::stdout()
                .write_all(&chunk)
                .map(|_| ())
                .map_err(From::from)
        })
    });
    core.run(work).unwrap();
}

note1:

您需要Hyper 0.10.x才能运行此代码。就我而言,我使用的是0.10.13

note2:

我正在发送无效载荷的Get请求,以便抽象功能无关的位。

note3:

看起来像高0.10.x和高0.11.x的操作以不同的方式处理IPv6服务器。高0.10.x给出上述错误,而0.11.x给我响应代码 400不良请求

ipv6支持似乎是先前版本和Hyperium/hyper(&lt; = 0.11.23(

的当前版本的问题

开发人员建议使用heptry 0.11.x使用Reqwest板条板,但由于ReqWest在Hyper上构建,结果将相同。


我到目前为止发现的解决方案是将卷曲的粘合物用于生锈,因为卷曲似乎足够坚固。这是我编写一个客户端的代码,该客户端将简单的获取请求发送到IPv6服务器地址。

客户端

extern crate curl;
use std::io::{stdout, Write};
use curl::easy::Easy;
fn main() {
    let mut easy = Easy::new();
    easy.url("https://[::1]:3000").unwrap();
    easy.write_function(|data| {
        stdout().write_all(data).unwrap();
        Ok(data.len())
    }).unwrap();
    easy.perform().unwrap();
}

这不是最漂亮的解决方案,因为它使用了内置C的库,这是一种不安全的语言,但是直到更好的替代方案出现之前,这是一个很好的解决方法。

相关内容

最新更新