0

我正在尝试Response在运行时在 Hyper 上设置标头。在实际代码中,标头来自一个文件,所以我不知道它们在编译时是什么。不幸的是,我已经翻阅了文档和我能找到的所有示例,但还没有看到有人这样做。这是代码:

extern crate hyper;
use std::collections::HashMap;
use std::io::{Read,Write};
use hyper::server::{Handler,Server,Response,Request};
use hyper::header::*;

fn main() {
    let headers = HashMap::new();
    headers.insert("X-Test-Header".to_string(), "test_value".to_string());
    let responder = Responder::new(headers);

    Server::http("127.0.0.1:1340")
    .unwrap()
    .handle(responder)
    .unwrap();
}

struct Responder {
    headers: HashMap<String, String>
}

impl Responder {
    pub fn new(headers: HashMap<String,String>) -> Self {
        Responder {
            headers: headers.clone()
        }
    }
    fn respond_success(&self, mut res: Response, content: &[u8]) {
        res.headers_mut()
            .set(ContentLength(content.len() as u64));
        for (key, val) in self.headers.iter() {
            res.headers_mut()
                .set_raw(key.as_str(), vec![val.into_bytes()])
        }
        let mut res_body = res.start().unwrap();
        res_body.write_all(content).unwrap();
    }
}

impl Handler for Responder {
    fn handle(&self, req: Request, res: Response) {
        let content = b"Hello World!";
        self.respond_success(res, content);
    }
}

错误:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src\main.rs:31:40
   |
31 |         for (key, val) in self.headers.iter() {
   |                                        ^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 28:65...
  --> src\main.rs:28:66
   |
28 |     fn respond_success(&self, mut res: Response, content: &[u8]) {
   |                                                                  ^
note: ...so that reference does not outlive borrowed content
  --> src\main.rs:31:27
   |
31 |         for (key, val) in self.headers.iter() {
   |                           ^^^^^^^^^^^^
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that types are compatible (expected std::convert::From<&str>, found std::convert::From<&str>)
  --> src\main.rs:33:18
   |
33 |                 .set_raw(key.as_str(), vec![val.into_bytes()])
   |                  ^^^^^^^

看起来set_raw需要一些静态的东西,但我不确定重构它的最佳选择是什么。responder必须是静态的吗?这似乎是错误的。

4

1 回答 1

2

查看签名Headers::set_raw

fn set_raw<K>(&mut self, name: K, value: Vec<Vec<u8>>)
where 
    K: Into<Cow<'static, str>>

这表示 thatname可以是任何可以转换为Cow<'static, str>. 这意味着它可以是 a&'static str a String

接下来,查看您尝试传递的类型:

.set_raw(key.as_str(), vec![val.into_bytes()])
  1. String::as_strString返回一个与调用它一样长的字符串切片,而不是那个'static生命周期。

    相反,您需要获得一个拥有的字符串。

  2. 您正在调用String::into_bytesa &String,但是,如不能移出借来的内容中所述,您不能,因为它按值获取接收者。

    相反,您需要获取字节的拥有副本。

在一起,它看起来像:

for (key, val) in self.headers.iter() {
    res.headers_mut()
        .set_raw(key.clone(), vec![val.clone().into_bytes()])
}
于 2017-05-18T17:37:10.330 回答