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