/* * JLibs: Common Utilities for Java * Copyright (C) 2009 Santhosh Kumar T <santhosh.tekuri@gmail.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package jlibs.nio.http.util; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; import static java.util.Objects.requireNonNull; /** * @author Santhosh Kumar Tekuri */ public class DigestChallenge extends Challenge{ public static final String SCHEME = "Digest"; public static final String REALM = "realm"; public static final String NONCE = "nonce"; public static final String DOMAIN = "domain"; public static final String ALGORITHM = "algorithm"; public static final String OPAQUE = "opaque"; public static final String QOP = "qop"; public static final String STALE = "stale"; // mandatory public String realm; public String nonce; // optional public List<String> domains; public String opaque; public boolean stale; public String algorithm; public List<String> qops; public DigestChallenge(){ } public DigestChallenge(String headerValue){ Parser parser = new Parser(true, headerValue); while(true){ String name = parser.lvalue(); if(name==null) break; else if(REALM.equalsIgnoreCase(name)) realm = parser.rvalue(); else if(NONCE.equalsIgnoreCase(name)) nonce = parser.rvalue(); else if(DOMAIN.equalsIgnoreCase(name)){ StringTokenizer stok = new StringTokenizer(parser.rvalue(), " "); domains = new ArrayList<>(stok.countTokens()); while(stok.hasMoreTokens()) domains.add(stok.nextToken()); }else if(ALGORITHM.equalsIgnoreCase(name)) algorithm = parser.rvalue(); else if(OPAQUE.equalsIgnoreCase(name)) opaque = parser.rvalue(); else if(QOP.equalsIgnoreCase(name)){ StringTokenizer stok = new StringTokenizer(parser.rvalue(), ","); qops = new ArrayList<>(stok.countTokens()); while(stok.hasMoreTokens()) qops.add(stok.nextToken().trim()); }else if(STALE.equalsIgnoreCase(name)) stale = Boolean.valueOf(parser.rvalue()); parser.skipPairs(); parser.skip(); } requireNonNull(realm, "realm==null"); requireNonNull(nonce, "nonce==null"); } @Override public String scheme(){ return SCHEME; } @Override public String toString(){ StringBuilder buffer = new StringBuilder(); buffer.append(SCHEME).append(' '); Parser.appendQuotedValue(buffer, REALM, realm); if(domains!=null && !domains.isEmpty()){ buffer.append(','); Parser.appendQuotedValue(buffer, DOMAIN, String.join(" ", domains)); } buffer.append(','); Parser.appendQuotedValue(buffer, NONCE, nonce); if(opaque!=null){ buffer.append(','); Parser.appendQuotedValue(buffer, OPAQUE, opaque); } if(stale){ buffer.append(','); buffer.append(STALE).append("=true"); } if(algorithm!=null){ buffer.append(','); buffer.append(ALGORITHM).append('=').append(algorithm); } if(qops!=null && !qops.isEmpty()){ buffer.append(','); Parser.appendQuotedValue(buffer, QOP, String.join(",", qops)); } return buffer.toString(); } }