我有一个小型的Rust程序,它格式化MySQL查询,但发现较大的查询失败,返回



我正在使用actix web,它看起来像这样

use actix_web::{
    web, App, HttpResponse, HttpServer, Result,
};

#[derive(Deserialize)]
pub struct MyParams {
    q: String,
}

fn index(params: web::Form<MyParams>) -> Result<HttpResponse> {
    Ok(HttpResponse::Ok()
        .content_type("text/html; charset=utf-8")
        .body("test"))
        // .body(mysql_format2(&params.q[..])))
}

fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new().service(
            web::resource("/")
                .route(web::post().to(index))
        )
    })
    .bind("127.0.0.1:48627")?
    .run()
}

和PHP脚本调用这看起来像

$this->FormattedMySQL = str_repeat("make a big query ", 1024*256);

$query =  http_build_query([
    'q' => $this->FormattedMySQL,
]);

// if I change this to 16385 (+1)
// then it breaks and returns that error
$query = substr($query, 0, 16384);

if ($this->FormatMySQL && strlen($query) <= 262144) {
    try {
        $this->VerbosePrint('formatting');
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, MYSQL_FORMAT_ENDPOINT);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $this->FormattedMySQL = curl_exec($ch);
        curl_close($ch);
    } catch (Exception $_) { }
}

我缺少什么,或者为什么这似乎是为16kB而不是256kB引发此错误?

我看到也可以使用set the Payload config,但是我不太确定如何/在何处将其应用到现有代码中。

最佳答案

快速的答案是有第二个配置(FormConfig),这是您要面对的问题。尚不清楚,因为它返回与PayloadConfig相同的错误类型(这是有原因的,我将在“较长版本”中解释)

将您的actix服务器定义更改为此,例如,将其更改为256kb:

HttpServer::new(|| {
    App::new().service(
        web::resource("/")
            .route(web::post()
                .to(index)
            )
            .data(web::Form::<MyParams>::configure(|cfg| cfg.limit(256 * 1024)))
    )
})
.bind("127.0.0.1:48627")?
.run()

您还需要导入actix_web::FromRequest,因为这是对象类型从请求更改为Urlencoded表单的地方,并且configure()方法存在。

现在,进行解释!

与其他框架一样,Actix也具有多层限制。您已经找到其中一个,这是另一个。

您找到的服务器可防止由于内存耗尽而导致拒绝服务(即有人将故意大的有效负载发送到服务器oom,因为服务器必须将主体存储在某个地方以进行处理)。它控制请求的整个有效负载。

您遇到的一个限制是对每个单独字段的限制要小得多,它的存在是为了防止发生另一种疲惫攻击。假设您的攻击者知道您正在使用某种东西来解析输入;我们假设它是JSON。通过发送任意大而复杂的JSON,它们可以在处理单个请求时有效地锁定服务器。小数据输入,后果非常严重。

因此,两个限制通常彼此独立,并允许您根据需要微调限制。很多小领域?没问题。一大块?也不是问题。

如果您想查看代码本身,FormConfig限制的影响位于here处。由于类型返回值与PayloadConfig限制(该结构的Overflow变体)[https://docs.rs/actix-web/1.0.7/actix_web/error/enum.UrlencodedError.html])相同,因此消息内容不清楚,最终您会挠头。

我认为该错误是“相似的”,其主要目的是防止服务器向潜在的攻击者(即it seems to be what they had in mind)指示限制其命中的限制。面向用户的错误描述是问题所在,而位置适当的PR可能会对此进行调整。

关于rust - “Urlencoded payload size is bigger than allowed (default: 256kB)”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57963082/

10-10 19:55