Skip to content

Commit 0d4486d

Browse files
author
Mark Adamcin
committed
resolved two parts to defect-2; dropped visibility of new AsyncUtil method to prevent use outside of package
1 parent 1da7070 commit 0d4486d

File tree

3 files changed

+125
-10
lines changed

3 files changed

+125
-10
lines changed

api/src/main/java/net/adamcin/httpsig/api/Constants.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,21 +123,17 @@ public static List<String> parseTokens(String tokens) {
123123
if (tokens == null || tokens.trim().isEmpty()) {
124124
return Collections.emptyList();
125125
} else {
126-
List<String> tokenList = new ArrayList<String>();
127-
String[] _tokens = tokens.trim().split("\\s+");
128-
for (String _token : _tokens) {
129-
tokenList.add(_token);
130-
}
131-
return Collections.unmodifiableList(tokenList);
126+
return Collections.unmodifiableList(Arrays.asList(tokens.trim().split("\\s+")));
132127
}
133128
}
134129

135130
public static String constructTokensString(List<String> tokens) {
136131
StringBuilder sb = new StringBuilder();
137-
if (tokens != null) {
132+
if (tokens != null && !tokens.isEmpty()) {
138133
for (String token : tokens) {
139134
sb.append(token).append(" ");
140135
}
136+
sb.deleteCharAt(sb.length() - 1);
141137
}
142138
return sb.toString();
143139
}
@@ -154,10 +150,10 @@ public static Map<String, String> parseRFC2617(String header) {
154150
}
155151

156152
public static String constructRFC2617(Map<String, String> params) {
157-
StringBuilder sb = new StringBuilder(SCHEME);
153+
StringBuilder sb = new StringBuilder(SCHEME + ' ');
158154
if (params != null && !params.isEmpty()) {
159155
for (Map.Entry<String, String> param : params.entrySet()) {
160-
sb.append(" ").append(param.getKey()).append("=\"").append(param.getValue()).append("\"").append(",");
156+
sb.append(param.getKey()).append("=\"").append(param.getValue()).append("\"").append(",");
161157
}
162158
sb.deleteCharAt(sb.length() - 1);
163159
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* This is free and unencumbered software released into the public domain.
3+
*
4+
* Anyone is free to copy, modify, publish, use, compile, sell, or
5+
* distribute this software, either in source code form or as a compiled
6+
* binary, for any purpose, commercial or non-commercial, and by any
7+
* means.
8+
*
9+
* In jurisdictions that recognize copyright laws, the author or authors
10+
* of this software dedicate any and all copyright interest in the
11+
* software to the public domain. We make this dedication for the benefit
12+
* of the public at large and to the detriment of our heirs and
13+
* successors. We intend this dedication to be an overt act of
14+
* relinquishment in perpetuity of all present and future rights to this
15+
* software under copyright law.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20+
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21+
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22+
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23+
* OTHER DEALINGS IN THE SOFTWARE.
24+
*
25+
* For more information, please refer to <http://unlicense.org/>
26+
*/
27+
28+
package net.adamcin.httpsig.api;
29+
30+
import org.junit.Test;
31+
32+
import java.util.*;
33+
34+
import static org.junit.Assert.assertEquals;
35+
36+
public class ConstantsTest {
37+
38+
/**
39+
* Added for defect-2; Provided test case {@code headers="date content-type"}
40+
*/
41+
@Test
42+
public void testConstructTokensString() {
43+
44+
assertEquals("headers should be empty if provided with a null list", "",
45+
Constants.constructTokensString(null));
46+
47+
assertEquals("headers should be empty if provided with an empty list", "",
48+
Constants.constructTokensString(Collections.<String>emptyList()));
49+
50+
assertEquals("should be a single token with no leading or trailing whitespace", "date",
51+
Constants.constructTokensString(Arrays.asList("date")));
52+
53+
assertEquals("headers should be separated by one space with no trailing spaces", "date content-type",
54+
Constants.constructTokensString(Arrays.asList("date", "content-type")));
55+
}
56+
57+
/**
58+
* Added for defect-2; should support new and old formats
59+
* Provided test case {@code headers="date content-type"} which should remain equivalent to
60+
* {@code headers="date content-type "}
61+
*/
62+
@Test
63+
public void testParseTokens() {
64+
List<String> tokens = Arrays.asList("date", "content-type");
65+
List<String> parsedExpected = Constants.parseTokens("date content-type");
66+
assertEquals("expected format should parse correctly", tokens, parsedExpected);
67+
68+
List<String> parsedLegacy = Constants.parseTokens("date content-type ");
69+
assertEquals("legacy format should parse correctly", tokens, parsedLegacy);
70+
}
71+
72+
/**
73+
* Added for defect-2; Provided test case:
74+
* {@code Signature keyId="unit", algorithm="hmac-sha1", headers="Content-Type Date", signature="8sY4dne3lta76PDMM+AUVaKkV7o="}
75+
* which should be
76+
* {@code Signature keyId="unit",algorithm="hmac-sha1",headers="Content-Type Date",signature="yIy5ujWnGZ0pKVR7vY6Qv08WfLE="}
77+
*/
78+
@Test
79+
public void testConstructRFC2617() {
80+
Map<String, String> params = new LinkedHashMap<String, String>();
81+
params.put("keyId", "unit");
82+
params.put("algorithm", "hmac-sha1");
83+
params.put("headers", "Content-Type Date");
84+
params.put("signature", "yIy5ujWnGZ0pKVR7vY6Qv08WfLE=");
85+
86+
String formatted = Constants.constructRFC2617(params);
87+
88+
assertEquals("RFC 2617 string should be properly formatted",
89+
"Signature keyId=\"unit\",algorithm=\"hmac-sha1\",headers=\"Content-Type Date\",signature=\"yIy5ujWnGZ0pKVR7vY6Qv08WfLE=\"",
90+
formatted);
91+
}
92+
93+
/**
94+
* Added for defect-2; maintain support for both new and old formats.
95+
* {@code Signature keyId="unit", algorithm="hmac-sha1", headers="Content-Type Date", signature="8sY4dne3lta76PDMM+AUVaKkV7o="}
96+
* {@code Signature keyId="unit",algorithm="hmac-sha1",headers="Content-Type Date",signature="yIy5ujWnGZ0pKVR7vY6Qv08WfLE="}
97+
*/
98+
@Test
99+
public void testParseRFC2617() {
100+
final String expectedFormat = "Signature keyId=\"unit\",algorithm=\"hmac-sha1\",headers=\"Content-Type Date\",signature=\"yIy5ujWnGZ0pKVR7vY6Qv08WfLE=\"";
101+
final String legacyFormat = "Signature keyId=\"unit\", algorithm=\"hmac-sha1\", headers=\"Content-Type Date\", signature=\"yIy5ujWnGZ0pKVR7vY6Qv08WfLE=\"";
102+
103+
Map<String, String> params = new LinkedHashMap<String, String>();
104+
params.put("keyId", "unit");
105+
params.put("algorithm", "hmac-sha1");
106+
params.put("headers", "Content-Type Date");
107+
params.put("signature", "yIy5ujWnGZ0pKVR7vY6Qv08WfLE=");
108+
109+
Map<String, String> parsedExpected = Constants.parseRFC2617(expectedFormat);
110+
for (Map.Entry<String, String> entry : params.entrySet()) {
111+
assertEquals("parsed param values should be the same", entry.getValue(), parsedExpected.get(entry.getKey()));
112+
}
113+
114+
Map<String, String> parsedLegacy = Constants.parseRFC2617(legacyFormat);
115+
for (Map.Entry<String, String> entry : params.entrySet()) {
116+
assertEquals("parsed param values should be the same", entry.getValue(), parsedLegacy.get(entry.getKey()));
117+
}
118+
}
119+
}

http-helpers/src/main/java/net/adamcin/httpsig/http/ning/AsyncUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public static <T> Future<T> login(final AsyncHttpClient client,
164164
return response;
165165
}
166166

167-
public static String getRequestPath(Request request) {
167+
protected static String getRequestPath(Request request) {
168168
try {
169169
URL url = new URL(request.getUrl());
170170
return url.getPath() + (url.getQuery() != null ? "?" + url.getQuery() : "");

0 commit comments

Comments
 (0)