英文:
Actix - two conflicting routes
问题
I have two services,
#[put("/{bucket_name}")]
pub async fn create_bucket(
bucket_name: web::Path<String>,
data: web::Data<crate::AppState>,
) -> Result<HttpResponse, Error> {
and
#[put("/{bucket}/{object_name}")]
pub async fn put_object(
bucket: web::Path<String>,
object_name: web::Path<String>,
data: web::Data<crate::AppState>,
_req: HttpRequest,
mut payload: web::Payload,
) -> Result<HttpResponse, Error> {
However, the second doesn't work, as it is not found. What can I do to handle both PUT but for different functions?
Currently it produces the following errors:
2023-05-20T13:12:07.324986Z INFO actix_web::middleware::logger: ::1 "PUT /sardor HTTP/1.1" 409 219 "-" "aws-cli/2.11.20 Python/3.11.3 Darwin/22.5.0 source/arm64 prompt/off command/s3.mb" 0.000900
2023-05-20T13:12:13.496646Z INFO actix_web::middleware::logger: ::1 "PUT /sardo/5.png HTTP/1.1" 404 40 "-" "aws-cli/2.11.20 Python/3.11.3 Darwin/22.5.0 source/arm64 prompt/off command/s3.cp" 0.000621
Registering services:
let server = HttpServer::new(move || {
App::new()
.wrap(middleware::Logger::default())
.service(apis::put_object::put_object)
.service(apis::create_bucket::create_bucket)
.service(apis::list_buckets::list_buckets)
.default_service(web::route().to(not_found))
.app_data(web::Data::new(AppState {
working_folder: config.working_folder.clone(),
}))
});
英文:
I have two services,
#[put("/{bucket_name}")]
pub async fn create_bucket(
bucket_name: web::Path<String>,
data: web::Data<crate::AppState>,
) -> Result<HttpResponse, Error> {
and
#[put("/{bucket}/{object_name}")]
pub async fn put_object(
bucket: web::Path<String>,
object_name: web::Path<String>,
data: web::Data<crate::AppState>,
_req: HttpRequest,
mut payload: web::Payload,
) -> Result<HttpResponse, Error> {
However, the second doesn't work, as it is not found. What can I do to handle both PUT
but for different functions?
Currently it produces the following errors:
2023-05-20T13:12:07.324986Z INFO actix_web::middleware::logger: ::1 "PUT /sardor HTTP/1.1" 409 219 "-" "aws-cli/2.11.20 Python/3.11.3 Darwin/22.5.0 source/arm64 prompt/off command/s3.mb" 0.000900
2023-05-20T13:12:13.496646Z INFO actix_web::middleware::logger: ::1 "PUT /sardo/5.png HTTP/1.1" 404 40 "-" "aws-cli/2.11.20 Python/3.11.3 Darwin/22.5.0 source/arm64 prompt/off command/s3.cp" 0.000621
Registering services:
let server = HttpServer::new(move || {
App::new()
.wrap(middleware::Logger::default())
.service(apis::put_object::put_object)
.service(apis::create_bucket::create_bucket)
.service(apis::list_buckets::list_buckets)
.default_service(web::route().to(not_found))
.app_data(web::Data::new(AppState {
working_folder: config.working_folder.clone(),
}))
});
答案1
得分: 1
I have done a different way, created one handler which handles all PUT /{}*
, and inside I match them myself.
#[put("/{tail}*")]
pub async fn handle_put(_: web::Path<String>, req: HttpRequest) -> Result<HttpResponse, Error> {
let mut path = Path::new(Url::new(req.uri().clone()));
let mut message = String::new();
let routes = [
("/{bucket}/{object_name}", "bucket and object"),
("/{bucket}", "bucket"),
];
for (pattern, description) in &routes {
if ResourceDef::new(*pattern).capture_match_info(&mut path) {
match (path.get("bucket"), path.get("object_name")) {
(Some(bucket), Some(object_name)) if *description == "bucket and object" => {
message = format!("bucket: {}, object_name: {}", bucket, object_name);
}
(Some(bucket), None) if *description == "bucket" => {
message = format!("bucket: {}", bucket);
}
_ => return Ok(HttpResponse::InternalServerError().finish()),
}
break;
}
}
if message.is_empty() {
Ok(HttpResponse::NotFound().finish())
} else {
Ok(HttpResponse::Ok().body(message))
}
}
(Note: I've removed the HTML encoding from the code snippet for clarity.)
英文:
I have done a different way, created one handler which handles all PUT /{}*
, and inside I match them myself.
#[put("/{tail}*")]
pub async fn handle_put(_: web::Path<String>, req: HttpRequest) -> Result<HttpResponse, Error> {
let mut path = Path::new(Url::new(req.uri().clone()));
let mut message = String::new();
let routes = [
("/{bucket}/{object_name}", "bucket and object"),
("/{bucket}", "bucket"),
];
for (pattern, description) in &routes {
if ResourceDef::new(*pattern).capture_match_info(&mut path) {
match (path.get("bucket"), path.get("object_name")) {
(Some(bucket), Some(object_name)) if *description == "bucket and object" => {
message = format!("bucket: {}, object_name: {}", bucket, object_name);
}
(Some(bucket), None) if *description == "bucket" => {
message = format!("bucket: {}", bucket);
}
_ => return Ok(HttpResponse::InternalServerError().finish()),
}
break;
}
}
if message.is_empty() {
Ok(HttpResponse::NotFound().finish())
} else {
Ok(HttpResponse::Ok().body(message))
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论