Mercurial Hosting > luan
comparison src/org/eclipse/jetty/http/HttpURI.java @ 1018:4dc1e1a18661
remove HttpSchemes
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 24 Oct 2016 05:37:24 -0600 |
parents | 3428c60d7cfc |
children |
comparison
equal
deleted
inserted
replaced
1017:d2c3ff33387c | 1018:4dc1e1a18661 |
---|---|
45 * </ul> | 45 * </ul> |
46 * | 46 * |
47 */ | 47 */ |
48 public class HttpURI | 48 public class HttpURI |
49 { | 49 { |
50 private static final byte[] __empty={}; | 50 private static final byte[] __empty={}; |
51 private final static int | 51 private final static int |
52 START=0, | 52 START=0, |
53 AUTH_OR_PATH=1, | 53 AUTH_OR_PATH=1, |
54 SCHEME_OR_PATH=2, | 54 SCHEME_OR_PATH=2, |
55 AUTH=4, | 55 AUTH=4, |
56 IPV6=5, | 56 IPV6=5, |
57 PORT=6, | 57 PORT=6, |
58 PATH=7, | 58 PATH=7, |
59 PARAM=8, | 59 PARAM=8, |
60 QUERY=9, | 60 QUERY=9, |
61 ASTERISK=10; | 61 ASTERISK=10; |
62 | 62 |
63 boolean _partial=false; | 63 boolean _partial=false; |
64 byte[] _raw=__empty; | 64 byte[] _raw=__empty; |
65 String _rawString; | 65 String _rawString; |
66 int _scheme; | 66 int _scheme; |
67 int _authority; | 67 int _authority; |
68 int _host; | 68 int _host; |
69 int _port; | 69 int _port; |
70 int _portValue; | 70 int _portValue; |
71 int _path; | 71 int _path; |
72 int _param; | 72 int _param; |
73 int _query; | 73 int _query; |
74 int _fragment; | 74 int _fragment; |
75 int _end; | 75 int _end; |
76 boolean _encoded=false; | 76 boolean _encoded=false; |
77 | 77 |
78 final Utf8StringBuilder _utf8b = new Utf8StringBuilder(64); | 78 final Utf8StringBuilder _utf8b = new Utf8StringBuilder(64); |
79 | 79 |
80 public HttpURI() | 80 public HttpURI() |
81 { | 81 { |
82 | 82 |
83 } | 83 } |
84 | 84 |
85 /* ------------------------------------------------------------ */ | 85 /* ------------------------------------------------------------ */ |
86 /** | 86 /** |
87 * @param parsePartialAuth If True, parse auth without prior scheme, else treat all URIs starting with / as paths | 87 * @param parsePartialAuth If True, parse auth without prior scheme, else treat all URIs starting with / as paths |
88 */ | 88 */ |
89 public HttpURI(boolean parsePartialAuth) | 89 public HttpURI(boolean parsePartialAuth) |
90 { | 90 { |
91 _partial=parsePartialAuth; | 91 _partial=parsePartialAuth; |
92 } | 92 } |
93 | 93 |
94 public HttpURI(String raw) | 94 public HttpURI(String raw) |
95 { | 95 { |
96 _rawString=raw; | 96 _rawString=raw; |
97 byte[] b; | 97 byte[] b; |
98 try | 98 try |
99 { | 99 { |
100 b = raw.getBytes(StringUtil.__UTF8); | 100 b = raw.getBytes(StringUtil.__UTF8); |
101 } | 101 } |
102 catch (UnsupportedEncodingException e) | 102 catch (UnsupportedEncodingException e) |
103 { | 103 { |
104 throw new RuntimeException(e.getMessage()); | 104 throw new RuntimeException(e.getMessage()); |
105 } | 105 } |
106 parse(b,0,b.length); | 106 parse(b,0,b.length); |
107 } | 107 } |
108 | 108 |
109 public HttpURI(byte[] raw,int offset, int length) | 109 public HttpURI(byte[] raw,int offset, int length) |
110 { | 110 { |
111 parse2(raw,offset,length); | 111 parse2(raw,offset,length); |
112 } | 112 } |
113 | 113 |
114 public HttpURI(URI uri) | 114 public HttpURI(URI uri) |
115 { | 115 { |
116 parse(uri.toASCIIString()); | 116 parse(uri.toASCIIString()); |
117 } | 117 } |
118 | 118 |
119 public void parse(String raw) | 119 public void parse(String raw) |
120 { | 120 { |
121 byte[] b = raw.getBytes(); | 121 byte[] b = raw.getBytes(); |
122 parse2(b,0,b.length); | 122 parse2(b,0,b.length); |
123 _rawString=raw; | 123 _rawString=raw; |
124 } | 124 } |
125 | 125 |
126 public void parse(byte[] raw,int offset, int length) | 126 public void parse(byte[] raw,int offset, int length) |
127 { | 127 { |
128 _rawString=null; | 128 _rawString=null; |
129 parse2(raw,offset,length); | 129 parse2(raw,offset,length); |
130 } | 130 } |
131 | 131 |
132 | 132 |
133 public void parseConnect(byte[] raw,int offset, int length) | 133 public void parseConnect(byte[] raw,int offset, int length) |
134 { | 134 { |
135 _rawString=null; | 135 _rawString=null; |
136 _encoded=false; | 136 _encoded=false; |
137 _raw=raw; | 137 _raw=raw; |
138 int i=offset; | 138 int i=offset; |
139 int e=offset+length; | 139 int e=offset+length; |
140 int state=AUTH; | 140 int state=AUTH; |
141 _end=offset+length; | 141 _end=offset+length; |
142 _scheme=offset; | 142 _scheme=offset; |
143 _authority=offset; | 143 _authority=offset; |
144 _host=offset; | 144 _host=offset; |
145 _port=_end; | 145 _port=_end; |
146 _portValue=-1; | 146 _portValue=-1; |
147 _path=_end; | 147 _path=_end; |
148 _param=_end; | 148 _param=_end; |
149 _query=_end; | 149 _query=_end; |
150 _fragment=_end; | 150 _fragment=_end; |
151 | 151 |
152 loop: while (i<e) | 152 loop: while (i<e) |
153 { | 153 { |
154 char c=(char)(0xff&_raw[i]); | 154 char c=(char)(0xff&_raw[i]); |
155 int s=i++; | 155 int s=i++; |
156 | 156 |
157 switch (state) | 157 switch (state) |
158 { | 158 { |
159 case AUTH: | 159 case AUTH: |
160 { | 160 { |
161 switch (c) | 161 switch (c) |
162 { | 162 { |
163 case ':': | 163 case ':': |
164 { | 164 { |
165 _port = s; | 165 _port = s; |
166 break loop; | 166 break loop; |
167 } | 167 } |
168 case '[': | 168 case '[': |
169 { | 169 { |
170 state = IPV6; | 170 state = IPV6; |
171 break; | 171 break; |
172 } | 172 } |
173 } | 173 } |
174 continue; | 174 continue; |
175 } | 175 } |
176 | 176 |
177 case IPV6: | 177 case IPV6: |
178 { | 178 { |
179 switch (c) | 179 switch (c) |
180 { | 180 { |
181 case '/': | 181 case '/': |
182 { | 182 { |
183 throw new IllegalArgumentException("No closing ']' for " + StringUtil.toString(_raw,offset,length,URIUtil.__CHARSET)); | 183 throw new IllegalArgumentException("No closing ']' for " + StringUtil.toString(_raw,offset,length,URIUtil.__CHARSET)); |
184 } | 184 } |
185 case ']': | 185 case ']': |
186 { | 186 { |
187 state = AUTH; | 187 state = AUTH; |
188 break; | 188 break; |
189 } | 189 } |
190 } | 190 } |
191 | 191 |
192 continue; | 192 continue; |
193 } | 193 } |
194 } | 194 } |
195 } | 195 } |
196 | 196 |
197 if (_port<_path) | 197 if (_port<_path) |
198 _portValue=TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10); | 198 _portValue=TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10); |
199 else | 199 else |
200 throw new IllegalArgumentException("No port"); | 200 throw new IllegalArgumentException("No port"); |
201 _path=offset; | 201 _path=offset; |
202 } | 202 } |
203 | 203 |
204 | 204 |
205 private void parse2(byte[] raw,int offset, int length) | 205 private void parse2(byte[] raw,int offset, int length) |
206 { | 206 { |
207 _encoded=false; | 207 _encoded=false; |
208 _raw=raw; | 208 _raw=raw; |
209 int i=offset; | 209 int i=offset; |
210 int e=offset+length; | 210 int e=offset+length; |
211 int state=START; | 211 int state=START; |
212 int m=offset; | 212 int m=offset; |
213 _end=offset+length; | 213 _end=offset+length; |
214 _scheme=offset; | 214 _scheme=offset; |
215 _authority=offset; | 215 _authority=offset; |
216 _host=offset; | 216 _host=offset; |
217 _port=offset; | 217 _port=offset; |
218 _portValue=-1; | 218 _portValue=-1; |
219 _path=offset; | 219 _path=offset; |
220 _param=_end; | 220 _param=_end; |
221 _query=_end; | 221 _query=_end; |
222 _fragment=_end; | 222 _fragment=_end; |
223 while (i<e) | 223 while (i<e) |
224 { | 224 { |
225 char c=(char)(0xff&_raw[i]); | 225 char c=(char)(0xff&_raw[i]); |
226 int s=i++; | 226 int s=i++; |
227 | 227 |
228 state: switch (state) | 228 state: switch (state) |
229 { | 229 { |
230 case START: | 230 case START: |
231 { | 231 { |
232 m=s; | 232 m=s; |
233 switch(c) | 233 switch(c) |
234 { | 234 { |
235 case '/': | 235 case '/': |
236 state=AUTH_OR_PATH; | 236 state=AUTH_OR_PATH; |
237 break; | 237 break; |
238 case ';': | 238 case ';': |
239 _param=s; | 239 _param=s; |
240 state=PARAM; | 240 state=PARAM; |
241 break; | 241 break; |
242 case '?': | 242 case '?': |
243 _param=s; | 243 _param=s; |
244 _query=s; | 244 _query=s; |
245 state=QUERY; | 245 state=QUERY; |
246 break; | 246 break; |
247 case '#': | 247 case '#': |
248 _param=s; | 248 _param=s; |
249 _query=s; | 249 _query=s; |
250 _fragment=s; | 250 _fragment=s; |
251 break; | 251 break; |
252 case '*': | 252 case '*': |
253 _path=s; | 253 _path=s; |
254 state=ASTERISK; | 254 state=ASTERISK; |
255 break; | 255 break; |
256 | 256 |
257 default: | 257 default: |
258 state=SCHEME_OR_PATH; | 258 state=SCHEME_OR_PATH; |
259 } | 259 } |
260 | 260 |
261 continue; | 261 continue; |
262 } | 262 } |
263 | 263 |
264 case AUTH_OR_PATH: | 264 case AUTH_OR_PATH: |
265 { | 265 { |
266 if ((_partial||_scheme!=_authority) && c=='/') | 266 if ((_partial||_scheme!=_authority) && c=='/') |
267 { | 267 { |
268 _host=i; | 268 _host=i; |
269 _port=_end; | 269 _port=_end; |
270 _path=_end; | 270 _path=_end; |
271 state=AUTH; | 271 state=AUTH; |
272 } | 272 } |
273 else if (c==';' || c=='?' || c=='#') | 273 else if (c==';' || c=='?' || c=='#') |
274 { | 274 { |
275 i--; | 275 i--; |
276 state=PATH; | 276 state=PATH; |
277 } | 277 } |
278 else | 278 else |
279 { | 279 { |
280 _host=m; | 280 _host=m; |
281 _port=m; | 281 _port=m; |
282 state=PATH; | 282 state=PATH; |
283 } | 283 } |
284 continue; | 284 continue; |
285 } | 285 } |
286 | 286 |
287 case SCHEME_OR_PATH: | 287 case SCHEME_OR_PATH: |
288 { | 288 { |
289 // short cut for http and https | 289 // short cut for http and https |
290 if (length>6 && c=='t') | 290 if (length>6 && c=='t') |
291 { | 291 { |
292 if (_raw[offset+3]==':') | 292 if (_raw[offset+3]==':') |
293 { | 293 { |
294 s=offset+3; | 294 s=offset+3; |
295 i=offset+4; | 295 i=offset+4; |
296 c=':'; | 296 c=':'; |
297 } | 297 } |
298 else if (_raw[offset+4]==':') | 298 else if (_raw[offset+4]==':') |
299 { | 299 { |
300 s=offset+4; | 300 s=offset+4; |
301 i=offset+5; | 301 i=offset+5; |
302 c=':'; | 302 c=':'; |
303 } | 303 } |
304 else if (_raw[offset+5]==':') | 304 else if (_raw[offset+5]==':') |
305 { | 305 { |
306 s=offset+5; | 306 s=offset+5; |
307 i=offset+6; | 307 i=offset+6; |
308 c=':'; | 308 c=':'; |
309 } | 309 } |
310 } | 310 } |
311 | 311 |
312 switch (c) | 312 switch (c) |
313 { | 313 { |
314 case ':': | 314 case ':': |
315 { | 315 { |
316 m = i++; | 316 m = i++; |
317 _authority = m; | 317 _authority = m; |
318 _path = m; | 318 _path = m; |
319 c = (char)(0xff & _raw[i]); | 319 c = (char)(0xff & _raw[i]); |
320 if (c == '/') | 320 if (c == '/') |
321 state = AUTH_OR_PATH; | 321 state = AUTH_OR_PATH; |
322 else | 322 else |
323 { | 323 { |
324 _host = m; | 324 _host = m; |
325 _port = m; | 325 _port = m; |
326 state = PATH; | 326 state = PATH; |
327 } | 327 } |
328 break; | 328 break; |
329 } | 329 } |
330 | 330 |
331 case '/': | 331 case '/': |
332 { | 332 { |
333 state = PATH; | 333 state = PATH; |
334 break; | 334 break; |
335 } | 335 } |
336 | 336 |
337 case ';': | 337 case ';': |
338 { | 338 { |
339 _param = s; | 339 _param = s; |
340 state = PARAM; | 340 state = PARAM; |
341 break; | 341 break; |
342 } | 342 } |
343 | 343 |
344 case '?': | 344 case '?': |
345 { | 345 { |
346 _param = s; | 346 _param = s; |
347 _query = s; | 347 _query = s; |
348 state = QUERY; | 348 state = QUERY; |
349 break; | 349 break; |
350 } | 350 } |
351 | 351 |
352 case '#': | 352 case '#': |
353 { | 353 { |
354 _param = s; | 354 _param = s; |
355 _query = s; | 355 _query = s; |
356 _fragment = s; | 356 _fragment = s; |
357 break; | 357 break; |
358 } | 358 } |
359 } | 359 } |
360 continue; | 360 continue; |
361 } | 361 } |
362 | 362 |
363 case AUTH: | 363 case AUTH: |
364 { | 364 { |
365 switch (c) | 365 switch (c) |
366 { | 366 { |
367 | 367 |
368 case '/': | 368 case '/': |
369 { | 369 { |
370 m = s; | 370 m = s; |
371 _path = m; | 371 _path = m; |
372 _port = _path; | 372 _port = _path; |
373 state = PATH; | 373 state = PATH; |
374 break; | 374 break; |
375 } | 375 } |
376 case '@': | 376 case '@': |
377 { | 377 { |
378 _host = i; | 378 _host = i; |
379 break; | 379 break; |
380 } | 380 } |
381 case ':': | 381 case ':': |
382 { | 382 { |
383 _port = s; | 383 _port = s; |
384 state = PORT; | 384 state = PORT; |
385 break; | 385 break; |
386 } | 386 } |
387 case '[': | 387 case '[': |
388 { | 388 { |
389 state = IPV6; | 389 state = IPV6; |
390 break; | 390 break; |
391 } | 391 } |
392 } | 392 } |
393 continue; | 393 continue; |
394 } | 394 } |
395 | 395 |
396 case IPV6: | 396 case IPV6: |
397 { | 397 { |
398 switch (c) | 398 switch (c) |
399 { | 399 { |
400 case '/': | 400 case '/': |
401 { | 401 { |
402 throw new IllegalArgumentException("No closing ']' for " + StringUtil.toString(_raw,offset,length,URIUtil.__CHARSET)); | 402 throw new IllegalArgumentException("No closing ']' for " + StringUtil.toString(_raw,offset,length,URIUtil.__CHARSET)); |
403 } | 403 } |
404 case ']': | 404 case ']': |
405 { | 405 { |
406 state = AUTH; | 406 state = AUTH; |
407 break; | 407 break; |
408 } | 408 } |
409 } | 409 } |
410 | 410 |
411 continue; | 411 continue; |
412 } | 412 } |
413 | 413 |
414 case PORT: | 414 case PORT: |
415 { | 415 { |
416 if (c=='/') | 416 if (c=='/') |
417 { | 417 { |
418 m=s; | 418 m=s; |
419 _path=m; | 419 _path=m; |
420 if (_port<=_authority) | 420 if (_port<=_authority) |
421 _port=_path; | 421 _port=_path; |
422 state=PATH; | 422 state=PATH; |
423 } | 423 } |
424 continue; | 424 continue; |
425 } | 425 } |
426 | 426 |
427 case PATH: | 427 case PATH: |
428 { | 428 { |
429 switch (c) | 429 switch (c) |
430 { | 430 { |
431 case ';': | 431 case ';': |
432 { | 432 { |
433 _param = s; | 433 _param = s; |
434 state = PARAM; | 434 state = PARAM; |
435 break; | 435 break; |
436 } | 436 } |
437 case '?': | 437 case '?': |
438 { | 438 { |
439 _param = s; | 439 _param = s; |
440 _query = s; | 440 _query = s; |
441 state = QUERY; | 441 state = QUERY; |
442 break; | 442 break; |
443 } | 443 } |
444 case '#': | 444 case '#': |
445 { | 445 { |
446 _param = s; | 446 _param = s; |
447 _query = s; | 447 _query = s; |
448 _fragment = s; | 448 _fragment = s; |
449 break state; | 449 break state; |
450 } | 450 } |
451 case '%': | 451 case '%': |
452 { | 452 { |
453 _encoded=true; | 453 _encoded=true; |
454 } | 454 } |
455 } | 455 } |
456 continue; | 456 continue; |
457 } | 457 } |
458 | 458 |
459 case PARAM: | 459 case PARAM: |
460 { | 460 { |
461 switch (c) | 461 switch (c) |
462 { | 462 { |
463 case '?': | 463 case '?': |
464 { | 464 { |
465 _query = s; | 465 _query = s; |
466 state = QUERY; | 466 state = QUERY; |
467 break; | 467 break; |
468 } | 468 } |
469 case '#': | 469 case '#': |
470 { | 470 { |
471 _query = s; | 471 _query = s; |
472 _fragment = s; | 472 _fragment = s; |
473 break state; | 473 break state; |
474 } | 474 } |
475 } | 475 } |
476 continue; | 476 continue; |
477 } | 477 } |
478 | 478 |
479 case QUERY: | 479 case QUERY: |
480 { | 480 { |
481 if (c=='#') | 481 if (c=='#') |
482 { | 482 { |
483 _fragment=s; | 483 _fragment=s; |
484 break state; | 484 break state; |
485 } | 485 } |
486 continue; | 486 continue; |
487 } | 487 } |
488 | 488 |
489 case ASTERISK: | 489 case ASTERISK: |
490 { | 490 { |
491 throw new IllegalArgumentException("only '*'"); | 491 throw new IllegalArgumentException("only '*'"); |
492 } | 492 } |
493 } | 493 } |
494 } | 494 } |
495 | 495 |
496 if (_port<_path) | 496 if (_port<_path) |
497 _portValue=TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10); | 497 _portValue=TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10); |
498 } | 498 } |
499 | 499 |
500 private String toUtf8String(int offset,int length) | 500 private String toUtf8String(int offset,int length) |
501 { | 501 { |
502 _utf8b.reset(); | 502 _utf8b.reset(); |
503 _utf8b.append(_raw,offset,length); | 503 _utf8b.append(_raw,offset,length); |
504 return _utf8b.toString(); | 504 return _utf8b.toString(); |
505 } | 505 } |
506 | 506 |
507 public String getScheme() | 507 public String getScheme() |
508 { | 508 { |
509 if (_scheme==_authority) | 509 if (_scheme==_authority) |
510 return null; | 510 return null; |
511 int l=_authority-_scheme; | 511 int l=_authority-_scheme; |
512 if (l==5 && | 512 if (l==5 && |
513 _raw[_scheme]=='h' && | 513 _raw[_scheme]=='h' && |
514 _raw[_scheme+1]=='t' && | 514 _raw[_scheme+1]=='t' && |
515 _raw[_scheme+2]=='t' && | 515 _raw[_scheme+2]=='t' && |
516 _raw[_scheme+3]=='p' ) | 516 _raw[_scheme+3]=='p' ) |
517 return HttpSchemes.HTTP; | 517 return "http"; |
518 if (l==6 && | 518 if (l==6 && |
519 _raw[_scheme]=='h' && | 519 _raw[_scheme]=='h' && |
520 _raw[_scheme+1]=='t' && | 520 _raw[_scheme+1]=='t' && |
521 _raw[_scheme+2]=='t' && | 521 _raw[_scheme+2]=='t' && |
522 _raw[_scheme+3]=='p' && | 522 _raw[_scheme+3]=='p' && |
523 _raw[_scheme+4]=='s' ) | 523 _raw[_scheme+4]=='s' ) |
524 return HttpSchemes.HTTPS; | 524 return "https"; |
525 | 525 |
526 return toUtf8String(_scheme,_authority-_scheme-1); | 526 return toUtf8String(_scheme,_authority-_scheme-1); |
527 } | 527 } |
528 | 528 |
529 public String getAuthority() | 529 public String getAuthority() |
530 { | 530 { |
531 if (_authority==_path) | 531 if (_authority==_path) |
532 return null; | 532 return null; |
533 return toUtf8String(_authority,_path-_authority); | 533 return toUtf8String(_authority,_path-_authority); |
534 } | 534 } |
535 | 535 |
536 public String getHost() | 536 public String getHost() |
537 { | 537 { |
538 if (_host==_port) | 538 if (_host==_port) |
539 return null; | 539 return null; |
540 return toUtf8String(_host,_port-_host); | 540 return toUtf8String(_host,_port-_host); |
541 } | 541 } |
542 | 542 |
543 public int getPort() | 543 public int getPort() |
544 { | 544 { |
545 return _portValue; | 545 return _portValue; |
546 } | 546 } |
547 | 547 |
548 public String getPath() | 548 public String getPath() |
549 { | 549 { |
550 if (_path==_param) | 550 if (_path==_param) |
551 return null; | 551 return null; |
552 return toUtf8String(_path,_param-_path); | 552 return toUtf8String(_path,_param-_path); |
553 } | 553 } |
554 | 554 |
555 public String getDecodedPath() | 555 public String getDecodedPath() |
556 { | 556 { |
557 if (_path==_param) | 557 if (_path==_param) |
558 return null; | 558 return null; |
559 | 559 |
560 int length = _param-_path; | 560 int length = _param-_path; |
561 boolean decoding=false; | 561 boolean decoding=false; |
562 | 562 |
563 for (int i=_path;i<_param;i++) | 563 for (int i=_path;i<_param;i++) |
564 { | 564 { |
565 byte b = _raw[i]; | 565 byte b = _raw[i]; |
566 | 566 |
567 if (b=='%') | 567 if (b=='%') |
568 { | 568 { |
569 if (!decoding) | 569 if (!decoding) |
570 { | 570 { |
571 _utf8b.reset(); | 571 _utf8b.reset(); |
572 _utf8b.append(_raw,_path,i-_path); | 572 _utf8b.append(_raw,_path,i-_path); |
573 decoding=true; | 573 decoding=true; |
574 } | 574 } |
575 | 575 |
576 if ((i+2)>=_param) | 576 if ((i+2)>=_param) |
577 throw new IllegalArgumentException("Bad % encoding: "+this); | 577 throw new IllegalArgumentException("Bad % encoding: "+this); |
578 if (_raw[i+1]=='u') | 578 if (_raw[i+1]=='u') |
579 { | 579 { |
580 if ((i+5)>=_param) | 580 if ((i+5)>=_param) |
581 throw new IllegalArgumentException("Bad %u encoding: "+this); | 581 throw new IllegalArgumentException("Bad %u encoding: "+this); |
582 try | 582 try |
583 { | 583 { |
584 String unicode = new String(Character.toChars(TypeUtil.parseInt(_raw,i+2,4,16))); | 584 String unicode = new String(Character.toChars(TypeUtil.parseInt(_raw,i+2,4,16))); |
585 _utf8b.getStringBuilder().append(unicode); | 585 _utf8b.getStringBuilder().append(unicode); |
586 i+=5; | 586 i+=5; |
587 } | 587 } |
588 catch(Exception e) | 588 catch(Exception e) |
589 { | 589 { |
590 throw new RuntimeException(e); | 590 throw new RuntimeException(e); |
591 } | 591 } |
592 } | 592 } |
593 else | 593 else |
594 { | 594 { |
595 b=(byte)(0xff&TypeUtil.parseInt(_raw,i+1,2,16)); | 595 b=(byte)(0xff&TypeUtil.parseInt(_raw,i+1,2,16)); |
596 _utf8b.append(b); | 596 _utf8b.append(b); |
597 i+=2; | 597 i+=2; |
598 } | 598 } |
599 continue; | 599 continue; |
600 } | 600 } |
601 else if (decoding) | 601 else if (decoding) |
602 { | 602 { |
603 _utf8b.append(b); | 603 _utf8b.append(b); |
604 } | 604 } |
605 } | 605 } |
606 | 606 |
607 if (!decoding) | 607 if (!decoding) |
608 return toUtf8String(_path,length); | 608 return toUtf8String(_path,length); |
609 return _utf8b.toString(); | 609 return _utf8b.toString(); |
610 } | 610 } |
611 | 611 |
612 public String getDecodedPath(String encoding) | 612 public String getDecodedPath(String encoding) |
613 { | 613 { |
614 if (_path==_param) | 614 if (_path==_param) |
615 return null; | 615 return null; |
616 | 616 |
617 int length = _param-_path; | 617 int length = _param-_path; |
618 byte[] bytes=null; | 618 byte[] bytes=null; |
619 int n=0; | 619 int n=0; |
620 | 620 |
621 for (int i=_path;i<_param;i++) | 621 for (int i=_path;i<_param;i++) |
622 { | 622 { |
623 byte b = _raw[i]; | 623 byte b = _raw[i]; |
624 | 624 |
625 if (b=='%') | 625 if (b=='%') |
626 { | 626 { |
627 if (bytes==null) | 627 if (bytes==null) |
628 { | 628 { |
629 bytes=new byte[length]; | 629 bytes=new byte[length]; |
630 System.arraycopy(_raw,_path,bytes,0,n); | 630 System.arraycopy(_raw,_path,bytes,0,n); |
631 } | 631 } |
632 | 632 |
633 if ((i+2)>=_param) | 633 if ((i+2)>=_param) |
634 throw new IllegalArgumentException("Bad % encoding: "+this); | 634 throw new IllegalArgumentException("Bad % encoding: "+this); |
635 if (_raw[i+1]=='u') | 635 if (_raw[i+1]=='u') |
636 { | 636 { |
637 if ((i+5)>=_param) | 637 if ((i+5)>=_param) |
638 throw new IllegalArgumentException("Bad %u encoding: "+this); | 638 throw new IllegalArgumentException("Bad %u encoding: "+this); |
639 | 639 |
640 try | 640 try |
641 { | 641 { |
642 String unicode = new String(Character.toChars(TypeUtil.parseInt(_raw,i+2,4,16))); | 642 String unicode = new String(Character.toChars(TypeUtil.parseInt(_raw,i+2,4,16))); |
643 byte[] encoded = unicode.getBytes(encoding); | 643 byte[] encoded = unicode.getBytes(encoding); |
644 System.arraycopy(encoded,0,bytes,n,encoded.length); | 644 System.arraycopy(encoded,0,bytes,n,encoded.length); |
645 n+=encoded.length; | 645 n+=encoded.length; |
646 i+=5; | 646 i+=5; |
647 } | 647 } |
648 catch(Exception e) | 648 catch(Exception e) |
649 { | 649 { |
650 throw new RuntimeException(e); | 650 throw new RuntimeException(e); |
651 } | 651 } |
652 } | 652 } |
653 else | 653 else |
654 { | 654 { |
655 b=(byte)(0xff&TypeUtil.parseInt(_raw,i+1,2,16)); | 655 b=(byte)(0xff&TypeUtil.parseInt(_raw,i+1,2,16)); |
656 bytes[n++]=b; | 656 bytes[n++]=b; |
657 i+=2; | 657 i+=2; |
658 } | 658 } |
659 continue; | 659 continue; |
660 } | 660 } |
661 else if (bytes==null) | 661 else if (bytes==null) |
662 { | 662 { |
663 n++; | 663 n++; |
664 continue; | 664 continue; |
665 } | 665 } |
666 | 666 |
667 bytes[n++]=b; | 667 bytes[n++]=b; |
668 } | 668 } |
669 | 669 |
670 | 670 |
671 if (bytes==null) | 671 if (bytes==null) |
672 return StringUtil.toString(_raw,_path,_param-_path,encoding); | 672 return StringUtil.toString(_raw,_path,_param-_path,encoding); |
673 | 673 |
674 return StringUtil.toString(bytes,0,n,encoding); | 674 return StringUtil.toString(bytes,0,n,encoding); |
675 } | 675 } |
676 | 676 |
677 | 677 |
678 | 678 |
679 | 679 |
680 | 680 |
681 | 681 |
682 | 682 |
683 public String getPathAndParam() | 683 public String getPathAndParam() |
684 { | 684 { |
685 if (_path==_query) | 685 if (_path==_query) |
686 return null; | 686 return null; |
687 return toUtf8String(_path,_query-_path); | 687 return toUtf8String(_path,_query-_path); |
688 } | 688 } |
689 | 689 |
690 public String getCompletePath() | 690 public String getCompletePath() |
691 { | 691 { |
692 if (_path==_end) | 692 if (_path==_end) |
693 return null; | 693 return null; |
694 return toUtf8String(_path,_end-_path); | 694 return toUtf8String(_path,_end-_path); |
695 } | 695 } |
696 | 696 |
697 public String getParam() | 697 public String getParam() |
698 { | 698 { |
699 if (_param==_query) | 699 if (_param==_query) |
700 return null; | 700 return null; |
701 return toUtf8String(_param+1,_query-_param-1); | 701 return toUtf8String(_param+1,_query-_param-1); |
702 } | 702 } |
703 | 703 |
704 public String getQuery() | 704 public String getQuery() |
705 { | 705 { |
706 if (_query==_fragment) | 706 if (_query==_fragment) |
707 return null; | 707 return null; |
708 return toUtf8String(_query+1,_fragment-_query-1); | 708 return toUtf8String(_query+1,_fragment-_query-1); |
709 } | 709 } |
710 | 710 |
711 public String getQuery(String encoding) | 711 public String getQuery(String encoding) |
712 { | 712 { |
713 if (_query==_fragment) | 713 if (_query==_fragment) |
714 return null; | 714 return null; |
715 return StringUtil.toString(_raw,_query+1,_fragment-_query-1,encoding); | 715 return StringUtil.toString(_raw,_query+1,_fragment-_query-1,encoding); |
716 } | 716 } |
717 | 717 |
718 public boolean hasQuery() | 718 public boolean hasQuery() |
719 { | 719 { |
720 return (_fragment>_query); | 720 return (_fragment>_query); |
721 } | 721 } |
722 | 722 |
723 public String getFragment() | 723 public String getFragment() |
724 { | 724 { |
725 if (_fragment==_end) | 725 if (_fragment==_end) |
726 return null; | 726 return null; |
727 return toUtf8String(_fragment+1,_end-_fragment-1); | 727 return toUtf8String(_fragment+1,_end-_fragment-1); |
728 } | 728 } |
729 | 729 |
730 public void decodeQueryTo(MultiMap parameters) | 730 public void decodeQueryTo(MultiMap parameters) |
731 { | 731 { |
732 if (_query==_fragment) | 732 if (_query==_fragment) |
733 return; | 733 return; |
734 _utf8b.reset(); | 734 _utf8b.reset(); |
735 UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters,_utf8b); | 735 UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters,_utf8b); |
736 } | 736 } |
737 | 737 |
738 public void decodeQueryTo(MultiMap parameters, String encoding) | 738 public void decodeQueryTo(MultiMap parameters, String encoding) |
739 throws UnsupportedEncodingException | 739 throws UnsupportedEncodingException |
740 { | 740 { |
741 if (_query==_fragment) | 741 if (_query==_fragment) |
742 return; | 742 return; |
743 | 743 |
744 if (encoding==null || StringUtil.isUTF8(encoding)) | 744 if (encoding==null || StringUtil.isUTF8(encoding)) |
745 UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters); | 745 UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters); |
746 else | 746 else |
747 UrlEncoded.decodeTo(StringUtil.toString(_raw,_query+1,_fragment-_query-1,encoding),parameters,encoding); | 747 UrlEncoded.decodeTo(StringUtil.toString(_raw,_query+1,_fragment-_query-1,encoding),parameters,encoding); |
748 } | 748 } |
749 | 749 |
750 public void clear() | 750 public void clear() |
751 { | 751 { |
752 _scheme=_authority=_host=_port=_path=_param=_query=_fragment=_end=0; | 752 _scheme=_authority=_host=_port=_path=_param=_query=_fragment=_end=0; |
753 _raw=__empty; | 753 _raw=__empty; |
754 _rawString=""; | 754 _rawString=""; |
755 _encoded=false; | 755 _encoded=false; |
756 } | 756 } |
757 | 757 |
758 @Override | 758 @Override |
759 public String toString() | 759 public String toString() |
760 { | 760 { |
761 if (_rawString==null) | 761 if (_rawString==null) |
762 _rawString=toUtf8String(_scheme,_end-_scheme); | 762 _rawString=toUtf8String(_scheme,_end-_scheme); |
763 return _rawString; | 763 return _rawString; |
764 } | 764 } |
765 | 765 |
766 public void writeTo(Utf8StringBuilder buf) | 766 public void writeTo(Utf8StringBuilder buf) |
767 { | 767 { |
768 buf.append(_raw,_scheme,_end-_scheme); | 768 buf.append(_raw,_scheme,_end-_scheme); |
769 } | 769 } |
770 | 770 |
771 } | 771 } |