我试图通过使用Hyper 0.10实现一个简单的内存URL缩短器来学习Rust.我遇到了一个问题,我认为这是因为我试图HashMap在我的处理程序中关闭一个mutable :
fn post(mut req: Request, mut res: Response, short_uris: &mut HashMap<&str, &str>) {
let mut body = String::new();
match req.read_to_string(&mut body) {
Ok(_) => {
let key = short_uris.len();
short_uris.insert(&key.to_string(), &body.to_string());
*res.status_mut() = StatusCode::Created;
res.start().unwrap().write(&key.to_string().into_bytes());
},
Err(_) => *res.status_mut() = StatusCode::BadRequest
}
}
fn get(req: Request, mut res: Response, short_uris: &HashMap<&str, &str>) {
match req.uri.clone() {
AbsolutePath(path) => {
match short_uris.get::<str>(&path) {
Some(short_uri) => {
*res.status_mut() = StatusCode::MovedPermanently;
res.headers_mut().set(Location(short_uri.to_string()));
},
None => *res.status_mut() = StatusCode::NotFound
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试像 cURL 那样使用 hyper 发布图像文件:
curl -F smfile=@11.jpg https://httpbin.org/post --trace-ascii -
Run Code Online (Sandbox Code Playgroud)
结果是:
{
"args": {},
"data": "",
"files": {
"smfile": "data:image/jpeg;base64,..."
},
"form": {},
"headers": {
"Accept": "/",
"Connection": "close",
"Content-Length": "1709",
"Content-Type": "multipart/form-data; boundary=------------------------58370e136081470e",
"Expect": "100-continue",
"Host": "httpbin.org",
"User-Agent": "curl/7.59.0"
},
"json": null,
"origin": "myip",
"url": "https://httpbin.org/post"
}
Run Code Online (Sandbox Code Playgroud)
我了解到应该将 Content-Type 设置为multipart/form-data带有边界标记。这是我的代码:
extern crate futures;
extern crate hyper;
extern crate hyper_tls;
extern crate tokio;
use futures::{future, Future};
use hyper::header::CONTENT_TYPE;
use hyper::rt::Stream;
use hyper::{Body, Client, Method, Request};
use hyper_tls::HttpsConnector; …Run Code Online (Sandbox Code Playgroud) 我有一个在内部使用 hyper 的库。我希望用户能够创建一个App包含Server处理 HTTP 连接的内部。
use hyper::server::conn::AddrIncoming;
use hyper::server::Server;
use hyper::service::service_fn_ok;
use std::net::SocketAddr;
pub struct App {
inner: Server<AddrIncoming, ()>,
}
impl App {
pub fn new() -> Self {
let addr = SocketAddr::from(([0, 0, 0, 0], 3000));
let inner = Server::bind(&addr).serve(|| service_fn_ok(|_req| unimplemented!()));
App { inner }
}
}
Run Code Online (Sandbox Code Playgroud)
(游乐场链接)
正如预期的那样,错误是:
error[E0308]: mismatched types
--> src/lib.rs:15:15
|
15 | App { inner }
| ^^^^^ expected (), found closure
|
= note: expected …Run Code Online (Sandbox Code Playgroud) 我尝试使用Hyper将URL的内容(正文)显示为文本
extern crate hyper;
use hyper::client::Client;
use std::io::Read;
fn main () {
let client = Client::new();
let mut s = String::new();
let res = client.get("https://www.reddit.com/r/programming/.rss")
.send()
.unwrap()
.read_to_string(&mut s)
.unwrap();
println!("Result: {}", res);
}
Run Code Online (Sandbox Code Playgroud)
但是运行此脚本只会返回正文的大小:
Result: 22871
Run Code Online (Sandbox Code Playgroud)
我做错了什么?我误解了什么吗?
我正在尝试使用hyper来获取HTML页面的内容,并希望同步返回将来的输出。我意识到我可以选择一个更好的示例,因为同步HTTP请求已经存在,但是我对了解我们是否可以从异步计算中返回一个值更感兴趣。
extern crate futures;
extern crate hyper;
extern crate hyper_tls;
extern crate tokio;
use futures::{future, Future, Stream};
use hyper::Client;
use hyper::Uri;
use hyper_tls::HttpsConnector;
use std::str;
fn scrap() -> Result<String, String> {
let scraped_content = future::lazy(|| {
let https = HttpsConnector::new(4).unwrap();
let client = Client::builder().build::<_, hyper::Body>(https);
client
.get("https://hyper.rs".parse::<Uri>().unwrap())
.and_then(|res| {
res.into_body().concat2().and_then(|body| {
let s_body: String = str::from_utf8(&body).unwrap().to_string();
futures::future::ok(s_body)
})
}).map_err(|err| format!("Error scraping web page: {:?}", &err))
});
scraped_content.wait()
}
fn read() {
let scraped_content = future::lazy(|| {
let https = HttpsConnector::new(4).unwrap(); …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 tokio 编写一个测试程序,该程序从网站上获取文件并将流式响应写入文件。超级网站显示了一个示例,该示例使用 while 循环并使用.data()响应主体的方法,但我想与.map()其他几个人一起操作流。
我认为下一个合理的尝试是AsyncRead使用.into_async_read()from 方法将流转换为 an TryStreamExt,但这似乎不起作用。我不得不使用地图将 the 转换hyper::error::Error为 astd::error::Error以获取 a TryStream,但现在编译器告诉我AsyncRead没有为转换后的流实现。这是我的 main.rs 文件和错误:
src/main.rs
use futures::stream::{StreamExt, TryStreamExt};
use http::Request;
use hyper::{Body, Client};
use hyper_tls::HttpsConnector;
use tokio::fs::File;
use tokio::io;
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let https = HttpsConnector::new();
let client = Client::builder().build::<_, Body>(https);
let request = Request::get("some file from the internet").body(Body::empty())?;
let response = client.request(request).await?;
let …Run Code Online (Sandbox Code Playgroud) ps:下面的答案有帮助,但这不是我需要的答案,我有一个新问题,我编辑了问题
我正在尝试为hyper http crate制作自定义传输器,因此我可以以自己的方式传输 http 数据包。
Hyper 的 http 客户端可以通过自定义 https://docs.rs/hyper/0.14.2/hyper/client/connect/trait.Connect.html在这里:
pub fn build<C, B>(&self, connector: C) -> Client<C, B> where C: Connect + Clone, B: HttpBody + Send, B::Data: Send,
如果我们看
impl<S, T> Connect for S where
S: Service<Uri, Response = T> + Send + 'static,
S::Error: Into<Box<dyn StdError + Send + Sync>>,
S::Future: Unpin + Send,
T: AsyncRead + AsyncWrite + Connection + Unpin + Send + 'static,
Run Code Online (Sandbox Code Playgroud)
类型T,即 的类型Response,必须实现AsyncRead …
我有多个线程执行一些繁重的操作,我需要在工作中使用客户端。我使用 Hyper v0.11 作为 HTTP 客户端,我想重用连接,所以我需要共享hyper::Client连接以保持打开连接(在keep-alive模式下)。
客户端不可在线程之间共享(它没有实现Sync或Send)。这是我尝试执行的代码的小片段:
let mut core = Core::new().expect("Create Client Event Loop");
let handle = core.handle();
let remote = core.remote();
let client = Client::new(&handle.clone());
thread::spawn(move || {
// intensive operations...
let response = &client.get("http://google.com".parse().unwrap()).and_then(|res| {
println!("Response: {}", res.status());
Ok(())
});
remote.clone().spawn(|_| {
response.map(|_| { () }).map_err(|_| { () })
});
// more intensive operations...
});
core.run(futures::future::empty::<(), ()>()).unwrap();
Run Code Online (Sandbox Code Playgroud)
此代码无法编译:
let mut core = Core::new().expect("Create Client Event Loop");
let handle = …Run Code Online (Sandbox Code Playgroud) 我正在使用hyper 0.12 来构建代理服务。当从上游服务器接收响应身体我要转发它返回给客户端的ASAP,并保存该内容在用于后续处理的缓冲器。
所以我需要一个函数:
Stream(a hyper::Body,准确地说)Stream与输入流功能相同的Future<Item = Vec<u8>, Error = ...>当输出流被完全消耗时,还返回某种通过输入流的缓冲内容解决的问题我一生都无法弄清楚如何做到这一点。
我想我正在寻找的功能看起来像这样:
type BufferFuture = Box<Future<Item = Vec<u8>, Error = ()>>;
pub fn copy_body(body: hyper::Body) -> (hyper::Body, BufferFuture) {
let body2 = ... // ???
let buffer = body.fold(Vec::<u8>::new(), |mut buf, chunk| {
buf.extend_from_slice(&chunk);
// ...somehow send this chunk to body2 also?
});
(body2, buffer);
}
Run Code Online (Sandbox Code Playgroud)
以下是我尝试过的,它一直工作到send_data()失败(显然)。
type BufferFuture = Box<Future<Item = Vec<u8>, Error …Run Code Online (Sandbox Code Playgroud) 在actix-web解析器中创建超级发布请求时,会引发以下错误 - 如何通过将请求生成到现有执行程序来发送 http 请求?
thread 'actix-rt:worker:1' panicked at 'Multiple executors at once: EnterError { reason: "attempted to run an executor while another executor is already running" }', src/libcore/result.rs:999:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
Panic in Arbiter thread, shutting down system.
Run Code Online (Sandbox Code Playgroud)
主文件
extern crate actix_web;
extern crate serde_json;
extern crate actix_rt;
extern crate hyper;
use serde_json::{Value, json};
use hyper::{Client, Uri, Body, Request};
use actix_web::{middleware, web, App, HttpResponse, HttpServer};
use actix_rt::System;
use actix_web::client;
use …Run Code Online (Sandbox Code Playgroud)