{"action":"created","comment":{"url":"https://api.github.com/repos/Keats/rust-jwt/pulls/comments/44172614","id":44172614,"diff_hunk":"@@ -29,40 +30,69 @@ pub enum Algorithm {\n /// A part of the JWT: header and claims specifically\n /// Allows converting from/to struct with base64\n pub trait Part {\n-    fn from_base64(encoded: String) -> Result<Self, Error> where Self: Sized;\n-    fn to_base64(&self) -> Result<String, Error>;\n+    type Encoded: AsRef<str>;\n+\n+    fn from_base64<B: AsRef<[u8]>>(encoded: B) -> Result<Self, Error> where Self: Sized;\n+    fn to_base64(&self) -> Result<Self::Encoded, Error>;\n }\n \n impl<T> Part for T where T: Encodable + Decodable {\n-    fn to_base64(&self) -> Result<String, Error> {\n+    type Encoded = String;\n+\n+    fn to_base64(&self) -> Result<Self::Encoded, Error> {\n         let encoded = try!(json::encode(&self));\n         Ok(encoded.as_bytes().to_base64(base64::URL_SAFE))\n     }\n \n-    fn from_base64(encoded: String) -> Result<T, Error> {\n-        let decoded = try!(encoded.as_bytes().from_base64());\n+    fn from_base64<B: AsRef<[u8]>>(encoded: B) -> Result<T, Error> {\n+        let decoded = try!(encoded.as_ref().from_base64());\n         let s = try!(String::from_utf8(decoded));\n         Ok(try!(json::decode(&s)))\n     }\n }\n \n-#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable)]\n+#[derive(Debug, PartialEq)]\n /// A basic JWT header part, the alg is automatically filled for use\n /// It's missing things like the kid but that's for later\n pub struct Header {\n-    typ: String,\n+    typ: &'static str,\n     alg: Algorithm,\n }\n \n impl Header {\n     pub fn new(algorithm: Algorithm) -> Header {\n         Header {\n-            typ: \"JWT\".to_owned(),\n+            typ: \"JWT\",\n             alg: algorithm,\n         }\n     }\n }\n \n+impl Part for Header {\n+    type Encoded = &'static str;\n+\n+    fn from_base64<B: AsRef<[u8]>>(encoded: B) -> Result<Self, Error> where Self: Sized {\n+        let algoritm = match encoded.as_ref() {\n+            b\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\" => { Algorithm::HS256 },\n+            b\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9\" => { Algorithm::HS384 },\n+            b\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9\" => { Algorithm::HS512 },\n+            _ => return Err(Error::InvalidToken)\n+        };\n+\n+        Ok(Header::new(algoritm))\n+    }\n+\n+    fn to_base64(&self) -> Result<Self::Encoded, Error> {\n+        let encoded = match self.alg {\n+            Algorithm::HS256 => { \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\" },\n+            Algorithm::HS384 => { \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9\" },\n+            Algorithm::HS512 => { \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9\" },\n+        };\n+\n+        Ok(encoded)\n+    }\n+}","path":"src/lib.rs","position":87,"original_position":87,"commit_id":"64af1e239861aa9a59f9112de8d272e058e52e4e","original_commit_id":"64af1e239861aa9a59f9112de8d272e058e52e4e","user":{"login":"Keats","id":680355,"avatar_url":"https://avatars.githubusercontent.com/u/680355?v=3","gravatar_id":"","url":"https://api.github.com/users/Keats","html_url":"https://github.com/Keats","followers_url":"https://api.github.com/users/Keats/followers","following_url":"https://api.github.com/users/Keats/following{/other_user}","gists_url":"https://api.github.com/users/Keats/gists{/gist_id}","starred_url":"https://api.github.com/users/Keats/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Keats/subscriptions","organizations_url":"https://api.github.com/users/Keats/orgs","repos_url":"https://api.github.com/users/Keats/repos","events_url":"https://api.github.com/users/Keats/events{/privacy}","received_events_url":"https://api.github.com/users/Keats/received_events","type":"User","site_admin":false},"body":"The issue with that is that you loose any kind of support for other parameters in the header.\r\nFor example, google oauth seems to use the `kid` one (http://stackoverflow.com/questions/20159782/how-can-i-decode-a-google-oauth-2-0-jwt-openid-connect-in-a-node-app).","created_at":"2015-11-06T18:47:26Z","updated_at":"2015-11-06T18:47:26Z","html_url":"https://github.com/Keats/rust-jwt/pull/1#discussion_r44172614","pull_request_url":"https://api.github.com/repos/Keats/rust-jwt/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/Keats/rust-jwt/pulls/comments/44172614"},"html":{"href":"https://github.com/Keats/rust-jwt/pull/1#discussion_r44172614"},"pull_request":{"href":"https://api.github.com/repos/Keats/rust-jwt/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/Keats/rust-jwt/pulls/1","id":49982647,"html_url":"https://github.com/Keats/rust-jwt/pull/1","diff_url":"https://github.com/Keats/rust-jwt/pull/1.diff","patch_url":"https://github.com/Keats/rust-jwt/pull/1.patch","issue_url":"https://api.github.com/repos/Keats/rust-jwt/issues/1","number":1,"state":"open","locked":false,"title":"Improve user ergonomics, performance and deny a timing attack","user":{"login":"Ryman","id":994978,"avatar_url":"https://avatars.githubusercontent.com/u/994978?v=3","gravatar_id":"","url":"https://api.github.com/users/Ryman","html_url":"https://github.com/Ryman","followers_url":"https://api.github.com/users/Ryman/followers","following_url":"https://api.github.com/users/Ryman/following{/other_user}","gists_url":"https://api.github.com/users/Ryman/gists{/gist_id}","starred_url":"https://api.github.com/users/Ryman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ryman/subscriptions","organizations_url":"https://api.github.com/users/Ryman/orgs","repos_url":"https://api.github.com/users/Ryman/repos","events_url":"https://api.github.com/users/Ryman/events{/privacy}","received_events_url":"https://api.github.com/users/Ryman/received_events","type":"User","site_admin":false},"body":"(sorry for the bundled commits, I can separate them into separate PRs if you need)\r\n\r\nThis looks pretty useful so I wanted to help improve the ergonomics a bit (and then got a bit sidetracked in making it faster). Most of the ownership was not required (so `to_owned` is generally unnecessary), as the majority of work cannot be done in-place (at least not with current libraries).\r\n\r\nThis commit fixes a potential timing attack on hmac verification: 486c4a87f9603250167e40d70da2845e04a07500\r\n\r\nPerformance change:\r\n```bash\r\n# before\r\ntest bench_decode ... bench:      11,501 ns/iter (+/- 885)\r\ntest bench_encode ... bench:       5,036 ns/iter (+/- 511)\r\n\r\n# after\r\ntest bench_decode ... bench:       3,460 ns/iter (+/- 718)\r\ntest bench_encode ... bench:       3,964 ns/iter (+/- 516)\r\n```","created_at":"2015-11-06T17:40:45Z","updated_at":"2015-11-06T18:47:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"99ae24716ebf8b37cacd77c801a0359cbd650944","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Keats/rust-jwt/pulls/1/commits","review_comments_url":"https://api.github.com/repos/Keats/rust-jwt/pulls/1/comments","review_comment_url":"https://api.github.com/repos/Keats/rust-jwt/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Keats/rust-jwt/issues/1/comments","statuses_url":"https://api.github.com/repos/Keats/rust-jwt/statuses/64af1e239861aa9a59f9112de8d272e058e52e4e","head":{"label":"Ryman:patch","ref":"patch","sha":"64af1e239861aa9a59f9112de8d272e058e52e4e","user":{"login":"Ryman","id":994978,"avatar_url":"https://avatars.githubusercontent.com/u/994978?v=3","gravatar_id":"","url":"https://api.github.com/users/Ryman","html_url":"https://github.com/Ryman","followers_url":"https://api.github.com/users/Ryman/followers","following_url":"https://api.github.com/users/Ryman/following{/other_user}","gists_url":"https://api.github.com/users/Ryman/gists{/gist_id}","starred_url":"https://api.github.com/users/Ryman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ryman/subscriptions","organizations_url":"https://api.github.com/users/Ryman/orgs","repos_url":"https://api.github.com/users/Ryman/repos","events_url":"https://api.github.com/users/Ryman/events{/privacy}","received_events_url":"https://api.github.com/users/Ryman/received_events","type":"User","site_admin":false},"repo":{"id":45696478,"name":"rust-jwt","full_name":"Ryman/rust-jwt","owner":{"login":"Ryman","id":994978,"avatar_url":"https://avatars.githubusercontent.com/u/994978?v=3","gravatar_id":"","url":"https://api.github.com/users/Ryman","html_url":"https://github.com/Ryman","followers_url":"https://api.github.com/users/Ryman/followers","following_url":"https://api.github.com/users/Ryman/following{/other_user}","gists_url":"https://api.github.com/users/Ryman/gists{/gist_id}","starred_url":"https://api.github.com/users/Ryman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ryman/subscriptions","organizations_url":"https://api.github.com/users/Ryman/orgs","repos_url":"https://api.github.com/users/Ryman/repos","events_url":"https://api.github.com/users/Ryman/events{/privacy}","received_events_url":"https://api.github.com/users/Ryman/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Ryman/rust-jwt","description":"JWT lib in rust","fork":true,"url":"https://api.github.com/repos/Ryman/rust-jwt","forks_url":"https://api.github.com/repos/Ryman/rust-jwt/forks","keys_url":"https://api.github.com/repos/Ryman/rust-jwt/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Ryman/rust-jwt/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Ryman/rust-jwt/teams","hooks_url":"https://api.github.com/repos/Ryman/rust-jwt/hooks","issue_events_url":"https://api.github.com/repos/Ryman/rust-jwt/issues/events{/number}","events_url":"https://api.github.com/repos/Ryman/rust-jwt/events","assignees_url":"https://api.github.com/repos/Ryman/rust-jwt/assignees{/user}","branches_url":"https://api.github.com/repos/Ryman/rust-jwt/branches{/branch}","tags_url":"https://api.github.com/repos/Ryman/rust-jwt/tags","blobs_url":"https://api.github.com/repos/Ryman/rust-jwt/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Ryman/rust-jwt/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Ryman/rust-jwt/git/refs{/sha}","trees_url":"https://api.github.com/repos/Ryman/rust-jwt/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Ryman/rust-jwt/statuses/{sha}","languages_url":"https://api.github.com/repos/Ryman/rust-jwt/languages","stargazers_url":"https://api.github.com/repos/Ryman/rust-jwt/stargazers","contributors_url":"https://api.github.com/repos/Ryman/rust-jwt/contributors","subscribers_url":"https://api.github.com/repos/Ryman/rust-jwt/subscribers","subscription_url":"https://api.github.com/repos/Ryman/rust-jwt/subscription","commits_url":"https://api.github.com/repos/Ryman/rust-jwt/commits{/sha}","git_commits_url":"https://api.github.com/repos/Ryman/rust-jwt/git/commits{/sha}","comments_url":"https://api.github.com/repos/Ryman/rust-jwt/comments{/number}","issue_comment_url":"https://api.github.com/repos/Ryman/rust-jwt/issues/comments{/number}","contents_url":"https://api.github.com/repos/Ryman/rust-jwt/contents/{+path}","compare_url":"https://api.github.com/repos/Ryman/rust-jwt/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Ryman/rust-jwt/merges","archive_url":"https://api.github.com/repos/Ryman/rust-jwt/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Ryman/rust-jwt/downloads","issues_url":"https://api.github.com/repos/Ryman/rust-jwt/issues{/number}","pulls_url":"https://api.github.com/repos/Ryman/rust-jwt/pulls{/number}","milestones_url":"https://api.github.com/repos/Ryman/rust-jwt/milestones{/number}","notifications_url":"https://api.github.com/repos/Ryman/rust-jwt/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Ryman/rust-jwt/labels{/name}","releases_url":"https://api.github.com/repos/Ryman/rust-jwt/releases{/id}","created_at":"2015-11-06T17:26:49Z","updated_at":"2015-11-06T17:26:50Z","pushed_at":"2015-11-06T17:28:07Z","git_url":"git://github.com/Ryman/rust-jwt.git","ssh_url":"git@github.com:Ryman/rust-jwt.git","clone_url":"https://github.com/Ryman/rust-jwt.git","svn_url":"https://github.com/Ryman/rust-jwt","homepage":"","size":0,"stargazers_count":0,"watchers_count":0,"language":"Rust","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"Keats:master","ref":"master","sha":"4c6fa4945025f4f3aeeac4f48c803b4687172567","user":{"login":"Keats","id":680355,"avatar_url":"https://avatars.githubusercontent.com/u/680355?v=3","gravatar_id":"","url":"https://api.github.com/users/Keats","html_url":"https://github.com/Keats","followers_url":"https://api.github.com/users/Keats/followers","following_url":"https://api.github.com/users/Keats/following{/other_user}","gists_url":"https://api.github.com/users/Keats/gists{/gist_id}","starred_url":"https://api.github.com/users/Keats/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Keats/subscriptions","organizations_url":"https://api.github.com/users/Keats/orgs","repos_url":"https://api.github.com/users/Keats/repos","events_url":"https://api.github.com/users/Keats/events{/privacy}","received_events_url":"https://api.github.com/users/Keats/received_events","type":"User","site_admin":false},"repo":{"id":45360444,"name":"rust-jwt","full_name":"Keats/rust-jwt","owner":{"login":"Keats","id":680355,"avatar_url":"https://avatars.githubusercontent.com/u/680355?v=3","gravatar_id":"","url":"https://api.github.com/users/Keats","html_url":"https://github.com/Keats","followers_url":"https://api.github.com/users/Keats/followers","following_url":"https://api.github.com/users/Keats/following{/other_user}","gists_url":"https://api.github.com/users/Keats/gists{/gist_id}","starred_url":"https://api.github.com/users/Keats/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Keats/subscriptions","organizations_url":"https://api.github.com/users/Keats/orgs","repos_url":"https://api.github.com/users/Keats/repos","events_url":"https://api.github.com/users/Keats/events{/privacy}","received_events_url":"https://api.github.com/users/Keats/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Keats/rust-jwt","description":"JWT lib in rust","fork":false,"url":"https://api.github.com/repos/Keats/rust-jwt","forks_url":"https://api.github.com/repos/Keats/rust-jwt/forks","keys_url":"https://api.github.com/repos/Keats/rust-jwt/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Keats/rust-jwt/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Keats/rust-jwt/teams","hooks_url":"https://api.github.com/repos/Keats/rust-jwt/hooks","issue_events_url":"https://api.github.com/repos/Keats/rust-jwt/issues/events{/number}","events_url":"https://api.github.com/repos/Keats/rust-jwt/events","assignees_url":"https://api.github.com/repos/Keats/rust-jwt/assignees{/user}","branches_url":"https://api.github.com/repos/Keats/rust-jwt/branches{/branch}","tags_url":"https://api.github.com/repos/Keats/rust-jwt/tags","blobs_url":"https://api.github.com/repos/Keats/rust-jwt/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Keats/rust-jwt/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Keats/rust-jwt/git/refs{/sha}","trees_url":"https://api.github.com/repos/Keats/rust-jwt/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Keats/rust-jwt/statuses/{sha}","languages_url":"https://api.github.com/repos/Keats/rust-jwt/languages","stargazers_url":"https://api.github.com/repos/Keats/rust-jwt/stargazers","contributors_url":"https://api.github.com/repos/Keats/rust-jwt/contributors","subscribers_url":"https://api.github.com/repos/Keats/rust-jwt/subscribers","subscription_url":"https://api.github.com/repos/Keats/rust-jwt/subscription","commits_url":"https://api.github.com/repos/Keats/rust-jwt/commits{/sha}","git_commits_url":"https://api.github.com/repos/Keats/rust-jwt/git/commits{/sha}","comments_url":"https://api.github.com/repos/Keats/rust-jwt/comments{/number}","issue_comment_url":"https://api.github.com/repos/Keats/rust-jwt/issues/comments{/number}","contents_url":"https://api.github.com/repos/Keats/rust-jwt/contents/{+path}","compare_url":"https://api.github.com/repos/Keats/rust-jwt/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Keats/rust-jwt/merges","archive_url":"https://api.github.com/repos/Keats/rust-jwt/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Keats/rust-jwt/downloads","issues_url":"https://api.github.com/repos/Keats/rust-jwt/issues{/number}","pulls_url":"https://api.github.com/repos/Keats/rust-jwt/pulls{/number}","milestones_url":"https://api.github.com/repos/Keats/rust-jwt/milestones{/number}","notifications_url":"https://api.github.com/repos/Keats/rust-jwt/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Keats/rust-jwt/labels{/name}","releases_url":"https://api.github.com/repos/Keats/rust-jwt/releases{/id}","created_at":"2015-11-01T22:35:34Z","updated_at":"2015-11-03T13:06:39Z","pushed_at":"2015-11-06T17:40:45Z","git_url":"git://github.com/Keats/rust-jwt.git","ssh_url":"git@github.com:Keats/rust-jwt.git","clone_url":"https://github.com/Keats/rust-jwt.git","svn_url":"https://github.com/Keats/rust-jwt","homepage":"","size":0,"stargazers_count":1,"watchers_count":1,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":1,"forks":1,"open_issues":1,"watchers":1,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Keats/rust-jwt/pulls/1"},"html":{"href":"https://github.com/Keats/rust-jwt/pull/1"},"issue":{"href":"https://api.github.com/repos/Keats/rust-jwt/issues/1"},"comments":{"href":"https://api.github.com/repos/Keats/rust-jwt/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/Keats/rust-jwt/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/Keats/rust-jwt/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Keats/rust-jwt/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/Keats/rust-jwt/statuses/64af1e239861aa9a59f9112de8d272e058e52e4e"}}}}