-
Notifications
You must be signed in to change notification settings - Fork 462
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Iotedged: Encode deviceId/moduleId for IOThub operations (#750)
* Add url encoding * Cleanup * Add test * Use percent encoding * Fix test * Fixing formatting * Remove println * Remove tostring.. return PercentEncode<T> instead
- Loading branch information
1 parent
4992833
commit bb10be0
Showing
4 changed files
with
76 additions
and
4 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,13 +4,18 @@ use failure::{Fail, ResultExt}; | |
use futures::future::{self, Either}; | ||
use futures::Future; | ||
use hyper::{Method, StatusCode}; | ||
use percent_encoding::{percent_encode, PercentEncode, PATH_SEGMENT_ENCODE_SET}; | ||
|
||
use edgelet_http::client::{Client, ClientImpl, TokenSource}; | ||
use edgelet_http::error::ErrorKind as HttpErrorKind; | ||
use edgelet_utils::ensure_not_empty_with_context; | ||
use error::{Error, ErrorKind, ModuleOperationReason}; | ||
use model::{AuthMechanism, Module}; | ||
|
||
define_encode_set! { | ||
pub IOTHUB_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | { '=' } | ||
} | ||
|
||
pub struct DeviceClient<C, T> { | ||
client: Client<C, T>, | ||
device_id: String, | ||
|
@@ -81,7 +86,11 @@ where | |
.client | ||
.request::<Module, Module>( | ||
Method::PUT, | ||
&format!("/devices/{}/modules/{}", &self.device_id, module_id), | ||
&format!( | ||
"/devices/{}/modules/{}", | ||
url_encode(&self.device_id), | ||
url_encode(&module_id) | ||
), | ||
None, | ||
Some(module), | ||
add_if_match, | ||
|
@@ -113,7 +122,11 @@ where | |
.client | ||
.request::<(), Module>( | ||
Method::GET, | ||
&format!("/devices/{}/modules/{}", &self.device_id, module_id), | ||
&format!( | ||
"/devices/{}/modules/{}", | ||
url_encode(&self.device_id), | ||
url_encode(&module_id) | ||
), | ||
None, | ||
None, | ||
false, | ||
|
@@ -148,7 +161,7 @@ where | |
self.client | ||
.request::<(), Vec<Module>>( | ||
Method::GET, | ||
&format!("/devices/{}/modules", &self.device_id), | ||
&format!("/devices/{}/modules", url_encode(&self.device_id)), | ||
None, | ||
None, | ||
false, | ||
|
@@ -174,7 +187,11 @@ where | |
.client | ||
.request::<(), ()>( | ||
Method::DELETE, | ||
&format!("/devices/{}/modules/{}", self.device_id, module_id), | ||
&format!( | ||
"/devices/{}/modules/{}", | ||
url_encode(&self.device_id), | ||
url_encode(&module_id) | ||
), | ||
None, | ||
None, | ||
true, | ||
|
@@ -200,6 +217,10 @@ where | |
} | ||
} | ||
|
||
fn url_encode(value: &str) -> PercentEncode<'_, IOTHUB_ENCODE_SET> { | ||
percent_encode(value.as_bytes(), IOTHUB_ENCODE_SET) | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
@@ -636,6 +657,53 @@ mod tests { | |
.unwrap(); | ||
} | ||
|
||
#[test] | ||
fn modules_get_request_with_encoding() { | ||
let api_version = "2018-04-10".to_string(); | ||
let host_name = Url::parse("http://localhost").unwrap(); | ||
let auth = AuthMechanism::default() | ||
.with_type(AuthType::Sas) | ||
.with_symmetric_key( | ||
SymmetricKey::default() | ||
.with_primary_key("pkey".to_string()) | ||
.with_secondary_key("skey".to_string()), | ||
); | ||
let module = Module::default() | ||
.with_device_id("[email protected]#st".to_string()) | ||
.with_module_id("$edgeAgent".to_string()) | ||
.with_generation_id("g1".to_string()) | ||
.with_managed_by("iotedge".to_string()) | ||
.with_authentication(auth.clone()); | ||
let expected_module = module.clone(); | ||
|
||
let handler = move |req: Request<Body>| { | ||
assert_eq!(req.method(), &Method::GET); | ||
assert_eq!(req.uri().path(), "/devices/[email protected]%23st/modules/$edgeAgent"); | ||
assert_eq!(None, req.headers().get(hyper::header::IF_MATCH)); | ||
|
||
let mut response = Response::new(serde_json::to_string(&module).unwrap().into()); | ||
response | ||
.headers_mut() | ||
.typed_insert(&ContentType(mime::APPLICATION_JSON)); | ||
Ok(response) | ||
}; | ||
let client = Client::new(handler, Some(NullTokenSource), api_version, host_name).unwrap(); | ||
|
||
let device_client = DeviceClient::new(client, "[email protected]#st".to_string()).unwrap(); | ||
let task = device_client | ||
.get_module_by_id("$edgeAgent".to_string()) | ||
.then(|module| { | ||
let module = module.unwrap(); | ||
assert_eq!(expected_module, module); | ||
Ok::<_, Error>(()) | ||
}); | ||
|
||
tokio::runtime::current_thread::Runtime::new() | ||
.unwrap() | ||
.block_on(task) | ||
.unwrap(); | ||
} | ||
|
||
#[test] | ||
fn modules_get_not_found() { | ||
let api_version = "2018-04-10".to_string(); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters