Panic on chain/outputs API (#1086) (#1089)

This commit is contained in:
Gary Yu
2018-06-29 23:03:06 +08:00
committed by Yeastplume
parent 43540b36f6
commit 9654ee237b
2 changed files with 57 additions and 7 deletions
+41 -5
View File
@@ -57,6 +57,11 @@ impl Handler for IndexHandler {
}
}
struct HandlerResult {
with_status: status::Status,
with_body: String,
}
// Supports retrieval of multiple outputs in a single request -
// GET /v1/chain/outputs/byids?id=xxx,yyy,zzz
// GET /v1/chain/outputs/byids?id=xxx&id=yyy&id=zzz
@@ -158,7 +163,11 @@ impl OutputHandler {
}
// returns outputs for a specified range of blocks
fn outputs_block_batch(&self, req: &mut Request) -> Vec<BlockOutputs> {
fn outputs_block_batch(
&self,
req: &mut Request,
result: &mut HandlerResult,
) -> Vec<BlockOutputs> {
let mut commitments: Vec<Commitment> = vec![];
let mut start_height = 1;
let mut end_height = 1;
@@ -176,12 +185,28 @@ impl OutputHandler {
}
if let Some(heights) = params.get("start_height") {
for height in heights {
start_height = height.parse().unwrap();
start_height = match height.parse() {
Ok(h) => h,
_ => {
result.with_status = status::BadRequest;
result.with_body =
String::from("start_height parse error. check request format");
return vec![];
}
}
}
}
if let Some(heights) = params.get("end_height") {
for height in heights {
end_height = height.parse().unwrap();
end_height = match height.parse() {
Ok(h) => h,
_ => {
result.with_status = status::BadRequest;
result.with_body =
String::from("end_height parse error. check request format");
return vec![];
}
}
}
}
if let Some(_) = params.get("include_rp") {
@@ -217,10 +242,21 @@ impl Handler for OutputHandler {
if *path_elems.last().unwrap() == "" {
path_elems.pop();
}
match *path_elems.last().unwrap() {
let mut result = HandlerResult {
with_status: status::Ok,
with_body: String::new(),
};
let response = match *path_elems.last().unwrap() {
"byids" => json_response(&self.outputs_by_ids(req)),
"byheight" => json_response(&self.outputs_block_batch(req)),
"byheight" => json_response(&self.outputs_block_batch(req, &mut result)),
_ => Ok(Response::with((status::BadRequest, ""))),
};
match result.with_status {
status::Ok => response,
_ => Ok(Response::with((result.with_status, result.with_body))),
}
}
}
+16 -2
View File
@@ -16,7 +16,6 @@
/// to bytes. Given that rustc-serialize is deprecated and serde doesn't
/// provide easy hex encoding, hex is a bit in limbo right now in Rust-
/// land. It's simple enough that we can just have our own.
use std::fmt::Write;
use std::num;
@@ -31,11 +30,17 @@ pub fn to_hex(bytes: Vec<u8>) -> String {
/// Decode a hex string into bytes.
pub fn from_hex(hex_str: String) -> Result<Vec<u8>, num::ParseIntError> {
let hex_trim = if &hex_str[..2] == "0x" {
let mut hex_trim = if hex_str.len() >= 2 && &hex_str[..2] == "0x" {
hex_str[2..].to_owned()
} else {
hex_str.clone()
};
// fill one nibble if having half byte tail
if hex_trim.len() & 1 != 0 {
hex_trim.push('0');
}
split_n(&hex_trim.trim()[..], 2)
.iter()
.map(|b| u8::from_str_radix(b, 16))
@@ -43,6 +48,9 @@ pub fn from_hex(hex_str: String) -> Result<Vec<u8>, num::ParseIntError> {
}
fn split_n(s: &str, n: usize) -> Vec<&str> {
if s.len() < n {
return vec![];
}
(0..(s.len() - n + 1) / 2 + 1)
.map(|i| &s[2 * i..2 * i + n])
.collect()
@@ -70,5 +78,11 @@ mod test {
from_hex("000000ff".to_string()).unwrap(),
vec![0, 0, 0, 255]
);
assert!(
from_hex("".to_string()).is_ok(),
"should return Ok([]) for empty string"
);
assert_eq!(from_hex("0".to_string()).unwrap(), vec![0]);
assert_eq!(from_hex("0ff".to_string()).unwrap(), vec![15, 240]);
}
}