Skip to content

Commit

Permalink
feat: add bugcheck api
Browse files Browse the repository at this point in the history
  • Loading branch information
zleyyij committed Sep 26, 2024
1 parent c9522fc commit cc72918
Show file tree
Hide file tree
Showing 9 changed files with 732 additions and 9 deletions.
50 changes: 49 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Current information fetched includes:
- CPU info (Intel ARK, AMD Product Database)
- USB info (VID/PID mapping)
- PCIe info (VID/PID/SUBSYS mapping)
- Windows BugCheck error codes

## Project layout
The code is organized into 4 separate crates:
Expand Down Expand Up @@ -158,4 +159,51 @@ And here's example response (truncated):
"subsystem":null
},
]
```
```

### BugCheck
To interact with the bugcheck API, submit a `GET` request to `/api/bugcheck/?code=[BUGCHECK_CODE]`, where `[BUGCHECK_CODE]` is an integer value of a valid bugcheck code.

The endpoint will return a structure that looks like this:
```json
{
"code": "number",
"name": "string",
"url": "string",
}
```

Responses:<br>
| Code | Meaning |
| -- | -- |
| `404` | No bugcheck is associated with that code|


Here's an example curl request:
```
curl http://127.0.0.1:3000/api/bugcheck/?code=1
```

For bulk processing, you may submit a `POST` request to the same endpoint with a `Content-Type` of `application/json` and a payload containing an array of bugcheck codes (as numbers).

The endpoint will return an array of objects (same shape as the `GET` request), or if an identifier string was unable to be processed successfully, `null` will substitute in the response.

Here's an example curl request:
```
curl -X POST http://127.0.0.1:3000/api/bugcheck/ -H "Content-Type: application/json" -d '[1, 2, 3, 4, 5]'
```

And here's an example response (truncated):
```json
[
{
"vendor":"SteelSeries ApS",
"device":null
},
{
"vendor":"Dell Computer Corp.",
"device":"Model L100 Keyboard"
},
null
]
```
19 changes: 19 additions & 0 deletions databases/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use parsing::bugcheck::CodeCache;
use parsing::cpu::IntermediateCpuCache;
use std::collections::HashSet;
use std::fs::File;
Expand All @@ -10,6 +11,24 @@ fn main() {
// println!("cargo::rerun-if-changed=build.rs");
gen_amd_cpus();
gen_intel_cpus();
gen_bugcheck();
}

/// Parse the windows bugcheck codes and generate `src/bugcheck/bugcheck_codegen.rs`
fn gen_bugcheck() {
let destination = Path::new("src/bugcheck/").join("bugcheck_codegen.rs");
let mut generated_file = BufWriter::new(File::create(destination).unwrap());
let mut generated_map = phf_codegen::Map::new();
let cache = CodeCache::new();
for (code, (name, url)) in cache.iter() {
generated_map.entry(code, &format!("({name:?}, {url:?})"));
}
write!(
&mut generated_file,
"// This file was autogenerated by build.rs\n#[rustfmt::skip]\n#[allow(clippy::all)]\npub static BUGCHECK_CODES: phf::Map<u64, (&'static str, &'static str)> = {};",
generated_map.build()
)
.unwrap();
}

/// Parse the database for AMD cpus and generate `src/cpu/amd_codegen.rs`
Expand Down
23 changes: 23 additions & 0 deletions databases/src/bugcheck/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
mod bugcheck_codegen;
use bugcheck_codegen::BUGCHECK_CODES;

#[derive(Clone)]
pub struct BugCheckCache {}

impl BugCheckCache {
/// Construct a new cache
pub fn new() -> Self {
Self {}
}

#[tracing::instrument(name = "bugcheck_lookup", skip(self))]
pub fn get(&self, code: u64) -> Option<&(&str, &str)> {
BUGCHECK_CODES.get(&code)
}
}

impl Default for BugCheckCache {
fn default() -> Self {
Self::new()
}
}
1 change: 1 addition & 0 deletions databases/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! This crate contains the interfaces used in production to store and lookup info.
pub mod bugcheck;
pub mod cpu;
pub mod pcie;
pub mod usb;
53 changes: 53 additions & 0 deletions handlers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use axum::extract::Query;
use axum::http::StatusCode;
use axum::{extract::State, Json};
use databases::bugcheck::BugCheckCache;
use databases::cpu::Cpu;
use databases::{cpu::CpuCache, pcie::PcieCache, usb::UsbCache};
use serde::{Deserialize, Serialize};
Expand All @@ -12,6 +13,7 @@ pub struct AppState {
pub cpu_cache: CpuCache,
pub usb_cache: UsbCache,
pub pcie_cache: PcieCache,
pub bugcheck_cache: BugCheckCache,
}

#[derive(Debug, Deserialize, Serialize)]
Expand Down Expand Up @@ -156,3 +158,54 @@ pub async fn get_cpu_handler(
}
}
}

#[derive(Serialize, Deserialize)]
pub struct GetBugCheckQuery {
code: u64,
}

#[derive(Deserialize, Serialize)]
pub struct BugCheckResponse {
code: u64,
name: String,
url: String,
}
/// This handler accepts a `GET` request to `/api/bugcheck/?code=[CODE]`
pub async fn get_bugcheck_handler(
State(state): State<AppState>,
Query(query): Query<GetBugCheckQuery>,
) -> Result<Json<BugCheckResponse>, StatusCode> {
if let Some((name, url)) = state.bugcheck_cache.get(query.code) {
Ok(Json(BugCheckResponse {
code: query.code,
name: name.to_string(),
url: url.to_string(),
}))
} else {
Err(StatusCode::NOT_FOUND)
}
}

/// This handler accepts a `POST` request to `/api/bugcheck/`, with a body containing a serialized array of bugcheck code numbers.
/// Any unknown bugcheck codes will be substituted with `null`
#[tracing::instrument(name = "bulk_bugcheck_handler", skip(state))]
pub async fn post_bugcheck_handler(
State(state): State<AppState>,
Json(query): Json<Vec<u64>>,
) -> Result<Json<Vec<Option<BugCheckResponse>>>, StatusCode> {
let mut response: Vec<Option<BugCheckResponse>> = Vec::with_capacity(16);
for entry in query {
if let Some((name, url)) = state.bugcheck_cache.get(entry) {
response.push({
Some(BugCheckResponse {
code: entry,
name: name.to_string(),
url: url.to_string(),
})
});
} else {
response.push(None);
}
}
Ok(Json(response))
}
Loading

0 comments on commit cc72918

Please sign in to comment.