4个版本 (2个重大更新)

0.3.1 2019年5月8日
0.3.0 2019年4月12日
0.2.0 2019年4月11日
0.1.0 2019年4月10日

#9 in #HTTP POST

Apache-2.0

24KB
196

报告API和网络错误记录

Build Status Latest Version Rust Documentation

此crate提供了一些有用的Rust代码,用于处理W3C的《报告API》和《网络错误记录》草案规范。

[dependencies]
reporting-api = "^0.3"

概述

报告API的核心非常简单:通过POST请求将报告上传到您选择的URL。POST请求的有效负载是一个JSON编码的报告数组,报告模式由规范定义。

报告API可以用于上传许多不同类型的报告。例如,报告本身定义了来自浏览器中运行的JavaScript环境的崩溃报告弃用干预。其他报告类型可能相当复杂,需要在自己的规范中定义,例如网络错误记录内容安全策略。无论它们在哪里定义,每种报告类型都定义了一些特定于该类型的字段(即主体),报告API定义了一些所有类型都通用的字段。

此库提供所有这些架构的正则Rust类型定义,以及使用serde进行序列化和反序列化的能力。我们仔细定义了一切,以便serde_json会自动做正确的事情,并使用与各种规范一致的JSON序列化。我们还提供了一种定义新报告类型主体架构的方法,并使它们无缝地与序列化逻辑的其他部分集成。

收集报告

如果您只想从某个地方接收报告(例如,您正在实现一个收集器,而我们已经为所有您关心的报告类型定义了Rust类型),那么使用此库的最简单方法就是使用它。

要实现这一点,你只需使用serde_json来反序列化你收到的JSON字符串的内容即可。

let reports: Vec<BareReport> = serde_json::from_str(payload).unwrap();

就是这样!向量中的元素将代表这次上传批次中的每个报告。每个都是一个“裸”报告,这意味着我们没有试图确定报告的类型,或者哪个Rust类型与该报告类型相对应。相反,报告的原始正文(在body字段中)作为serde_jsonValue

如果你知道你想要处理哪种特定的报告类型,你可以使用裸报告的parse方法将其转换为“解析”后的报告。例如,如果你只关心网络错误记录报告。

// Ignore both kinds of failure, returning a Vec<Report<NEL>>.
let nel_reports = reports
    .into_iter()
    .filter_map(BareReport::parse::<NEL>)
    .filter_map(Result::ok)
    .collect::<Vec<Report<NEL>>>();

请注意,parse的返回值被包装在两者Option两者Result中。外层的Option告诉你报告是否为预期的类型。如果是,则内层的Result告诉你我们是否能够根据该类型预期的模式解析报告的body字段。在这个例子中,因此我们需要两次filter_map调用以去除任何不匹配和错误,从而留下一个Report<NEL>实例的向量。

创建一个新的报告类型

这种情况应该相对罕见,但考虑一个使用Reporting API但在这里没有涉及的新报告类型。例如,假设有一个新的lint报告类型,其正文内容如下:

{
    "source_file": "foo.js",
    "line": 10,
    "column": 12,
    "finding": "Indentation doesn't match the rest of the file"
}

首先,你需要定义一个Rust类型来保存正文内容。

#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct Lint {
    pub source_file: String,
    pub line: u32,
    pub column: u32,
    pub finding: String,
}

最后,你必须为你的新类型实现ReportType特理,该特理定义了报告负载中type字段的新报告类型的值。

impl ReportType for Lint {
    fn report_type() -> &'static str {
        "lint"
    }
}

就这样!现在parse方法将支持你的新报告类型。

依赖项

~0.6–1.4MB
~32K SLoC