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
26
27
28
29
30
31
32 package org.apache.commons.httpclient;
33
34 import org.apache.commons.httpclient.util.URIUtil;
35
36 /***
37 * The HTTP URL.
38 *
39 * @author <a href="mailto:jericho at apache.org">Sung-Gu</a>
40 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
41 */
42 public class HttpURL extends URI {
43
44
45
46 /*** Create an instance as an internal use. */
47 protected HttpURL() {
48 }
49
50
51 /***
52 * Construct a HTTP URL as an escaped form of a character array with the
53 * given charset to do escape encoding.
54 *
55 * @param escaped the HTTP URL character sequence
56 * @param charset the charset string to do escape encoding
57 * @throws URIException If {@link #checkValid()} fails
58 * @throws NullPointerException if <code>escaped</code> is <code>null</code>
59 * @see #getProtocolCharset
60 */
61 public HttpURL(char[] escaped, String charset)
62 throws URIException, NullPointerException {
63 protocolCharset = charset;
64 parseUriReference(new String(escaped), true);
65 checkValid();
66 }
67
68
69 /***
70 * Construct a HTTP URL as an escaped form of a character array.
71 *
72 * @param escaped the HTTP URL character sequence
73 * @throws URIException If {@link #checkValid()} fails
74 * @throws NullPointerException if <code>escaped</code> is <code>null</code>
75 * @see #getDefaultProtocolCharset
76 */
77 public HttpURL(char[] escaped) throws URIException, NullPointerException {
78 parseUriReference(new String(escaped), true);
79 checkValid();
80 }
81
82
83 /***
84 * Construct a HTTP URL from a given string with the given charset to do
85 * escape encoding.
86 *
87 * @param original the HTTP URL string
88 * @param charset the charset string to do escape encoding
89 * @throws URIException If {@link #checkValid()} fails
90 * @see #getProtocolCharset
91 */
92 public HttpURL(String original, String charset) throws URIException {
93 protocolCharset = charset;
94 parseUriReference(original, false);
95 checkValid();
96 }
97
98
99 /***
100 * Construct a HTTP URL from a given string.
101 *
102 * @param original the HTTP URL string
103 * @throws URIException If {@link #checkValid()} fails
104 * @see #getDefaultProtocolCharset
105 */
106 public HttpURL(String original) throws URIException {
107 parseUriReference(original, false);
108 checkValid();
109 }
110
111
112 /***
113 * Construct a HTTP URL from given components.
114 *
115 * @param host the host string
116 * @param port the port number
117 * @param path the path string
118 * @throws URIException If {@link #checkValid()} fails
119 * @see #getDefaultProtocolCharset
120 */
121 public HttpURL(String host, int port, String path) throws URIException {
122 this(null, host, port, path, null, null);
123 checkValid();
124 }
125
126
127 /***
128 * Construct a HTTP URL from given components.
129 *
130 * @param host the host string
131 * @param port the port number
132 * @param path the path string
133 * @param query the query string
134 * @throws URIException If {@link #checkValid()} fails
135 * @see #getDefaultProtocolCharset
136 */
137 public HttpURL(String host, int port, String path, String query)
138 throws URIException {
139
140 this(null, host, port, path, query, null);
141 checkValid();
142 }
143
144
145 /***
146 * Construct a HTTP URL from given components.
147 *
148 * @param user the user name
149 * @param password his or her password
150 * @param host the host string
151 * @throws URIException If {@link #checkValid()} fails
152 * @see #getDefaultProtocolCharset
153 */
154 public HttpURL(String user, String password, String host)
155 throws URIException {
156
157 this((user == null) ? null : user
158 + ((password == null) ? "" : ':' + password),
159 host, -1, null, null, null);
160 checkValid();
161 }
162
163
164 /***
165 * Construct a HTTP URL from given components.
166 *
167 * @param user the user name
168 * @param password his or her password
169 * @param host the host string
170 * @param port the port number
171 * @throws URIException If {@link #checkValid()} fails
172 * @see #getDefaultProtocolCharset
173 */
174 public HttpURL(String user, String password, String host, int port)
175 throws URIException {
176
177 this((user == null) ? null : user
178 + ((password == null) ? "" : ':' + password),
179 host, port, null, null, null);
180 checkValid();
181 }
182
183
184 /***
185 * Construct a HTTP URL from given components.
186 *
187 * @param user the user name
188 * @param password his or her password
189 * @param host the host string
190 * @param port the port number
191 * @param path the path string
192 * @throws URIException If {@link #checkValid()} fails
193 * @see #getDefaultProtocolCharset
194 */
195 public HttpURL(String user, String password, String host, int port,
196 String path) throws URIException {
197
198 this((user == null) ? null : user
199 + ((password == null) ? "" : ':' + password),
200 host, port, path, null, null);
201 checkValid();
202 }
203
204
205 /***
206 * Construct a HTTP URL from given components.
207 *
208 * @param user the user name
209 * @param password his or her password
210 * @param host the host string
211 * @param port the port number
212 * @param path the path string
213 * @param query The query string.
214 * @throws URIException If {@link #checkValid()} fails
215 * @see #getDefaultProtocolCharset
216 */
217 public HttpURL(String user, String password, String host, int port,
218 String path, String query) throws URIException {
219
220 this((user == null) ? null : user
221 + ((password == null) ? "" : ':' + password),
222 host, port, path, query, null);
223 checkValid();
224 }
225
226
227 /***
228 * Construct a HTTP URL from given components.
229 *
230 * @param host the host string
231 * @param path the path string
232 * @param query the query string
233 * @param fragment the fragment string
234 * @throws URIException If {@link #checkValid()} fails
235 * @see #getDefaultProtocolCharset
236 */
237 public HttpURL(String host, String path, String query, String fragment)
238 throws URIException {
239
240 this(null, host, -1, path, query, fragment);
241 checkValid();
242 }
243
244
245 /***
246 * Construct a HTTP URL from given components.
247 *
248 * @param userinfo the userinfo string
249 * @param host the host string
250 * @param path the path string
251 * @param query the query string
252 * @param fragment the fragment string
253 * @throws URIException If {@link #checkValid()} fails
254 * @see #getDefaultProtocolCharset
255 */
256 public HttpURL(String userinfo, String host, String path, String query,
257 String fragment) throws URIException {
258
259 this(userinfo, host, -1, path, query, fragment);
260 checkValid();
261 }
262
263
264 /***
265 * Construct a HTTP URL from given components.
266 *
267 * @param userinfo the userinfo string
268 * @param host the host string
269 * @param port the port number
270 * @param path the path string
271 * @throws URIException If {@link #checkValid()} fails
272 * @see #getDefaultProtocolCharset
273 */
274 public HttpURL(String userinfo, String host, int port, String path)
275 throws URIException {
276
277 this(userinfo, host, port, path, null, null);
278 checkValid();
279 }
280
281
282 /***
283 * Construct a HTTP URL from given components.
284 *
285 * @param userinfo the userinfo string
286 * @param host the host string
287 * @param port the port number
288 * @param path the path string
289 * @param query the query string
290 * @throws URIException If {@link #checkValid()} fails
291 * @see #getDefaultProtocolCharset
292 */
293 public HttpURL(String userinfo, String host, int port, String path,
294 String query) throws URIException {
295
296 this(userinfo, host, port, path, query, null);
297 checkValid();
298 }
299
300
301 /***
302 * Construct a HTTP URL from given components.
303 *
304 * @param userinfo the userinfo string
305 * @param host the host string
306 * @param port the port number
307 * @param path the path string
308 * @param query the query string
309 * @param fragment the fragment string
310 * @throws URIException If {@link #checkValid()} fails
311 * @see #getDefaultProtocolCharset
312 */
313 public HttpURL(String userinfo, String host, int port, String path,
314 String query, String fragment) throws URIException {
315
316
317 StringBuffer buff = new StringBuffer();
318 if (userinfo != null || host != null || port != -1) {
319 _scheme = DEFAULT_SCHEME;
320 buff.append(_default_scheme);
321 buff.append("://");
322 if (userinfo != null) {
323 buff.append(URIUtil.encode(userinfo, URI.allowed_userinfo));
324 buff.append('@');
325 }
326 if (host != null) {
327 buff.append(URIUtil.encode(host, URI.allowed_host));
328 if (port != -1 || port != DEFAULT_PORT) {
329 buff.append(':');
330 buff.append(port);
331 }
332 }
333 }
334 if (path != null) {
335 if (scheme != null && !path.startsWith("/")) {
336 throw new URIException(URIException.PARSING,
337 "abs_path requested");
338 }
339 buff.append(URIUtil.encode(path, URI.allowed_abs_path));
340 }
341 if (query != null) {
342 buff.append('?');
343 buff.append(URIUtil.encode(query, URI.allowed_query));
344 }
345 if (fragment != null) {
346 buff.append('#');
347 buff.append(URIUtil.encode(fragment, URI.allowed_fragment));
348 }
349 parseUriReference(buff.toString(), true);
350 checkValid();
351 }
352
353
354 /***
355 * Construct a HTTP URL with a given relative URL string.
356 *
357 * @param base the base HttpURL
358 * @param relative the relative HTTP URL string
359 * @throws URIException If {@link #checkValid()} fails
360 */
361 public HttpURL(HttpURL base, String relative) throws URIException {
362 this(base, new HttpURL(relative));
363 }
364
365
366 /***
367 * Construct a HTTP URL with a given relative URL.
368 *
369 * @param base the base HttpURL
370 * @param relative the relative HttpURL
371 * @throws URIException If {@link #checkValid()} fails
372 */
373 public HttpURL(HttpURL base, HttpURL relative) throws URIException {
374 super(base, relative);
375 checkValid();
376 }
377
378
379
380 /***
381 * Default scheme for HTTP URL.
382 */
383 public static final char[] DEFAULT_SCHEME = { 'h', 't', 't', 'p' };
384
385 /***
386 * Default scheme for HTTP URL.
387 * @deprecated Use {@link #DEFAULT_SCHEME} instead. This one doesn't
388 * conform to the project naming conventions.
389 */
390 public static final char[] _default_scheme = DEFAULT_SCHEME;
391
392 /***
393 * Default port for HTTP URL.
394 */
395 public static final int DEFAULT_PORT = 80;
396
397 /***
398 * Default port for HTTP URL.
399 * @deprecated Use {@link #DEFAULT_PORT} instead. This one doesn't conform
400 * to the project naming conventions.
401 */
402 public static final int _default_port = DEFAULT_PORT;
403
404 /***
405 * The serialVersionUID.
406 */
407 static final long serialVersionUID = -7158031098595039459L;
408
409
410
411 /***
412 * Get the scheme. You can get the scheme explicitly.
413 *
414 * @return the scheme
415 */
416 public char[] getRawScheme() {
417 return (_scheme == null) ? null : HttpURL.DEFAULT_SCHEME;
418 }
419
420
421 /***
422 * Get the scheme. You can get the scheme explicitly.
423 *
424 * @return the scheme null if empty or undefined
425 */
426 public String getScheme() {
427 return (_scheme == null) ? null : new String(HttpURL.DEFAULT_SCHEME);
428 }
429
430
431
432 /***
433 * Get the port number.
434 * @return the port number
435 */
436 public int getPort() {
437 return (_port == -1) ? HttpURL.DEFAULT_PORT : _port;
438 }
439
440
441
442 /***
443 * Set the raw-escaped user and password.
444 *
445 * @param escapedUser the raw-escaped user
446 * @param escapedPassword the raw-escaped password; could be null
447 * @throws URIException escaped user not valid or user required; escaped
448 * password not valid or username missed
449 */
450 public void setRawUserinfo(char[] escapedUser, char[] escapedPassword)
451 throws URIException {
452
453 if (escapedUser == null || escapedUser.length == 0) {
454 throw new URIException(URIException.PARSING, "user required");
455 }
456 if (!validate(escapedUser, within_userinfo)
457 || ((escapedPassword != null)
458 && !validate(escapedPassword, within_userinfo))) {
459 throw new URIException(URIException.ESCAPING,
460 "escaped userinfo not valid");
461 }
462 String username = new String(escapedUser);
463 String password = (escapedPassword == null)
464 ? null : new String(escapedPassword);
465 String userinfo = username + ((password == null) ? "" : ":" + password);
466 String hostname = new String(getRawHost());
467 String hostport = (_port == -1) ? hostname : hostname + ":" + _port;
468 String authority = userinfo + "@" + hostport;
469 _userinfo = userinfo.toCharArray();
470 _authority = authority.toCharArray();
471 setURI();
472 }
473
474
475 /***
476 * Set the raw-escaped user and password.
477 *
478 * @param escapedUser the escaped user
479 * @param escapedPassword the escaped password; could be null
480 * @throws URIException escaped user not valid or user required; escaped
481 * password not valid or username missed
482 * @throws NullPointerException null user
483 */
484 public void setEscapedUserinfo(String escapedUser, String escapedPassword)
485 throws URIException, NullPointerException {
486
487 setRawUserinfo(escapedUser.toCharArray(), (escapedPassword == null)
488 ? null : escapedPassword.toCharArray());
489 }
490
491
492 /***
493 * Set the user and password.
494 *
495 * @param user the user
496 * @param password the password; could be null
497 * @throws URIException encoding error or username missed
498 * @throws NullPointerException null user
499 */
500 public void setUserinfo(String user, String password)
501 throws URIException, NullPointerException {
502
503 String charset = getProtocolCharset();
504 setRawUserinfo(encode(user, within_userinfo, charset),
505 (password == null)
506 ? null
507 : encode(password, within_userinfo, charset));
508 }
509
510
511 /***
512 * Set the raw-escaped user.
513 *
514 * @param escapedUser the raw-escaped user
515 * @throws URIException escaped user not valid or user required
516 */
517 public void setRawUser(char[] escapedUser) throws URIException {
518 if (escapedUser == null || escapedUser.length == 0) {
519 throw new URIException(URIException.PARSING, "user required");
520 }
521 if (!validate(escapedUser, within_userinfo)) {
522 throw new URIException(URIException.ESCAPING,
523 "escaped user not valid");
524 }
525 String username = new String(escapedUser);
526 String password = new String(getRawPassword());
527 String userinfo = username + ((password == null) ? "" : ":" + password);
528 String hostname = new String(getRawHost());
529 String hostport = (_port == -1) ? hostname : hostname + ":" + _port;
530 String authority = userinfo + "@" + hostport;
531 _userinfo = userinfo.toCharArray();
532 _authority = authority.toCharArray();
533 setURI();
534 }
535
536
537 /***
538 * Set the escaped user string.
539 *
540 * @param escapedUser the escaped user string
541 * @throws URIException escaped user not valid
542 * @throws NullPointerException null user
543 */
544 public void setEscapedUser(String escapedUser)
545 throws URIException, NullPointerException {
546 setRawUser(escapedUser.toCharArray());
547 }
548
549
550 /***
551 * Set the user string.
552 *
553 * @param user the user string
554 * @throws URIException user encoding error
555 * @throws NullPointerException null user
556 */
557 public void setUser(String user) throws URIException, NullPointerException {
558 setRawUser(encode(user, allowed_within_userinfo, getProtocolCharset()));
559 }
560
561
562 /***
563 * Get the raw-escaped user.
564 *
565 * @return the raw-escaped user
566 */
567 public char[] getRawUser() {
568 if (_userinfo == null || _userinfo.length == 0) {
569 return null;
570 }
571 int to = indexFirstOf(_userinfo, ':');
572
573 if (to == -1) {
574 return _userinfo;
575 }
576 char[] result = new char[to];
577 System.arraycopy(_userinfo, 0, result, 0, to);
578 return result;
579 }
580
581
582 /***
583 * Get the escaped user
584 *
585 * @return the escaped user
586 */
587 public String getEscapedUser() {
588 char[] user = getRawUser();
589 return (user == null) ? null : new String(user);
590 }
591
592
593 /***
594 * Get the user.
595 *
596 * @return the user name
597 * @throws URIException If {@link #decode} fails
598 */
599 public String getUser() throws URIException {
600 char[] user = getRawUser();
601 return (user == null) ? null : decode(user, getProtocolCharset());
602 }
603
604
605 /***
606 * Set the raw-escaped password.
607 *
608 * @param escapedPassword the raw-escaped password; could be null
609 * @throws URIException escaped password not valid or username missed
610 */
611 public void setRawPassword(char[] escapedPassword) throws URIException {
612 if (escapedPassword != null
613 && !validate(escapedPassword, within_userinfo)) {
614 throw new URIException(URIException.ESCAPING,
615 "escaped password not valid");
616 }
617 if (getRawUser() == null || getRawUser().length == 0) {
618 throw new URIException(URIException.PARSING, "username required");
619 }
620 String username = new String(getRawUser());
621 String password = new String(escapedPassword);
622
623 String userinfo = username + ((password == null) ? "" : ":" + password);
624 String hostname = new String(getRawHost());
625 String hostport = (_port == -1) ? hostname : hostname + ":" + _port;
626 String authority = userinfo + "@" + hostport;
627 _userinfo = userinfo.toCharArray();
628 _authority = authority.toCharArray();
629 setURI();
630 }
631
632
633 /***
634 * Set the escaped password string.
635 *
636 * @param escapedPassword the escaped password string; could be null
637 * @throws URIException escaped password not valid or username missed
638 */
639 public void setEscapedPassword(String escapedPassword) throws URIException {
640 setRawPassword((escapedPassword == null) ? null
641 : escapedPassword.toCharArray());
642 }
643
644
645 /***
646 * Set the password string.
647 *
648 * @param password the password string; could be null
649 * @throws URIException encoding error or username missed
650 */
651 public void setPassword(String password) throws URIException {
652 setRawPassword((password == null) ? null : encode(password,
653 allowed_within_userinfo, getProtocolCharset()));
654 }
655
656
657 /***
658 * Get the raw-escaped password.
659 *
660 * @return the raw-escaped password
661 */
662 public char[] getRawPassword() {
663 int from = indexFirstOf(_userinfo, ':');
664 if (from == -1) {
665 return null;
666 }
667 int len = _userinfo.length - from - 1;
668 char[] result = new char[len];
669 System.arraycopy(_userinfo, from + 1, result, 0, len);
670 return result;
671 }
672
673
674 /***
675 * Get the escaped password.
676 *
677 * @return the escaped password
678 */
679 public String getEscapedPassword() {
680 char[] password = getRawPassword();
681 return (password == null) ? null : new String(password);
682 }
683
684
685 /***
686 * Get the password.
687 *
688 * @return the password
689 * @throws URIException If {@link #decode(char[],String)} fails.
690 */
691 public String getPassword() throws URIException {
692 char[] password = getRawPassword();
693 return (password == null) ? null : decode(password,
694 getProtocolCharset());
695 }
696
697
698
699 /***
700 * Get the raw-escaped current hierarchy level.
701 *
702 * @return the raw-escaped current hierarchy level
703 * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
704 */
705 public char[] getRawCurrentHierPath() throws URIException {
706 return (_path == null || _path.length == 0) ? rootPath
707 : super.getRawCurrentHierPath(_path);
708 }
709
710
711 /***
712 * Get the level above the this hierarchy level.
713 *
714 * @return the raw above hierarchy level
715 * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
716 */
717 public char[] getRawAboveHierPath() throws URIException {
718 char[] path = getRawCurrentHierPath();
719 return (path == null || path.length == 0) ? rootPath : getRawCurrentHierPath(path);
720 }
721
722
723 /***
724 * Get the raw escaped path.
725 *
726 * @return the path '/' if empty or undefined
727 */
728 public char[] getRawPath() {
729 char[] path = super.getRawPath();
730 return (path == null || path.length == 0) ? rootPath : path;
731 }
732
733
734
735 /***
736 * Set the query as the name and value pair.
737 *
738 * @param queryName the query string.
739 * @param queryValue the query string.
740 * @throws URIException incomplete trailing escape pattern
741 * Or unsupported character encoding
742 * @throws NullPointerException null query
743 * @see #encode
744 */
745 public void setQuery(String queryName, String queryValue)
746 throws URIException, NullPointerException {
747
748 StringBuffer buff = new StringBuffer();
749
750 String charset = getProtocolCharset();
751 buff.append(encode(queryName, allowed_within_query, charset));
752 buff.append('=');
753 buff.append(encode(queryValue, allowed_within_query, charset));
754 _query = buff.toString().toCharArray();
755 setURI();
756 }
757
758
759 /***
760 * Set the query as the name and value pairs.
761 *
762 * @param queryName the array of the query string.
763 * @param queryValue the array of the query string.
764 * @throws URIException incomplete trailing escape pattern,
765 * unsupported character encoding or wrong array size
766 * @throws NullPointerException null query
767 * @see #encode
768 */
769 public void setQuery(String[] queryName, String[] queryValue)
770 throws URIException, NullPointerException {
771
772 int length = queryName.length;
773 if (length != queryValue.length) {
774 throw new URIException("wrong array size of query");
775 }
776
777 StringBuffer buff = new StringBuffer();
778
779 String charset = getProtocolCharset();
780 for (int i = 0; i < length; i++) {
781 buff.append(encode(queryName[i], allowed_within_query, charset));
782 buff.append('=');
783 buff.append(encode(queryValue[i], allowed_within_query, charset));
784 if (i + 1 < length) {
785 buff.append('&');
786 }
787 }
788 _query = buff.toString().toCharArray();
789 setURI();
790 }
791
792
793
794 /***
795 * Verify the valid class use for construction.
796 *
797 * @throws URIException the wrong scheme use
798 */
799 protected void checkValid() throws URIException {
800
801 if (!(equals(_scheme, DEFAULT_SCHEME) || _scheme == null)) {
802 throw new URIException(URIException.PARSING, "wrong class use");
803 }
804 }
805
806 }
807