Actix – 两个冲突的路由

huangapple go评论76阅读模式
英文:

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(&quot;/{bucket_name}&quot;)]
pub async fn create_bucket(
    bucket_name: web::Path&lt;String&gt;,
    data: web::Data&lt;crate::AppState&gt;,
) -&gt; Result&lt;HttpResponse, Error&gt; {

and

#[put(&quot;/{bucket}/{object_name}&quot;)]
pub async fn put_object(
    bucket: web::Path&lt;String&gt;,
    object_name: web::Path&lt;String&gt;,
    data: web::Data&lt;crate::AppState&gt;,
    _req: HttpRequest,
    mut payload: web::Payload,
) -&gt; Result&lt;HttpResponse, Error&gt; {

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 &quot;PUT /sardor HTTP/1.1&quot; 409 219 &quot;-&quot; &quot;aws-cli/2.11.20 Python/3.11.3 Darwin/22.5.0 source/arm64 prompt/off command/s3.mb&quot; 0.000900 

2023-05-20T13:12:13.496646Z INFO actix_web::middleware::logger: ::1 &quot;PUT /sardo/5.png HTTP/1.1&quot; 404 40 &quot;-&quot; &quot;aws-cli/2.11.20 Python/3.11.3 Darwin/22.5.0 source/arm64 prompt/off command/s3.cp&quot; 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(&quot;/{tail}*&quot;)]
pub async fn handle_put(_: web::Path&lt;String&gt;, req: HttpRequest) -&gt; Result&lt;HttpResponse, Error&gt; {
    let mut path = Path::new(Url::new(req.uri().clone()));
    let mut message = String::new();

    let routes = [
        (&quot;/{bucket}/{object_name}&quot;, &quot;bucket and object&quot;),
        (&quot;/{bucket}&quot;, &quot;bucket&quot;),
    ];

    for (pattern, description) in &amp;routes {
        if ResourceDef::new(*pattern).capture_match_info(&amp;mut path) {
            match (path.get(&quot;bucket&quot;), path.get(&quot;object_name&quot;)) {
                (Some(bucket), Some(object_name)) if *description == &quot;bucket and object&quot; =&gt; {
                    message = format!(&quot;bucket: {}, object_name: {}&quot;, bucket, object_name);
                }
                (Some(bucket), None) if *description == &quot;bucket&quot; =&gt; {
                    message = format!(&quot;bucket: {}&quot;, bucket);
                }
                _ =&gt; return Ok(HttpResponse::InternalServerError().finish()),
            }
            break;
        }
    }

    if message.is_empty() {
        Ok(HttpResponse::NotFound().finish())
    } else {
        Ok(HttpResponse::Ok().body(message))
    }
}

huangapple
  • 本文由 发表于 2023年5月20日 21:04:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76295378.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定