Add GET peers/a.b.c.d handler in REST API (#564)

* Change name of get_peer to get_connected_peer and add a get_peer method with store
* Change to get_connected_peer
* Added handler for GET peers/a.b.c.d
This commit is contained in:
Quentin Le Sceller 2018-01-02 20:03:44 -05:00 committed by Ignotus Peverell
parent dc3a2113bd
commit 7b13b25782
3 changed files with 43 additions and 11 deletions

View file

@ -257,15 +257,14 @@ impl Handler for PeersConnectedHandler {
}
}
/// Get details about a given peer and peer operations
/// TODO GET /v1/peers/10.12.12.13
/// Peer operations
/// POST /v1/peers/10.12.12.13/ban
/// TODO POST /v1/peers/10.12.12.13/unban
pub struct PeerHandler {
pub struct PeerPostHandler {
pub peers: p2p::Peers,
}
impl Handler for PeerHandler {
impl Handler for PeerPostHandler {
fn handle(&self, req: &mut Request) -> IronResult<Response> {
let url = req.url.clone();
let mut path_elems = url.path();
@ -294,6 +293,29 @@ impl Handler for PeerHandler {
}
}
/// Get details about a given peer
pub struct PeerGetHandler {
pub peers: p2p::Peers,
}
impl Handler for PeerGetHandler {
fn handle(&self, req: &mut Request) -> IronResult<Response> {
let url = req.url.clone();
let mut path_elems = url.path();
if *path_elems.last().unwrap() == "" {
path_elems.pop();
}
if let Ok(addr) = path_elems.last().unwrap().parse() {
match self.peers.get_peer(addr) {
Ok(peer) => json_response(&peer),
Err(_) => Ok(Response::with((status::BadRequest, ""))),
}
} else {
Ok(Response::with((status::BadRequest, "")))
}
}
}
// Chain handler. Get the head details.
// GET /v1/chain
pub struct ChainHandler {
@ -491,7 +513,10 @@ let _ = thread::Builder::new()
let peers_connected_handler = PeersConnectedHandler {
peers: peers.clone(),
};
let peer_handler = PeerHandler {
let peer_post_handler = PeerPostHandler {
peers: peers.clone(),
};
let peer_get_handler = PeerGetHandler {
peers: peers.clone(),
};
@ -508,6 +533,7 @@ let _ = thread::Builder::new()
"post peers/a.b.c.d:p/ban".to_string(),
"get peers/all".to_string(),
"get peers/connected".to_string(),
"get peers/a.b.c.d".to_string(),
);
// We allow manually banning, like this:
// curl -v -X POST http://127.0.0.1:13413/v1/peers/88.99.251.87:13414/ban
@ -522,7 +548,8 @@ let _ = thread::Builder::new()
pool_push: post "/pool/push" => pool_push_handler,
peers_all: get "/peers/all" => peers_all_handler,
peers_connected: get "/peers/connected" => peers_connected_handler,
peer: post "/peers/*" => peer_handler,
peer: post "/peers/*" => peer_post_handler,
peer: get "/peers/*" => peer_get_handler
);
let mut apis = ApiServer::new("/v1".to_string());

View file

@ -70,7 +70,7 @@ impl Peers {
}
pub fn is_known(&self, addr: &SocketAddr) -> bool {
self.get_peer(addr).is_some()
self.get_connected_peer(addr).is_some()
}
/// Get vec of peers we are currently connected to.
@ -81,7 +81,7 @@ impl Peers {
}
/// Get a peer we're connected to by address.
pub fn get_peer(&self, addr: &SocketAddr) -> Option<Arc<RwLock<Peer>>> {
pub fn get_connected_peer(&self, addr: &SocketAddr) -> Option<Arc<RwLock<Peer>>> {
self.peers.read().unwrap().get(addr).map(|p| p.clone())
}
@ -185,7 +185,7 @@ impl Peers {
error!(LOGGER, "Couldn't ban {}: {:?}", peer_addr, e);
}
if let Some(peer) = self.get_peer(peer_addr) {
if let Some(peer) = self.get_connected_peer(peer_addr) {
debug!(LOGGER, "Banning peer {}", peer_addr);
// setting peer status will get it removed at the next clean_peer
let peer = peer.write().unwrap();
@ -262,6 +262,11 @@ impl Peers {
self.store.find_peers(state, cap, count)
}
/// Get peer in store by address
pub fn get_peer(&self, peer_addr: SocketAddr) -> Result<PeerData, Error> {
self.store.get_peer(peer_addr).map_err(From::from)
}
/// Whether we've already seen a peer with the provided address
pub fn exists_peer(&self, peer_addr: SocketAddr) -> Result<bool, Error> {
self.store.exists_peer(peer_addr).map_err(From::from)
@ -415,7 +420,7 @@ impl NetAdapter for Peers {
);
if diff.into_num() > 0 {
if let Some(peer) = self.get_peer(&addr) {
if let Some(peer) = self.get_connected_peer(&addr) {
let mut peer = peer.write().unwrap();
peer.info.total_difficulty = diff;
}

View file

@ -216,7 +216,7 @@ impl Server {
h: reactor::Handle,
) -> Box<Future<Item = Option<Arc<RwLock<Peer>>>, Error = Error>> {
if let Some(p) = self.peers.get_peer(&addr) {
if let Some(p) = self.peers.get_connected_peer(&addr) {
// if we're already connected to the addr, just return the peer
debug!(LOGGER, "connect_peer: already connected {}", addr);
return Box::new(future::ok(Some(p)));