Skip to content

Commit

Permalink
* port to hyper to enable https
Browse files Browse the repository at this point in the history
  • Loading branch information
mabels committed Oct 5, 2016
1 parent 5e29d7e commit 137bde5
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 115 deletions.
3 changes: 2 additions & 1 deletion woko/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ serde_codegen = "0.8"
[dependencies]
#nix = "0.7.0"
#libc = "0.2.16"
iron = "0.4.0"
#iron = "0.4.0"
hyper = "0.9.10"
#time = "0.1.35"
regex = "0.1.77"
#log = "0.3.6"
Expand Down
132 changes: 63 additions & 69 deletions woko/src/apt.rs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ include!(concat!(env!("OUT_DIR"), "/serde_types.rs"));
//}



//impl Deserialize for ReqPackageList {
// fn deserialize(deserializer: &mut ReqPackageList) -> Result<Self, ReqPackageList::Error> where Deserializer {
// Ok(ReqPackageList{
Expand All @@ -60,77 +59,72 @@ include!(concat!(env!("OUT_DIR"), "/serde_types.rs"));
//}

pub fn parse(req: &ReqPackageList) -> Result<Vec<PkgDesc>, String> {
let lxc_name = format!("{}-{}-{}", &req.dist, &req.version, &req.arch);
let mut fix_lxc_quirk_cmd = Command::new("lxc-info");
fix_lxc_quirk_cmd.arg("-n");
fix_lxc_quirk_cmd.arg(&lxc_name);
let fix_lxc_quirk_ = fix_lxc_quirk_cmd.output();
if fix_lxc_quirk_.is_err() {
return Err(format!("failed to execute lxc_info"));
}
let fix_lxc_quirk = fix_lxc_quirk_.unwrap();
if !fix_lxc_quirk.status.success() {
return Err(format!("failed to execute lxc_info for {} status {}",
&lxc_name,
fix_lxc_quirk.status.code().unwrap()));
}
let mut apt_get_cmd = Command::new("lxc-execute");
apt_get_cmd.arg("-n");
apt_get_cmd.arg(&lxc_name);
apt_get_cmd.arg("--");
apt_get_cmd.arg("apt-get");
apt_get_cmd.arg("install");
for pkg in &req.packages {
//println!("parse:1");
apt_get_cmd.arg(pkg);
}
apt_get_cmd.arg("--print-uris").arg("-qq");
let apt_get_ = apt_get_cmd.output();
if apt_get_.is_err() {
return Err(format!("failed to execute apt-get"));
}
let apt_get = apt_get_.unwrap();
println!(">>>>{} {:?} {:?}", apt_get.status,
apt_get.status.success(),
apt_get.status.code());
if !apt_get.status.success() {
return Err(format!("failed to execute apt-get status {}", apt_get.status.code().unwrap()));
}
return parse_from_string(&String::from_utf8_lossy(&apt_get.stdout)
.as_ref()
.to_string());
let lxc_name = format!("{}-{}-{}", &req.dist, &req.version, &req.arch);
let mut fix_lxc_quirk_cmd = Command::new("lxc-info");
fix_lxc_quirk_cmd.arg("-n");
fix_lxc_quirk_cmd.arg(&lxc_name);
let fix_lxc_quirk_ = fix_lxc_quirk_cmd.output();
if fix_lxc_quirk_.is_err() {
return Err(format!("failed to execute lxc_info"));
}
let fix_lxc_quirk = fix_lxc_quirk_.unwrap();
if !fix_lxc_quirk.status.success() {
return Err(format!("failed to execute lxc_info for {} status {}",
&lxc_name,
fix_lxc_quirk.status.code().unwrap()));
}
let mut apt_get_cmd = Command::new("lxc-execute");
apt_get_cmd.arg("-n");
apt_get_cmd.arg(&lxc_name);
apt_get_cmd.arg("--");
apt_get_cmd.arg("apt-get");
apt_get_cmd.arg("install");
for pkg in &req.packages {
//println!("parse:1");
apt_get_cmd.arg(pkg);
}
apt_get_cmd.arg("--print-uris").arg("-qq");
let apt_get_ = apt_get_cmd.output();
if apt_get_.is_err() {
return Err(format!("failed to execute apt-get"));
}
let apt_get = apt_get_.unwrap();
println!(">>>>{} {:?} {:?}", apt_get.status,
apt_get.status.success(),
apt_get.status.code());
if !apt_get.status.success() {
return Err(format!("failed to execute apt-get status {}", apt_get.status.code().unwrap()));
}

return parse_from_string(&String::from_utf8_lossy(&apt_get.stdout)
.as_ref()
.to_string());
}

pub fn parse_from_string(lines: &String) -> Result<Vec<PkgDesc>, String> {
let mut ret: Vec<PkgDesc> = Vec::new();
let re = Regex::new(r"^'((?:[^'\\]|\\.)*)'\s+(\S+)\s+(\d+)\s+(\S+):(\S+)$").unwrap();
let re_crnl = Regex::new(r"\s*[\n\r]+\s*").unwrap();
let mut split = re_crnl.split(lines);
loop {
match split.next() {
None => {
break;
}
Some(line) => {
//println!(">{}", line);
for cap in re.captures_iter(line) {
let pkg_desc = PkgDesc {
// url: "url",
// name: "name",
// size: 4711,
// sum_type: "sum_type",
// sum: "sum",
url: cap.at(1).unwrap().to_string(),
name: cap.at(2).unwrap().to_string(),
size: cap.at(3).unwrap().parse::<usize>().unwrap(),
sum_type: cap.at(4).unwrap().to_string(),
sum: cap.at(5).unwrap().to_string(),
};
ret.push(pkg_desc);
}
}
let mut ret: Vec<PkgDesc> = Vec::new();
let re = Regex::new(r"^'((?:[^'\\]|\\.)*)'\s+(\S+)\s+(\d+)\s+(\S+):(\S+)$").unwrap();
let re_crnl = Regex::new(r"\s*[\n\r]+\s*").unwrap();
let mut split = re_crnl.split(lines);
loop {
match split.next() {
None => {
break;
}
Some(line) => {
//println!(">{}", line);
for cap in re.captures_iter(line) {
let pkg_desc = PkgDesc {
url: cap.at(1).unwrap().to_string(),
name: cap.at(2).unwrap().to_string(),
size: cap.at(3).unwrap().parse::<usize>().unwrap(),
sum_type: cap.at(4).unwrap().to_string(),
sum: cap.at(5).unwrap().to_string(),
};
ret.push(pkg_desc);
}
}
}
return Ok(ret);
}
return Ok(ret);
}
Empty file modified woko/src/lib.rs
100644 → 100755
Empty file.
142 changes: 107 additions & 35 deletions woko/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,72 +1,144 @@
//#![feature(custom_derive, plugin)]
//#![plugin(serde_macros)]


extern crate regex;
extern crate iron;
// extern crate iron;
//extern crate bodyparser;
//extern crate time;
//extern crate persistent;
//extern crate rustc_serialize;
extern crate serde_json;
extern crate hyper;

pub mod apt;


//use woko::apt;
use iron::prelude::*;
use std::io::Read;
use std::io::Write;
//use iron::{BeforeMiddleware, AfterMiddleware, typemap};
//use time::precise_time_ns;

//use persistent::Read;
use iron::status;
use iron::headers;
// use iron::prelude::*;
// use iron::status;
// use iron::headers;

use hyper::net::Openssl;
// use std::io;
use hyper::server::{Server, Request, Response};
use hyper::status::StatusCode;
use hyper::header::{ContentType};
use hyper::mime::{Mime, TopLevel, SubLevel};


//use rustc_serialize::json::{self};
//use rustc_serialize::json;

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

fn apt_process(req: &mut Request) -> IronResult<Response> {
// fn apt_process(req: &mut Request) -> IronResult<Response> {
//
// //println!(">-<");
// //let payload = req.get::<bodyparser::Struct<apt::ReqPackageList>>();
// let mut req_buf = String::new();
// match req.body.read_to_string(&mut req_buf) {
// Ok(_) => {},
// Err(err) => return Ok(Response::with((status::ServiceUnavailable,
// format!("Internal Error:{}", err))))
// }
// let payload = serde_json::from_str::<apt::ReqPackageList>(&req_buf);
// //let payload = Some(None);
//
// //println!(">+<");
// match payload {
// Ok(plist) => {
// //println!(">0<");
// let result = apt::parse(&plist);
// if result.is_err() {
// return Ok(Response::with((status::ServiceUnavailable,
// format!("parse error {}", result.err().unwrap()))));
// }
// let mut resp = Response::with((status::Ok, serde_json::to_string(&result.unwrap()).unwrap()));
// resp.headers.set(headers::ContentType::json());
// return Ok(resp);
// }
// // Ok(None) => return Ok(Response::with((status::ServiceUnavailable, "No Json found"))),
// Err(err) => return Ok(Response::with((status::ServiceUnavailable,
// format!("Internal Error:{}", err)))),
// // _ => return Ok(Response::with((status::ServiceUnavailable, "unknown case")))
// }
// }

//println!(">-<");
//let payload = req.get::<bodyparser::Struct<apt::ReqPackageList>>();
let mut req_buf = String::new();
match req.body.read_to_string(&mut req_buf) {
Ok(_) => {},
Err(err) => return Ok(Response::with((status::ServiceUnavailable,
format!("Internal Error:{}", err))))
}
let payload = serde_json::from_str::<apt::ReqPackageList>(&req_buf);
//let payload = Some(None);

//println!(">+<");
match payload {
Ok(plist) => {
//println!(">0<");
let result = apt::parse(&plist);
if result.is_err() {
return Ok(Response::with((status::ServiceUnavailable,
format!("parse error {}", result.err().unwrap()))));
fn hyper_apt_process(req: Request, mut res: Response) {
match req.method {
hyper::Post => {
let mut max = 0;
let mut req_vec : Vec<u8> = Vec::new();
for c in req.bytes() {
req_vec.push(c.unwrap());
max += 1;
if max >= 8192 {
println!("to long");
*res.status_mut() = StatusCode::BadRequest;
return;
}
}
let mut resp = Response::with((status::Ok, serde_json::to_string(&result.unwrap()).unwrap()));
resp.headers.set(headers::ContentType::json());
return Ok(resp);
}
// Ok(None) => return Ok(Response::with((status::ServiceUnavailable, "No Json found"))),
Err(err) => return Ok(Response::with((status::ServiceUnavailable,
format!("Internal Error:{}", err)))),
// _ => return Ok(Response::with((status::ServiceUnavailable, "unknown case")))
match String::from_utf8(req_vec) {
Ok(req_buf) => {
match serde_json::from_str::<apt::ReqPackageList>(&req_buf) {
Ok(plist) => {
match apt::parse(&plist) {
Ok(apt) => {
// let mut resp = Response::with((status::Ok, serde_json::to_string(&result.unwrap()).unwrap()));
res.headers_mut().set(
ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![]))
);
// res.headers.set(headers::ContentType::json());
res.start().unwrap().write_all(serde_json::to_string(&apt).unwrap().as_bytes()).unwrap();
},
Err(err) => {
println!("apt-parse: {}", err);
*res.status_mut() = StatusCode::MethodNotAllowed
}
}
},
Err(err) => {
println!("json-parse: {}", err);
*res.status_mut() = StatusCode::MethodNotAllowed
}
}
},
Err(err) => {
println!("utf8-parse: {}", err);
*res.status_mut() = StatusCode::MethodNotAllowed
}

}
},
_ => *res.status_mut() = StatusCode::MethodNotAllowed
}
}

const MAX_BODY_LENGTH: usize = 1024 * 1024 * 1;

// const MAX_BODY_LENGTH: usize = 1024 * 1024 * 1;

fn main() {
let mut chain = Chain::new(apt_process);
let key = std::env::args().nth(1);
let cert = std::env::args().nth(2);
if key.is_some() && cert.is_some() {
let key_file = key.unwrap();
let cert_file = cert.unwrap();
println!("key={} cert={}", &key_file, &cert_file);
let ssl = Openssl::with_cert_and_key(&cert_file, &key_file).unwrap();
Server::https("0.0.0.0:8443", ssl).unwrap().handle(hyper_apt_process).unwrap();
} else {
Server::http("0.0.0.0:8080").unwrap().handle(hyper_apt_process).unwrap();
}
//let mut chain = Chain::new(apt_process);
//chain.link_before(Read::<bodyparser::MaxBodyLength>::one(MAX_BODY_LENGTH));
//chain.link_before(ResponseTime);
//chain.link_after(ResponseTime);
Iron::new(chain).http("0.0.0.0:7878").unwrap();
//Iron::new(chain).https("0.0.0.0:7878").unwrap();
}
19 changes: 9 additions & 10 deletions woko/src/serde_types.in.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@

#[derive(Serialize, Debug, Clone, Deserialize)] //, RustcDecodable, RustcEncodable)]
pub struct PkgDesc {
pub url: String,
pub name: String,
pub size: usize,
pub sum_type: String,
pub sum: String,
pub url: String,
pub name: String,
pub size: usize,
pub sum_type: String,
pub sum: String,
}

#[derive(Serialize, Debug, Clone, Deserialize)] //,RustcDecodable, RustcEncodable)]
pub struct ReqPackageList {
dist: String,
arch: String,
version: String,
packages: Vec<String>
dist: String,
arch: String,
version: String,
packages: Vec<String>
}

0 comments on commit 137bde5

Please sign in to comment.