1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.metricshub.wbem.sblim.cimclient.internal.http;
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 import java.util.Vector;
48
49
50
51
52
53 public class Challenge {
54 private String iScheme;
55
56 private HttpHeader iParams;
57
58 private Challenge() {
59
60 }
61
62
63
64
65
66
67 public HttpHeader getParams() {
68 return this.iParams;
69 }
70
71
72
73
74
75
76 public String getScheme() {
77 return this.iScheme;
78 }
79
80
81
82
83
84
85 public String getRealm() {
86 return this.iParams.getField("realm");
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 public static Challenge[] parseChallenge(String pLine) throws HttpParseException {
106 if (pLine == null || pLine.length() == 0) throw new IllegalArgumentException("Invalid challenge, empty");
107 pLine = pLine.trim();
108 if (pLine.length() == 0) throw new IllegalArgumentException("Invalid challenge, empty");
109
110 Vector<Challenge> challenges = new Vector<Challenge>();
111
112 try {
113 int start = 0, end = 0;
114
115
116 Vector<String> tokensBetweenCommas = new Vector<String>();
117 while ((end = indexOfOutsideQuotedString(pLine, ',', start)) > 0) {
118 tokensBetweenCommas.add(removeWhitespace(pLine.substring(start, end)));
119 start = end + 1;
120 }
121 if (start < pLine.length()) tokensBetweenCommas.add(removeWhitespace(pLine.substring(start)));
122
123
124 Vector<String> tokens = new Vector<String>();
125 for (int i = 0; i < tokensBetweenCommas.size(); i++) {
126 String token = tokensBetweenCommas.elementAt(i);
127
128 if (token.length() == 0) continue;
129
130 start = 0;
131 end = indexOfOutsideQuotedString(token, ' ', start);
132
133 if (end == -1) {
134 tokens.add(token);
135 } else {
136 tokens.add(token.substring(0, end));
137 start = end + 1;
138 end = indexOfOutsideQuotedString(token, ' ', start);
139
140 if (end == -1) {
141
142
143
144
145
146 if (indexOfOutsideQuotedString(token, '=', start) == -1) {
147
148
149
150 } else {
151 tokens.add(token.substring(start));
152 }
153 } else {
154 throw new HttpParseException("Invalid challenge, too many tokens in " + token);
155 }
156 }
157 }
158
159 Challenge challenge = new Challenge();
160 challenge.iScheme = null;
161 challenge.iParams = new HttpHeader();
162
163 for (int i = 0; i < tokens.size(); i++) {
164 String token = tokens.elementAt(i);
165
166 int equalSign = indexOfOutsideQuotedString(token, '=', 0);
167 if (equalSign == 0) {
168 throw new HttpParseException("Invalid challenge, no token before equal sign in " + token);
169 } else if (equalSign > 0) {
170
171 if (challenge.iScheme == null) throw new HttpParseException("Invalid challenge, param without scheme");
172 String name = token.substring(0, equalSign);
173 String value = token.substring(equalSign + 1);
174 if (value.length() == 0) {
175 throw new HttpParseException("Invalid challenge, no token after equal sign in " + token);
176 } else if (value.startsWith("\"") && value.endsWith("\"") && value.length() > 1) {
177 challenge.iParams.addField(name, value.substring(1, value.length() - 1));
178 } else {
179 challenge.iParams.addField(name, value);
180 }
181 } else {
182
183 if (challenge.iScheme != null) {
184
185 challenges.add(challenge);
186
187 challenge = new Challenge();
188 challenge.iParams = new HttpHeader();
189 }
190 challenge.iScheme = new String(token);
191 }
192 }
193
194 if (challenge.iScheme != null) {
195 challenges.add(challenge);
196 }
197 } catch (HttpParseException e) {
198 throw e;
199 } catch (Exception e) {
200 throw new HttpParseException("Invalid challenge, " + e.getMessage());
201 }
202
203 return challenges.toArray(new Challenge[challenges.size()]);
204 }
205
206
207
208
209
210 private static String removeWhitespace(String str) throws HttpParseException {
211 char inBuf[] = str.trim().toCharArray();
212 StringBuilder outStr = new StringBuilder();
213 boolean inQuotes = false;
214
215 for (int inIdx = 0; inIdx < inBuf.length; inIdx++) {
216 if (inQuotes || !Character.isSpaceChar(inBuf[inIdx])) {
217 if (inBuf[inIdx] == '=' && outStr.length() == 0) throw new HttpParseException(
218 "Invalid challenge, no token before equal sign in " + str
219 );
220
221 outStr.append(inBuf[inIdx]);
222 } else {
223
224 int i = skipSpaces(inBuf, inIdx + 1);
225 if (i >= inBuf.length) throw new HttpParseException("Invalid challenge, no token after space in " + str);
226
227 if (inBuf[i] == '=') {
228
229 i = skipSpaces(inBuf, i + 1);
230 if (i >= inBuf.length) throw new HttpParseException("Invalid challenge, no token after equal sign in " + str);
231 outStr.append('=');
232 } else {
233
234
235 outStr.append(' ');
236 }
237 outStr.append(inBuf[i]);
238 inIdx = i;
239 }
240 if (inBuf[inIdx] == '\"') inQuotes = !inQuotes;
241 }
242 if (inQuotes) throw new HttpParseException("Invalid challenge, quoted string not terminated in " + str);
243 return outStr.toString();
244 }
245
246 private static int skipSpaces(char[] buf, int pos) {
247 while (pos < buf.length && Character.isSpaceChar(buf[pos])) pos++;
248 return pos;
249 }
250
251 private static int indexOfOutsideQuotedString(String str, int ch, int pos) throws HttpParseException {
252 int len = str.length();
253 boolean inQuotes = false;
254
255 while (pos < len) {
256 if (str.charAt(pos) == '\"') {
257 inQuotes = !inQuotes;
258 } else if (str.charAt(pos) == ch) {
259 if (!inQuotes) return pos;
260 }
261 pos++;
262 }
263 if (inQuotes) throw new HttpParseException("Invalid callenge, quoted string not terminated in " + str);
264 return -1;
265 }
266 }