mirror of
https://github.com/ZeusWPI/ZNS.git
synced 2024-10-29 21:14:27 +01:00
Parsing rdata + get record
This commit is contained in:
parent
89df20d582
commit
335670c3c2
4 changed files with 76 additions and 20 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -106,6 +106,15 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.30"
|
||||
|
@ -305,6 +314,12 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
|
@ -631,6 +646,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"diesel",
|
||||
"dotenvy",
|
||||
"form_urlencoded",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
|
|
|
@ -7,6 +7,7 @@ edition = "2021"
|
|||
[dependencies]
|
||||
diesel = { version = "2.1.4", features = ["sqlite"] }
|
||||
dotenvy = "0.15"
|
||||
form_urlencoded = "1.2"
|
||||
tokio = {version = "1.36.0", features = ["macros","rt-multi-thread"], default-features = false}
|
||||
hyper = {version = "1.2.0", features = ["server", "http1"], default-features = false}
|
||||
hyper-util = { version = "0.1", features = ["server","http1", "tokio"], default-features = false}
|
||||
|
|
43
src/api.rs
43
src/api.rs
|
@ -1,10 +1,11 @@
|
|||
use std::collections::HashMap;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use http_body_util::{BodyExt, Full};
|
||||
use hyper::body::{Buf, Bytes};
|
||||
use hyper::server::conn::http1;
|
||||
use hyper::service::service_fn;
|
||||
use hyper::{header, Method, Request, Response, StatusCode};
|
||||
use hyper::{Method, Request, Response, StatusCode};
|
||||
use hyper_util::rt::TokioIo;
|
||||
use serde::Deserialize;
|
||||
use tokio::net::TcpListener;
|
||||
|
@ -28,18 +29,22 @@ struct Record {
|
|||
data: String,
|
||||
}
|
||||
|
||||
async fn api_post_response(req: Request<hyper::body::Incoming>) -> Result<Response<BoxBody>> {
|
||||
async fn create_record(req: Request<hyper::body::Incoming>) -> Result<Response<BoxBody>> {
|
||||
let whole_body = req.collect().await?.aggregate();
|
||||
|
||||
match serde_json::from_reader::<_, Record>(whole_body.reader()) {
|
||||
Ok(record) => {
|
||||
let rdata = record
|
||||
._type
|
||||
.to_bytes(&record.data)
|
||||
.map_err(|e| e.to_string())?;
|
||||
match insert_into_database(RR {
|
||||
name: record.name,
|
||||
_type: record._type,
|
||||
class: Class::IN,
|
||||
ttl: record.ttl,
|
||||
rdlength: record.data.as_bytes().len() as u16,
|
||||
rdata: record.data.as_bytes().to_vec(),
|
||||
rdlength: rdata.len() as u16,
|
||||
rdata,
|
||||
})
|
||||
.await
|
||||
{
|
||||
|
@ -55,30 +60,28 @@ async fn api_post_response(req: Request<hyper::body::Incoming>) -> Result<Respon
|
|||
}
|
||||
}
|
||||
Err(e) => Ok(Response::builder()
|
||||
.status(StatusCode::FORBIDDEN)
|
||||
.status(StatusCode::UNPROCESSABLE_ENTITY)
|
||||
.body(full(e.to_string()))?),
|
||||
}
|
||||
}
|
||||
|
||||
async fn api_get_response() -> Result<Response<BoxBody>> {
|
||||
let data = vec!["foo", "bar"];
|
||||
let res = match serde_json::to_string(&data) {
|
||||
Ok(json) => Response::builder()
|
||||
.header(header::CONTENT_TYPE, "application/json")
|
||||
.body(full(json))
|
||||
.unwrap(),
|
||||
Err(_) => Response::builder()
|
||||
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
.body(full(INTERNAL_SERVER_ERROR))
|
||||
.unwrap(),
|
||||
};
|
||||
Ok(res)
|
||||
async fn get_record(req: Request<hyper::body::Incoming>) -> Result<Response<BoxBody>> {
|
||||
if let Some(q) = req.uri().query() {
|
||||
let params = form_urlencoded::parse(q.as_bytes()).into_owned().collect::<HashMap<String,String>>();
|
||||
if let Some(domain) = params.get("domain_name") {
|
||||
return Ok(Response::builder().status(StatusCode::OK).body(full(domain.to_owned()))?)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Response::builder()
|
||||
.status(StatusCode::UNPROCESSABLE_ENTITY)
|
||||
.body(full("Missing domain_name query parameter"))?)
|
||||
}
|
||||
|
||||
async fn routes(req: Request<hyper::body::Incoming>) -> Result<Response<BoxBody>> {
|
||||
match (req.method(), req.uri().path()) {
|
||||
(&Method::POST, "/add") => api_post_response(req).await,
|
||||
(&Method::GET, "/json_api") => api_get_response().await,
|
||||
(&Method::POST, "/add") => create_record(req).await,
|
||||
(&Method::GET, "/get") => get_record(req).await,
|
||||
_ => Ok(Response::builder()
|
||||
.status(StatusCode::NOT_FOUND)
|
||||
.body(full(NOTFOUND))
|
||||
|
|
|
@ -38,6 +38,42 @@ pub trait FromBytes {
|
|||
Self: Sized;
|
||||
}
|
||||
|
||||
impl Type {
|
||||
pub fn to_bytes(&self, text: &String) -> Result<Vec<u8>> {
|
||||
match self {
|
||||
Type::A => {
|
||||
let arr: Vec<u8> = text
|
||||
.split(".")
|
||||
.filter_map(|s| s.parse::<u8>().ok())
|
||||
.collect();
|
||||
if arr.len() == 4 {
|
||||
Ok(arr)
|
||||
} else {
|
||||
Err(ParseError {
|
||||
object: String::from("Type::A"),
|
||||
message: String::from("Invalid IPv4 address"),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn from_bytes(&self, bytes: &[u8]) -> Result<String> {
|
||||
match self {
|
||||
Type::A => {
|
||||
if bytes.len() == 4 {
|
||||
let arr: Vec<String> = bytes.iter().map(|b| b.to_string()).collect();
|
||||
Ok(arr.join("."))
|
||||
} else {
|
||||
Err(ParseError {
|
||||
object: String::from("Type::A"),
|
||||
message: String::from("Invalid Ipv4 address bytes"),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromBytes for Header {
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||
if bytes.len() != size_of::<Header>() {
|
||||
|
|
Loading…
Reference in a new issue