Source Code Cross Referenced for AuthorizationInfo.java in  » Net » SkunkDAV » HTTPClient » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » SkunkDAV » HTTPClient 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * @(#)AuthorizationInfo.java				0.3-2 18/06/1999
0003:         *
0004:         *  This file is part of the HTTPClient package
0005:         *  Copyright (C) 1996-1999  Ronald Tschalär
0006:         *
0007:         *  This library is free software; you can redistribute it and/or
0008:         *  modify it under the terms of the GNU Lesser General Public
0009:         *  License as published by the Free Software Foundation; either
0010:         *  version 2 of the License, or (at your option) any later version.
0011:         *
0012:         *  This library is distributed in the hope that it will be useful,
0013:         *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015:         *  Lesser General Public License for more details.
0016:         *
0017:         *  You should have received a copy of the GNU Lesser General Public
0018:         *  License along with this library; if not, write to the Free
0019:         *  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
0020:         *  MA 02111-1307, USA
0021:         *
0022:         *  For questions, suggestions, bug-reports, enhancement-requests etc.
0023:         *  I may be contacted at:
0024:         *
0025:         *  ronald@innovation.ch
0026:         *
0027:         */
0028:
0029:        package HTTPClient;
0030:
0031:        import java.io.IOException;
0032:        import java.net.ProtocolException;
0033:        import java.util.Vector;
0034:        import java.util.Hashtable;
0035:        import java.util.Enumeration;
0036:
0037:        /**
0038:         * Holds the information for an authorization response.
0039:         *
0040:         * <P>There are 7 fields which make up this class: host, port, scheme,
0041:         * realm, cookie, params, and extra_info. The host and port select which
0042:         * server the info will be sent to. The realm is server specified string
0043:         * which groups various URLs under a given server together and which is
0044:         * used to select the correct info when a server issues an auth challenge;
0045:         * for schemes which don't use a realm (such as "NTLM", "PEM", and
0046:         * "Kerberos") the realm must be the empty string (""). The scheme is the
0047:         * authorization scheme used (such as "Basic" or "Digest").
0048:         *
0049:         * <P>There are basically two formats used for the Authorization header,
0050:         * the one used by the "Basic" scheme and derivatives, and the one used by
0051:         * the "Digest" scheme and derivatives. The first form contains just the
0052:         * the scheme and a "cookie":
0053:         * 
0054:         * <PRE>    Authorization: Basic aGVsbG86d29ybGQ=</PRE>
0055:         * 
0056:         * The second form contains the scheme followed by a number of parameters
0057:         * in the form of name=value pairs:
0058:         * 
0059:         * <PRE>    Authorization: Digest username="hello", realm="test", nonce="42", ...</PRE>
0060:         * 
0061:         * The two fields "cookie" and "params" correspond to these two forms.
0062:         * <A HREF="#toString()">toString()</A> is used by the AuthorizationModule
0063:         * when generating the Authorization header and will format the info
0064:         * accordingly. Note that "cookie" and "params" are mutually exclusive: if
0065:         * the cookie field is non-null then toString() will generate the first
0066:         * form; otherwise it will generate the second form.
0067:         *
0068:         * <P>In some schemes "extra" information needs to be kept which doesn't
0069:         * appear directly in the Authorization header. An example of this are the
0070:         * A1 and A2 strings in the Digest scheme. Since all elements in the params
0071:         * field will appear in the Authorization header this field can't be used
0072:         * for storing such info. This is what the extra_info field is for. It is
0073:         * an arbitrary object which can be manipulated by the corresponding
0074:         * setExtraInfo() and getExtraInfo() methods, but which will not be printed
0075:         * by toString().
0076:         *
0077:         * <P>The addXXXAuthorization(), removeXXXAuthorization(), and
0078:         * getAuthorization() methods manipulate and query an internal list of
0079:         * AuthorizationInfo instances. There can be only one instance per host,
0080:         * port, scheme, and realm combination (see <A HREF="#equals">equals()</A>).
0081:         *
0082:         * @version	0.3-2  18/06/1999
0083:         * @author	Ronald Tschalär
0084:         * @since	V0.1
0085:         */
0086:
0087:        public class AuthorizationInfo implements  GlobalConstants, Cloneable {
0088:            // class fields
0089:
0090:            /** Holds the list of lists of authorization info structures */
0091:            private static Hashtable CntxtList = new Hashtable();
0092:
0093:            /** A pointer to the handler to be called when we need authorization info */
0094:            private static AuthorizationHandler AuthHandler = new DefaultAuthHandler();
0095:
0096:            static {
0097:                CntxtList.put(HTTPConnection.getDefaultContext(),
0098:                        new Hashtable());
0099:            }
0100:
0101:            // the instance oriented stuff
0102:
0103:            /** the host (lowercase) */
0104:            private String host;
0105:
0106:            /** the port */
0107:            private int port;
0108:
0109:            /** the scheme. (e.g. "Basic")
0110:             * Note: don't lowercase because some buggy servers use a case-sensitive
0111:             * match */
0112:            private String scheme;
0113:
0114:            /** the realm */
0115:            private String realm;
0116:
0117:            /** the string used for the "Basic", "NTLM", and other authorization
0118:             *  schemes which don't use parameters  */
0119:            private String cookie;
0120:
0121:            /** any parameters */
0122:            private NVPair[] auth_params = new NVPair[0];
0123:
0124:            /** additional info which won't be displayed in the toString() */
0125:            private Object extra_info = null;
0126:
0127:            /** a list of paths where this realm has been known to be required */
0128:            private String[] paths = new String[0];
0129:
0130:            // Constructors
0131:
0132:            /**
0133:             * Creates an new info structure for the specified host and port.
0134:             *
0135:             * @param host   the host
0136:             * @param port   the port
0137:             */
0138:            AuthorizationInfo(String host, int port) {
0139:                this .host = host.trim().toLowerCase();
0140:                this .port = port;
0141:            }
0142:
0143:            /**
0144:             * Creates a new info structure for the specified host and port with the
0145:             * specified scheme, realm, params. The cookie is set to null.
0146:             *
0147:             * @param host   the host
0148:             * @param port   the port
0149:             * @param scheme the scheme
0150:             * @param realm  the realm
0151:             * @param params the parameters as an array of name/value pairs, or null
0152:             * @param info   arbitrary extra info, or null
0153:             */
0154:            public AuthorizationInfo(String host, int port, String scheme,
0155:                    String realm, NVPair params[], Object info) {
0156:                this .scheme = scheme.trim();
0157:                this .host = host.trim().toLowerCase();
0158:                this .port = port;
0159:                this .realm = realm;
0160:                this .cookie = null;
0161:
0162:                if (params != null)
0163:                    auth_params = Util.resizeArray(params, params.length);
0164:
0165:                this .extra_info = info;
0166:            }
0167:
0168:            /**
0169:             * Creates a new info structure for the specified host and port with the
0170:             * specified scheme, realm and cookie. The params is set to a zero-length
0171:             * array, and the extra_info is set to null.
0172:             *
0173:             * @param host   the host
0174:             * @param port   the port
0175:             * @param scheme the scheme
0176:             * @param realm  the realm
0177:             * @param cookie for the "Basic" scheme this is the base64-encoded
0178:             *               username/password; for the "NTLM" scheme this is the
0179:             *               base64-encoded username/password message.
0180:             */
0181:            public AuthorizationInfo(String host, int port, String scheme,
0182:                    String realm, String cookie) {
0183:                this .scheme = scheme.trim();
0184:                this .host = host.trim().toLowerCase();
0185:                this .port = port;
0186:                this .realm = realm;
0187:                if (cookie != null)
0188:                    this .cookie = cookie.trim();
0189:                else
0190:                    this .cookie = null;
0191:            }
0192:
0193:            /**
0194:             * Creates a new copy of the given AuthorizationInfo.
0195:             *
0196:             * @param templ the info to copy
0197:             */
0198:            AuthorizationInfo(AuthorizationInfo templ) {
0199:                this .scheme = templ.scheme;
0200:                this .host = templ.host;
0201:                this .port = templ.port;
0202:                this .realm = templ.realm;
0203:                this .cookie = templ.cookie;
0204:
0205:                this .auth_params = Util.resizeArray(templ.auth_params,
0206:                        templ.auth_params.length);
0207:
0208:                this .extra_info = templ.extra_info;
0209:            }
0210:
0211:            // Class Methods
0212:
0213:            /**
0214:             * Set's the authorization handler. This handler is called whenever
0215:             * the server requests authorization and no entry for the requested
0216:             * scheme and realm can be found in the list. The handler must implement
0217:             * the AuthorizationHandler interface.
0218:             * <BR>If no handler is set then a default handler is used. This handler
0219:             * currently only handles the "Basic" scheme and brings up a popup which
0220:             * prompts for the username and password.
0221:             * <BR>The default handler can be disabled by setting the auth handler
0222:             * to <var>null</var>.
0223:             *
0224:             * @param  handler the new authorization handler
0225:             * @return the old authorization handler
0226:             * @see    AuthorizationHandler
0227:             */
0228:            public static AuthorizationHandler setAuthHandler(
0229:                    AuthorizationHandler handler) {
0230:                AuthorizationHandler tmp = AuthHandler;
0231:                AuthHandler = handler;
0232:
0233:                return tmp;
0234:            }
0235:
0236:            /**
0237:             * Get's the current authorization handler.
0238:             *
0239:             * @return the current authorization handler, or null if none is set.
0240:             * @see    AuthorizationHandler
0241:             */
0242:            public static AuthorizationHandler getAuthHandler() {
0243:                return AuthHandler;
0244:            }
0245:
0246:            /**
0247:             * Searches for the authorization info using the given host, port,
0248:             * scheme and realm. The context is the default context.
0249:             *
0250:             * @param  host         the host
0251:             * @param  port         the port
0252:             * @param  scheme       the scheme
0253:             * @param  realm        the realm
0254:             * @return a pointer to the authorization data or null if not found
0255:             */
0256:            public static AuthorizationInfo getAuthorization(String host,
0257:                    int port, String scheme, String realm) {
0258:                return getAuthorization(host, port, scheme, realm,
0259:                        HTTPConnection.getDefaultContext());
0260:            }
0261:
0262:            /**
0263:             * Searches for the authorization info in the given context using the
0264:             * given host, port, scheme and realm.
0265:             *
0266:             * @param  host         the host
0267:             * @param  port         the port
0268:             * @param  scheme       the scheme
0269:             * @param  realm        the realm
0270:             * @param  context      the context this info is associated with
0271:             * @return a pointer to the authorization data or null if not found
0272:             */
0273:            public static synchronized AuthorizationInfo getAuthorization(
0274:                    String host, int port, String scheme, String realm,
0275:                    Object context) {
0276:                Hashtable AuthList = Util.getList(CntxtList, context);
0277:
0278:                AuthorizationInfo auth_info = new AuthorizationInfo(
0279:                        host.trim(), port, scheme.trim(), realm,
0280:                        (NVPair[]) null, null);
0281:
0282:                return (AuthorizationInfo) AuthList.get(auth_info);
0283:            }
0284:
0285:            /**
0286:             * Queries the AuthHandler for authorization info. It also adds this
0287:             * info to the list.
0288:             *
0289:             * @param  auth_info  any info needed by the AuthHandler; at a minimum the
0290:             *                    host, scheme and realm should be set.
0291:             * @param  req        the request which initiated this query
0292:             * @param  resp       the full response
0293:             * @return a structure containing the requested info, or null if either
0294:             *	       no AuthHandler is set or the user canceled the request.
0295:             * @exception AuthSchemeNotImplException if this is thrown by
0296:             *                                            the AuthHandler.
0297:             */
0298:            static AuthorizationInfo queryAuthHandler(
0299:                    AuthorizationInfo auth_info, RoRequest req, RoResponse resp)
0300:                    throws AuthSchemeNotImplException {
0301:                if (AuthHandler == null)
0302:                    return null;
0303:
0304:                AuthorizationInfo new_info = AuthHandler.getAuthorization(
0305:                        auth_info, req, resp);
0306:                if (new_info != null) {
0307:                    if (req != null)
0308:                        addAuthorization((AuthorizationInfo) new_info.clone(),
0309:                                req.getConnection().getContext());
0310:                    else
0311:                        addAuthorization((AuthorizationInfo) new_info.clone(),
0312:                                HTTPConnection.getDefaultContext());
0313:                }
0314:
0315:                return new_info;
0316:            }
0317:
0318:            /**
0319:             * Searches for the authorization info using the host, port, scheme and
0320:             * realm from the given info struct. If not found it queries the
0321:             * AuthHandler (if set).
0322:             *
0323:             * @param  auth_info    the AuthorizationInfo
0324:             * @param  request      the request which initiated this query
0325:             * @param  resp         the full response
0326:             * @param  query_auth_h if true, query the auth-handler if no info found.
0327:             * @return a pointer to the authorization data or null if not found
0328:             * @exception AuthSchemeNotImplException If thrown by the AuthHandler.
0329:             */
0330:            static synchronized AuthorizationInfo getAuthorization(
0331:                    AuthorizationInfo auth_info, RoRequest req,
0332:                    RoResponse resp, boolean query_auth_h)
0333:                    throws AuthSchemeNotImplException {
0334:                Hashtable AuthList;
0335:                if (req != null)
0336:                    AuthList = Util.getList(CntxtList, req.getConnection()
0337:                            .getContext());
0338:                else
0339:                    AuthList = Util.getList(CntxtList, HTTPConnection
0340:                            .getDefaultContext());
0341:
0342:                AuthorizationInfo new_info = (AuthorizationInfo) AuthList
0343:                        .get(auth_info);
0344:
0345:                if (new_info == null && query_auth_h)
0346:                    new_info = queryAuthHandler(auth_info, req, resp);
0347:
0348:                return new_info;
0349:            }
0350:
0351:            /**
0352:             * Searches for the authorization info given a host, port, scheme and
0353:             * realm. Queries the AuthHandler if not found in list.
0354:             *
0355:             * @param  host         the host
0356:             * @param  port         the port
0357:             * @param  scheme       the scheme
0358:             * @param  realm        the realm
0359:             * @param  query_auth_h if true, query the auth-handler if no info found.
0360:             * @return a pointer to the authorization data or null if not found
0361:             * @exception AuthSchemeNotImplException If thrown by the AuthHandler.
0362:             */
0363:            static AuthorizationInfo getAuthorization(String host, int port,
0364:                    String scheme, String realm, boolean query_auth_h)
0365:                    throws AuthSchemeNotImplException {
0366:                return getAuthorization(new AuthorizationInfo(host.trim(),
0367:                        port, scheme.trim(), realm, (NVPair[]) null, null),
0368:                        null, null, query_auth_h);
0369:            }
0370:
0371:            /**
0372:             * Adds an authorization entry to the list using the default context.
0373:             * If an entry for the specified scheme and realm already exists then
0374:             * its cookie and params are replaced with the new data.
0375:             *
0376:             * @param auth_info the AuthorizationInfo to add
0377:             */
0378:            public static void addAuthorization(AuthorizationInfo auth_info) {
0379:                addAuthorization(auth_info, HTTPConnection.getDefaultContext());
0380:            }
0381:
0382:            /**
0383:             * Adds an authorization entry to the list. If an entry for the
0384:             * specified scheme and realm already exists then its cookie and
0385:             * params are replaced with the new data.
0386:             *
0387:             * @param auth_info the AuthorizationInfo to add
0388:             * @param context   the context to associate this info with
0389:             */
0390:            public static void addAuthorization(AuthorizationInfo auth_info,
0391:                    Object context) {
0392:                Hashtable AuthList = Util.getList(CntxtList, context);
0393:
0394:                // merge path list
0395:                AuthorizationInfo old_info = (AuthorizationInfo) AuthList
0396:                        .get(auth_info);
0397:                if (old_info != null) {
0398:                    int ol = old_info.paths.length, al = auth_info.paths.length;
0399:
0400:                    if (al == 0)
0401:                        auth_info.paths = old_info.paths;
0402:                    else {
0403:                        auth_info.paths = Util.resizeArray(auth_info.paths, al
0404:                                + ol);
0405:                        System.arraycopy(old_info.paths, 0, auth_info.paths,
0406:                                al, ol);
0407:                    }
0408:                }
0409:
0410:                AuthList.put(auth_info, auth_info);
0411:            }
0412:
0413:            /**
0414:             * Adds an authorization entry to the list using the default context.
0415:             * If an entry for the specified scheme and realm already exists then
0416:             * its cookie and params are replaced with the new data.
0417:             *
0418:             * @param host   the host
0419:             * @param port   the port
0420:             * @param scheme the scheme
0421:             * @param realm  the realm
0422:             * @param cookie the cookie
0423:             * @param params an array of name/value pairs of parameters
0424:             * @param info   arbitrary extra auth info
0425:             */
0426:            public static void addAuthorization(String host, int port,
0427:                    String scheme, String realm, String cookie,
0428:                    NVPair params[], Object info) {
0429:                addAuthorization(host, port, scheme, realm, cookie, params,
0430:                        info, HTTPConnection.getDefaultContext());
0431:            }
0432:
0433:            /**
0434:             * Adds an authorization entry to the list. If an entry for the
0435:             * specified scheme and realm already exists then its cookie and
0436:             * params are replaced with the new data.
0437:             *
0438:             * @param host    the host
0439:             * @param port    the port
0440:             * @param scheme  the scheme
0441:             * @param realm   the realm
0442:             * @param cookie  the cookie
0443:             * @param params  an array of name/value pairs of parameters
0444:             * @param info    arbitrary extra auth info
0445:             * @param context the context to associate this info with
0446:             */
0447:            public static void addAuthorization(String host, int port,
0448:                    String scheme, String realm, String cookie,
0449:                    NVPair params[], Object info, Object context) {
0450:                AuthorizationInfo auth = new AuthorizationInfo(host, port,
0451:                        scheme, realm, cookie);
0452:                if (params != null && params.length > 0)
0453:                    auth.auth_params = Util.resizeArray(params, params.length);
0454:                auth.extra_info = info;
0455:
0456:                addAuthorization(auth, context);
0457:            }
0458:
0459:            /**
0460:             * Adds an authorization entry for the "Basic" authorization scheme to
0461:             * the list using the default context. If an entry already exists for
0462:             * the "Basic" scheme and the specified realm then it is overwritten.
0463:             *
0464:             * @param host   the host
0465:             * @param port   the port
0466:             * @param realm  the realm
0467:             * @param user   the username
0468:             * @param passwd the password
0469:             */
0470:            public static void addBasicAuthorization(String host, int port,
0471:                    String realm, String user, String passwd) {
0472:                addAuthorization(host, port, "Basic", realm, Codecs
0473:                        .base64Encode(user + ":" + passwd), (NVPair[]) null,
0474:                        null);
0475:            }
0476:
0477:            /**
0478:             * Adds an authorization entry for the "Basic" authorization scheme to
0479:             * the list. If an entry already exists for the "Basic" scheme and the
0480:             * specified realm then it is overwritten.
0481:             *
0482:             * @param host    the host
0483:             * @param port    the port
0484:             * @param realm   the realm
0485:             * @param user    the username
0486:             * @param passwd  the password
0487:             * @param context the context to associate this info with
0488:             */
0489:            public static void addBasicAuthorization(String host, int port,
0490:                    String realm, String user, String passwd, Object context) {
0491:                addAuthorization(host, port, "Basic", realm, Codecs
0492:                        .base64Encode(user + ":" + passwd), (NVPair[]) null,
0493:                        null, context);
0494:            }
0495:
0496:            /**
0497:             * Adds an authorization entry for the "Digest" authorization scheme to
0498:             * the list using the default context. If an entry already exists for the
0499:             * "Digest" scheme and the specified realm then it is overwritten.
0500:             *
0501:             * @param host   the host
0502:             * @param port   the port
0503:             * @param realm  the realm
0504:             * @param user   the username
0505:             * @param passwd the password
0506:             */
0507:            public static void addDigestAuthorization(String host, int port,
0508:                    String realm, String user, String passwd) {
0509:                addDigestAuthorization(host, port, realm, user, passwd,
0510:                        HTTPConnection.getDefaultContext());
0511:            }
0512:
0513:            /**
0514:             * Adds an authorization entry for the "Digest" authorization scheme to
0515:             * the list. If an entry already exists for the "Digest" scheme and the
0516:             * specified realm then it is overwritten.
0517:             *
0518:             * @param host    the host
0519:             * @param port    the port
0520:             * @param realm   the realm
0521:             * @param user    the username
0522:             * @param passwd  the password
0523:             * @param context the context to associate this info with
0524:             */
0525:            public static void addDigestAuthorization(String host, int port,
0526:                    String realm, String user, String passwd, Object context) {
0527:                AuthorizationInfo prev = getAuthorization(host, port, "Digest",
0528:                        realm, context);
0529:                NVPair[] params;
0530:
0531:                if (prev == null) {
0532:                    params = new NVPair[4];
0533:                    params[0] = new NVPair("username", user);
0534:                    params[1] = new NVPair("uri", "");
0535:                    params[2] = new NVPair("nonce", "");
0536:                    params[3] = new NVPair("response", "");
0537:                } else {
0538:                    params = prev.getParams();
0539:                    for (int idx = 0; idx < params.length; idx++) {
0540:                        if (params[idx].getName().equalsIgnoreCase("username")) {
0541:                            params[idx] = new NVPair("username", user);
0542:                            break;
0543:                        }
0544:                    }
0545:                }
0546:
0547:                String[] extra = {
0548:                        new MD5(user + ":" + realm + ":" + passwd).asHex(),
0549:                        null };
0550:
0551:                addAuthorization(host, port, "Digest", realm, null, params,
0552:                        extra, context);
0553:            }
0554:
0555:            /**
0556:             * Removes an authorization entry from the list using the default context.
0557:             * If no entry for the specified host, port, scheme and realm exists then
0558:             * this does nothing.
0559:             *
0560:             * @param auth_info the AuthorizationInfo to remove
0561:             */
0562:            public static void removeAuthorization(AuthorizationInfo auth_info) {
0563:                removeAuthorization(auth_info, HTTPConnection
0564:                        .getDefaultContext());
0565:            }
0566:
0567:            /**
0568:             * Removes an authorization entry from the list. If no entry for the
0569:             * specified host, port, scheme and realm exists then this does nothing.
0570:             *
0571:             * @param auth_info the AuthorizationInfo to remove
0572:             * @param context   the context this info is associated with
0573:             */
0574:            public static void removeAuthorization(AuthorizationInfo auth_info,
0575:                    Object context) {
0576:                Hashtable AuthList = Util.getList(CntxtList, context);
0577:                AuthList.remove(auth_info);
0578:            }
0579:
0580:            /**
0581:             * Removes an authorization entry from the list using the default context.
0582:             * If no entry for the specified host, port, scheme and realm exists then
0583:             * this does nothing.
0584:             *
0585:             * @param host   the host
0586:             * @param port   the port
0587:             * @param scheme the scheme
0588:             * @param realm  the realm
0589:             */
0590:            public static void removeAuthorization(String host, int port,
0591:                    String scheme, String realm) {
0592:                removeAuthorization(new AuthorizationInfo(host, port, scheme,
0593:                        realm, (NVPair[]) null, null));
0594:            }
0595:
0596:            /**
0597:             * Removes an authorization entry from the list. If no entry for the
0598:             * specified host, port, scheme and realm exists then this does nothing.
0599:             *
0600:             * @param host    the host
0601:             * @param port    the port
0602:             * @param scheme  the scheme
0603:             * @param realm   the realm
0604:             * @param context the context this info is associated with
0605:             */
0606:            public static void removeAuthorization(String host, int port,
0607:                    String scheme, String realm, Object context) {
0608:                removeAuthorization(new AuthorizationInfo(host, port, scheme,
0609:                        realm, (NVPair[]) null, null), context);
0610:            }
0611:
0612:            /**
0613:             * Tries to find the candidate in the current list of auth info for the
0614:             * given request. The paths associated with each auth info are examined,
0615:             * and the one with either the nearest direct parent or child is chosen.
0616:             * This is used for preemptively sending auth info.
0617:             *
0618:             * @param  req  the Request
0619:             * @return an AuthorizationInfo containing the info for the best match,
0620:             *         or null if none found.
0621:             */
0622:            static AuthorizationInfo findBest(RoRequest req) {
0623:                String path = Util.getPath(req.getRequestURI());
0624:                String host = req.getConnection().getHost();
0625:                int port = req.getConnection().getPort();
0626:
0627:                // First search for an exact match
0628:
0629:                Hashtable AuthList = Util.getList(CntxtList, req
0630:                        .getConnection().getContext());
0631:                Enumeration list = AuthList.elements();
0632:                while (list.hasMoreElements()) {
0633:                    AuthorizationInfo info = (AuthorizationInfo) list
0634:                            .nextElement();
0635:
0636:                    if (!info.host.equals(host) || info.port != port)
0637:                        continue;
0638:
0639:                    String[] paths = info.paths;
0640:                    for (int idx = 0; idx < paths.length; idx++) {
0641:                        if (path.equals(paths[idx]))
0642:                            return info;
0643:                    }
0644:                }
0645:
0646:                // Now find the closest parent or child
0647:
0648:                AuthorizationInfo best = null;
0649:                String base = path.substring(0, path.lastIndexOf('/') + 1);
0650:                int min = Integer.MAX_VALUE;
0651:
0652:                list = AuthList.elements();
0653:                while (list.hasMoreElements()) {
0654:                    AuthorizationInfo info = (AuthorizationInfo) list
0655:                            .nextElement();
0656:
0657:                    if (!info.host.equals(host) || info.port != port)
0658:                        continue;
0659:
0660:                    String[] paths = info.paths;
0661:                    for (int idx = 0; idx < paths.length; idx++) {
0662:                        // strip the last path segment, leaving a trailing "/"
0663:                        String ibase = paths[idx].substring(0, paths[idx]
0664:                                .lastIndexOf('/') + 1);
0665:
0666:                        if (base.equals(ibase))
0667:                            return info;
0668:
0669:                        if (base.startsWith(ibase)) // found a parent
0670:                        {
0671:                            int num_seg = 0, pos = ibase.length() - 1;
0672:                            while ((pos = base.indexOf('/', pos + 1)) != -1)
0673:                                num_seg++;
0674:
0675:                            if (num_seg < min) {
0676:                                min = num_seg;
0677:                                best = info;
0678:                            }
0679:                        } else if (ibase.startsWith(base)) // found a child
0680:                        {
0681:                            int num_seg = 0, pos = base.length();
0682:                            while ((pos = ibase.indexOf('/', pos + 1)) != -1)
0683:                                num_seg++;
0684:
0685:                            if (num_seg < min) {
0686:                                min = num_seg;
0687:                                best = info;
0688:                            }
0689:                        }
0690:                    }
0691:                }
0692:
0693:                return best;
0694:            }
0695:
0696:            /**
0697:             * Adds the path from the given resource to our path list. The path
0698:             * list is used for deciding when to preemptively send auth info.
0699:             *
0700:             * @param resource the resource from which to extract the path
0701:             */
0702:            public synchronized void addPath(String resource) {
0703:                String path = Util.getPath(resource);
0704:
0705:                // First check that we don't already have this one
0706:                for (int idx = 0; idx < paths.length; idx++)
0707:                    if (paths[idx].equals(path))
0708:                        return;
0709:
0710:                // Ok, add it
0711:                paths = Util.resizeArray(paths, paths.length + 1);
0712:                paths[paths.length - 1] = path;
0713:            }
0714:
0715:            /**
0716:             * Parses the authentication challenge(s) into an array of new info
0717:             * structures for the specified host and port.
0718:             *
0719:             * @param challenge a string containing authentication info. This must
0720:             *                  have the same format as value part of a
0721:             *                  WWW-authenticate response header field, and may
0722:             *                  contain multiple authentication challenges.
0723:             * @param req       the original request.
0724:             * @exception ProtocolException if any error during the parsing occurs.
0725:             */
0726:            static AuthorizationInfo[] parseAuthString(String challenge,
0727:                    RoRequest req, RoResponse resp) throws ProtocolException {
0728:                int beg = 0, end = 0;
0729:                char[] buf = challenge.toCharArray();
0730:                char ch;
0731:                int len = buf.length;
0732:
0733:                AuthorizationInfo auth_arr[] = new AuthorizationInfo[0], curr;
0734:
0735:                while (Character.isSpace(buf[len - 1]))
0736:                    len--;
0737:
0738:                while (true) // get all challenges
0739:                {
0740:                    // get scheme
0741:                    beg = Util.skipSpace(buf, beg);
0742:                    if (beg == len)
0743:                        break;
0744:
0745:                    end = Util.findSpace(buf, beg + 1);
0746:
0747:                    int sts;
0748:                    try {
0749:                        sts = resp.getStatusCode();
0750:                    } catch (IOException ioe) {
0751:                        throw new ProtocolException(ioe.toString());
0752:                    }
0753:                    if (sts == 401)
0754:                        curr = new AuthorizationInfo(req.getConnection()
0755:                                .getHost(), req.getConnection().getPort());
0756:                    else
0757:                        curr = new AuthorizationInfo(req.getConnection()
0758:                                .getProxyHost(), req.getConnection()
0759:                                .getProxyPort());
0760:                    curr.scheme = challenge.substring(beg, end);
0761:
0762:                    // get auth-parameters
0763:                    boolean first = true;
0764:                    Vector params = new Vector();
0765:                    while (true) {
0766:                        beg = Util.skipSpace(buf, end);
0767:                        if (beg == len)
0768:                            break;
0769:
0770:                        if (!first) // expect ","
0771:                        {
0772:                            if (buf[beg] != ',')
0773:                                throw new ProtocolException(
0774:                                        "Bad Authentication header "
0775:                                                + "format: '"
0776:                                                + challenge
0777:                                                + "'\nExpected \",\" at position "
0778:                                                + beg);
0779:
0780:                            beg = Util.skipSpace(buf, beg + 1); // find param name
0781:                            if (beg == len)
0782:                                break;
0783:                            if (buf[beg] == ',') // skip empty params
0784:                            {
0785:                                end = beg;
0786:                                continue;
0787:                            }
0788:                        }
0789:
0790:                        int pstart = beg;
0791:
0792:                        // extract name
0793:                        end = beg + 1;
0794:                        while (end < len && !Character.isSpace(buf[end])
0795:                                && buf[end] != '=' && buf[end] != ',')
0796:                            end++;
0797:
0798:                        // hack to deal with schemes which use cookies in challenge
0799:                        if (first
0800:                                && (end == len || buf[end] == '='
0801:                                        && (end + 1 == len || (buf[end + 1] == '=' && end + 2 == len)))) {
0802:                            curr.cookie = challenge.substring(beg, len);
0803:                            beg = len;
0804:                            break;
0805:                        }
0806:
0807:                        String param_name = challenge.substring(beg, end), param_value;
0808:
0809:                        beg = Util.skipSpace(buf, end); // find "=" or ","
0810:
0811:                        if (beg < len && buf[beg] != '=' && buf[beg] != ',') { // It's not a param, but another challenge
0812:                            beg = pstart;
0813:                            break;
0814:                        }
0815:
0816:                        if (buf[beg] == '=') // we have a value
0817:                        {
0818:                            beg = Util.skipSpace(buf, beg + 1);
0819:                            if (beg == len)
0820:                                throw new ProtocolException(
0821:                                        "Bad Authentication header "
0822:                                                + "format: "
0823:                                                + challenge
0824:                                                + "\nUnexpected EOL after token"
0825:                                                + " at position " + (end - 1));
0826:                            if (buf[beg] != '"') // it's a token
0827:                            {
0828:                                end = Util.skipToken(buf, beg);
0829:                                if (end == beg)
0830:                                    throw new ProtocolException(
0831:                                            "Bad Authentication header "
0832:                                                    + "format: " + challenge
0833:                                                    + "\nToken expected at "
0834:                                                    + "position " + beg);
0835:                                param_value = challenge.substring(beg, end);
0836:                            } else // it's a quoted-string
0837:                            {
0838:                                end = beg++;
0839:                                do
0840:                                    end = challenge.indexOf('"', end + 1);
0841:                                while (end != -1
0842:                                        && challenge.charAt(end - 1) == '\\');
0843:                                if (end == -1)
0844:                                    throw new ProtocolException(
0845:                                            "Bad Authentication header "
0846:                                                    + "format: "
0847:                                                    + challenge
0848:                                                    + "\nClosing <\"> for "
0849:                                                    + "quoted-string starting at position "
0850:                                                    + beg + " not found");
0851:                                param_value = Util.dequoteString(challenge
0852:                                        .substring(beg, end));
0853:                                end++;
0854:                            }
0855:                        } else
0856:                            // this is not strictly allowed
0857:                            param_value = null;
0858:
0859:                        if (param_name.equalsIgnoreCase("realm"))
0860:                            curr.realm = param_value;
0861:                        else
0862:                            params.addElement(new NVPair(param_name,
0863:                                    param_value));
0864:
0865:                        first = false;
0866:                    }
0867:
0868:                    if (!params.isEmpty()) {
0869:                        curr.auth_params = new NVPair[params.size()];
0870:                        params.copyInto(curr.auth_params);
0871:                    }
0872:
0873:                    if (curr.realm == null)
0874:                        /* Can't do this if we're supposed to allow for broken schemes
0875:                         * such as NTLM, Kerberos, and PEM.
0876:                         *
0877:                        throw new ProtocolException("Bad Authentication header "
0878:                            + "format: " + challenge + "\nNo realm value found");
0879:                         */
0880:                        curr.realm = "";
0881:
0882:                    auth_arr = Util.resizeArray(auth_arr, auth_arr.length + 1);
0883:                    auth_arr[auth_arr.length - 1] = curr;
0884:                }
0885:
0886:                return auth_arr;
0887:            }
0888:
0889:            // Instance Methods
0890:
0891:            /**
0892:             * Get the host.
0893:             *
0894:             * @return a string containing the host name.
0895:             */
0896:            public final String getHost() {
0897:                return host;
0898:            }
0899:
0900:            /**
0901:             * Get the port.
0902:             *
0903:             * @return an int containing the port number.
0904:             */
0905:            public final int getPort() {
0906:                return port;
0907:            }
0908:
0909:            /**
0910:             * Get the scheme.
0911:             *
0912:             * @return a string containing the scheme.
0913:             */
0914:            public final String getScheme() {
0915:                return scheme;
0916:            }
0917:
0918:            /**
0919:             * Get the realm.
0920:             *
0921:             * @return a string containing the realm.
0922:             */
0923:            public final String getRealm() {
0924:                return realm;
0925:            }
0926:
0927:            /**
0928:             * Get the cookie
0929:             *
0930:             * @return the cookie String
0931:             * @since V0.3-1
0932:             */
0933:            public final String getCookie() {
0934:                return cookie;
0935:            }
0936:
0937:            /**
0938:             * Set the cookie
0939:             *
0940:             * @param cookie the new cookie
0941:             * @since V0.3-1
0942:             */
0943:            public final void setCookie(String cookie) {
0944:                this .cookie = cookie;
0945:            }
0946:
0947:            /**
0948:             * Get the authentication parameters.
0949:             *
0950:             * @return an array of name/value pairs.
0951:             */
0952:            public final NVPair[] getParams() {
0953:                return Util.resizeArray(auth_params, auth_params.length);
0954:            }
0955:
0956:            /**
0957:             * Set the authentication parameters.
0958:             *
0959:             * @param an array of name/value pairs.
0960:             */
0961:            public final void setParams(NVPair[] params) {
0962:                if (params != null)
0963:                    auth_params = Util.resizeArray(params, params.length);
0964:                else
0965:                    auth_params = new NVPair[0];
0966:            }
0967:
0968:            /**
0969:             * Get the extra info.
0970:             *
0971:             * @return the extra_info object
0972:             */
0973:            public final Object getExtraInfo() {
0974:                return extra_info;
0975:            }
0976:
0977:            /**
0978:             * Set the extra info.
0979:             *
0980:             * @param info the extra info
0981:             */
0982:            public final void setExtraInfo(Object info) {
0983:                extra_info = info;
0984:            }
0985:
0986:            /**
0987:             * Constructs a string containing the authorization info. The format
0988:             * is that of the http Authorization header.
0989:             *
0990:             * @return a String containing all info.
0991:             */
0992:            public String toString() {
0993:                StringBuffer field = new StringBuffer(100);
0994:
0995:                field.append(scheme);
0996:                field.append(" ");
0997:
0998:                if (cookie != null) {
0999:                    field.append(cookie);
1000:                } else {
1001:                    if (realm.length() > 0) {
1002:                        field.append("realm=\"");
1003:                        field.append(Util.quoteString(realm, "\\\""));
1004:                        field.append('"');
1005:                    }
1006:
1007:                    for (int idx = 0; idx < auth_params.length; idx++) {
1008:                        field.append(',');
1009:                        field.append(auth_params[idx].getName());
1010:                        field.append("=\"");
1011:                        field.append(Util.quoteString(auth_params[idx]
1012:                                .getValue(), "\\\""));
1013:                        field.append('"');
1014:                    }
1015:                }
1016:
1017:                return field.toString();
1018:            }
1019:
1020:            /**
1021:             * Produces a hash code based on host, scheme and realm. Port is not
1022:             * included for simplicity (and because it probably won't make much
1023:             * difference). Used in the AuthorizationInfo.AuthList hash table.
1024:             *
1025:             * @return the hash code
1026:             */
1027:            public int hashCode() {
1028:                return (host + scheme.toLowerCase() + realm).hashCode();
1029:            }
1030:
1031:            /**
1032:             * Two AuthorizationInfos are considered equal if their host, port,
1033:             * scheme and realm match. Used in the AuthorizationInfo.AuthList hash
1034:             * table.
1035:             *
1036:             * @param obj another AuthorizationInfo against which this one is
1037:             *            to be compared.
1038:             * @return true if they match in the above mentioned fields; false
1039:             *              otherwise.
1040:             */
1041:            public boolean equals(Object obj) {
1042:                if ((obj != null) && (obj instanceof  AuthorizationInfo)) {
1043:                    AuthorizationInfo auth = (AuthorizationInfo) obj;
1044:                    if (host.equals(auth.host) && (port == auth.port)
1045:                            && scheme.equalsIgnoreCase(auth.scheme)
1046:                            && realm.equals(auth.realm))
1047:                        return true;
1048:                }
1049:                return false;
1050:            }
1051:
1052:            /**
1053:             * @return a clone of this AuthorizationInfo using a deep copy
1054:             */
1055:            public Object clone() {
1056:                AuthorizationInfo ai;
1057:                try {
1058:                    ai = (AuthorizationInfo) super .clone();
1059:                    ai.auth_params = Util.resizeArray(auth_params,
1060:                            auth_params.length);
1061:                    try {
1062:                        // ai.extra_info  = extra_info.clone();
1063:                        ai.extra_info = extra_info.getClass().getMethod(
1064:                                "clone", null).invoke(extra_info, null);
1065:                    } catch (Throwable t) {
1066:                    }
1067:                    ai.paths = new String[paths.length];
1068:                    System.arraycopy(paths, 0, ai.paths, 0, paths.length);
1069:                } catch (CloneNotSupportedException cnse) {
1070:                    throw new InternalError(cnse.toString()); /* shouldn't happen */
1071:                }
1072:
1073:                return ai;
1074:            }
1075:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.