changeset 1575:0160650180bc

better http authentication
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 27 Jan 2021 15:31:26 -0700
parents f118ead273a1
children 13135e289b50
files src/luan/modules/url/LuanUrl.java src/luan/modules/url/WwwAuthenticate.java
diffstat 2 files changed, 55 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
diff -r f118ead273a1 -r 0160650180bc src/luan/modules/url/LuanUrl.java
--- a/src/luan/modules/url/LuanUrl.java	Sun Dec 20 13:17:27 2020 -0700
+++ b/src/luan/modules/url/LuanUrl.java	Wed Jan 27 15:31:26 2021 -0700
@@ -280,8 +280,13 @@
 			if( responseCode == 401 && authUsername != null && authorization==null ) {
 				String authStr = httpCon.getHeaderField("www-authenticate");
 				//System.out.println("auth = "+authStr);
+				List<WwwAuthenticate> auths;
 				try {
-					WwwAuthenticate auth = new WwwAuthenticate(authStr);
+					auths = WwwAuthenticate.parse(authStr);
+				} catch(ParseException pe) {
+					throw new LuanException(pe);
+				}
+				for( WwwAuthenticate auth : auths ) {
 					if( auth.type.equals("Basic") ) {
 						String val = basicAuth(authUsername,authPassword);
 						throw new AuthException(val);
@@ -320,11 +325,9 @@
 						}
 						//System.out.println("val = "+val);
 						throw new AuthException(val);
-					} else
-						throw new RuntimeException(auth.type);
-				} catch(ParseException pe) {
-					throw new LuanException(pe);
+					}
 				}
+				throw new RuntimeException(authStr);
 			}
 			String msg = "" + responseCode;
 			String responseMessage = httpCon.getResponseMessage();
diff -r f118ead273a1 -r 0160650180bc src/luan/modules/url/WwwAuthenticate.java
--- a/src/luan/modules/url/WwwAuthenticate.java	Sun Dec 20 13:17:27 2020 -0700
+++ b/src/luan/modules/url/WwwAuthenticate.java	Wed Jan 27 15:31:26 2021 -0700
@@ -2,52 +2,73 @@
 
 import java.util.Map;
 import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
 import goodjava.parser.Parser;
 import goodjava.parser.ParseException;
+import goodjava.logging.Logger;
+import goodjava.logging.LoggerFactory;
 
 
 public final class WwwAuthenticate {
+	private static final Logger logger = LoggerFactory.getLogger(WwwAuthenticate.class);
+
+	public static List<WwwAuthenticate> parse(String header) throws ParseException {
+		Parser parser = new Parser(header);
+		List<WwwAuthenticate> auths = new ArrayList<WwwAuthenticate>();
+		do {
+			auths.add(new WwwAuthenticate(parser,header));
+		} while( !parser.endOfInput() );
+		return auths;
+	}
+
 	public final String type;
 	public final Map<String,String> options = new HashMap<String,String>();
 	private final Parser parser;
 
-	public WwwAuthenticate(String header) throws ParseException {
-		parser = new Parser(header);
+	private WwwAuthenticate(Parser parser,String header) throws ParseException {
+		this.parser = parser;
 		type = parseType();
 		if( !matchSpace() )
 			throw new ParseException(parser,"space expected");
 		do {
 			while( matchSpace() );
-			int start = parser.currentIndex();
-			while( parser.inCharRange('a','z') );
-			String name = parser.textFrom(start);
-			if( name.length() == 0 )
-				throw new ParseException(parser,"option name not found");
-			if( !parser.match('=') )
-				throw new ParseException(parser,"'=' expected");
-			if( !parser.match('"') )
-				throw new ParseException(parser,"'\"' expected");
-			start = parser.currentIndex();
-			while( !parser.test('"') ) {
-				if( !parser.anyChar() )
-					throw new ParseException(parser,"unexpected end of text");
-			}
-			String value = parser.textFrom(start);
-			if( !parser.match('"') )
-				throw new ParseException(parser,"'\"' expected");
-			options.put(name,value);
-			while( matchSpace() );
+			if( !parseOption() )
+				return;
 		} while( parser.match(',') );
 		if( !parser.endOfInput() )
 			throw new ParseException(parser,"unexpected input");
 	}
 
 	private String parseType() throws ParseException {
-		if( parser.match("Basic") )
-			return "Basic";
-		if( parser.match("Digest") )
-			return "Digest";
-		throw new ParseException(parser,"invalid type");
+		int start = parser.currentIndex();
+		if( !parser.inCharRange('A','Z') )
+			throw new ParseException(parser,"invalid type");
+		while( parser.inCharRange('a','z') );
+		return parser.textFrom(start);
+	}
+
+	private boolean parseOption() throws ParseException {
+		int start = parser.begin();
+		while( parser.inCharRange('a','z') );
+		String name = parser.textFrom(start);
+		if( name.length() == 0 )
+			return parser.failure();
+		if( !parser.match('=') )
+			throw new ParseException(parser,"'=' expected");
+		if( !parser.match('"') )
+			throw new ParseException(parser,"'\"' expected");
+		start = parser.currentIndex();
+		while( !parser.test('"') ) {
+			if( !parser.anyChar() )
+				throw new ParseException(parser,"unexpected end of text");
+		}
+		String value = parser.textFrom(start);
+		if( !parser.match('"') )
+			throw new ParseException(parser,"'\"' expected");
+		options.put(name,value);
+		while( matchSpace() );
+		return parser.success();
 	}
 
 	private boolean matchSpace() {