view src/luan/modules/url/WwwAuthenticate.java @ 1575:0160650180bc

better http authentication
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 27 Jan 2021 15:31:26 -0700
parents 27efb1fcbcb5
children dbf63bef4b86
line wrap: on
line source

package luan.modules.url;

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;

	private WwwAuthenticate(Parser parser,String header) throws ParseException {
		this.parser = parser;
		type = parseType();
		if( !matchSpace() )
			throw new ParseException(parser,"space expected");
		do {
			while( matchSpace() );
			if( !parseOption() )
				return;
		} while( parser.match(',') );
		if( !parser.endOfInput() )
			throw new ParseException(parser,"unexpected input");
	}

	private String parseType() throws ParseException {
		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() {
		return parser.anyOf(" \t\r\n");
	}
}