Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use bodyparser::Struct to parse request bodies in HTTP Gateways #1227

Merged
merged 1 commit into from
Sep 14, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions components/builder-admin/doc/api.raml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ securitySchemes:
description: One or more matching entities found
404:
description: No matching entities found
422:
description: Malformed search term in request body
/accounts:
/{id}:
get:
Expand Down
25 changes: 10 additions & 15 deletions components/builder-admin/src/http/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use protocol::net::NetOk;
use protocol::search::FromSearchPair;
use protocol::sessionsrv::*;
use router::Router;
use serde_json::{self, Value};
use serde_json;

include!(concat!(env!("OUT_DIR"), "/serde_types.rs"));

Expand Down Expand Up @@ -111,22 +111,17 @@ pub fn status(_req: &mut Request) -> IronResult<Response> {
}

pub fn search(req: &mut Request) -> IronResult<Response> {
match req.get::<bodyparser::Json>() {
Ok(Some(ref body)) => {
let attr = match body.find("attr") {
Some(&Value::String(ref s)) => s.to_string(),
_ => return Ok(Response::with(status::UnprocessableEntity)),
};
let value = match body.find("value") {
Some(&Value::String(ref s)) => s.to_string(),
_ => return Ok(Response::with(status::UnprocessableEntity)),
};
match body.find("entity") {
Some(&Value::String(ref s)) if &*s == "account" => search_account(attr, value),
_ => Ok(Response::with(status::UnprocessableEntity)),
match req.get::<bodyparser::Struct<SearchTerm>>() {
Ok(Some(body)) => {
match &*body.entity.to_lowercase() {
"account" => search_account(body.attr, body.value),
entity => {
Ok(Response::with((status::UnprocessableEntity,
format!("Unknown search entity: {}", entity))))
}
}
}
_ => Ok(Response::with(status::BadRequest)),
_ => Ok(Response::with(status::UnprocessableEntity)),
}
}

Expand Down
7 changes: 7 additions & 0 deletions components/builder-admin/src/serde_types.in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,10 @@ impl FeatureFlag {
}
}
}

#[derive(Clone, Serialize, Deserialize)]
pub struct SearchTerm {
pub attr: String,
pub entity: String,
pub value: String,
}
6 changes: 5 additions & 1 deletion components/builder-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "habitat_builder_api"
version = "0.0.0"
authors = ["Adam Jacob <adam@chef.io>", "Jamie Winsor <reset@chef.io>", "Fletcher Nichol <fnichol@chef.io>", "Joshua Timberman <joshua@chef.io>", "Dave Parfitt <dparfitt@chef.io>"]
description = "Habitat-Builder HTTP API gateway"
build = "../build.rs"
build = "build.rs"
workspace = "../../"

[[bin]]
Expand All @@ -22,6 +22,7 @@ persistent = "*"
protobuf = "*"
router = "*"
rustc-serialize = "*"
serde = "*"
serde_json = "*"
staticfile = "*"
toml = "*"
Expand Down Expand Up @@ -52,6 +53,9 @@ path = "../net"
git = "https://github.com/habitat-sh/redis-rs"
branch = "habitat"

[build-dependencies]
serde_codegen = "*"

[replace]
"redis:0.7.0" = { git = 'https://github.com/habitat-sh/redis-rs', branch = 'habitat' }

Expand Down
42 changes: 42 additions & 0 deletions components/builder-api/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
extern crate serde_codegen;

use std::env;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::Path;

fn main() {
write_version_file();
codegen();
}

fn read_version() -> String {
let ver_file = Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap())
.parent()
.unwrap()
.parent()
.unwrap()
.join("VERSION");
let f = File::open(ver_file).unwrap();
let mut reader = BufReader::new(f);
let mut ver = String::new();
reader.read_line(&mut ver).unwrap();
ver
}

fn codegen() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let src = Path::new("src/serde_types.in.rs");
let dst = Path::new(&out_dir).join("serde_types.rs");
serde_codegen::expand(&src, &dst).unwrap();
}

fn write_version_file() {
let version = match env::var("PLAN_VERSION") {
Ok(ver) => ver,
_ => read_version(),
};
let mut f = File::create(Path::new(&env::var("OUT_DIR").unwrap()).join("VERSION")).unwrap();
f.write_all(version.as_bytes()).unwrap();
}
5 changes: 5 additions & 0 deletions components/builder-api/doc/api.raml
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ securitySchemes:
get:
securedBy: [oauth_2_0]
/{invitationId}:
delete:
securedBy: [oauth_2_0]
responses:
204:
description: Invitation successfully ignored
put:
securedBy: [oauth_2_0]
responses:
Expand Down