blob: a76a499bd42dcd82b58984c88be5019b048f7e93 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2002-2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.wst.wsi.internal.core.util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.util.Locale;
import com.ibm.icu.util.StringTokenizer;
import sun.net.www.MessageHeader;
import com.ibm.icu.text.SimpleDateFormat;
/**
* This class checks HTTP request headers about RFC 2616.
*
* @author Volodin
*/
public class HttpHeadersValidator
{
private static final String HEADER_ALLOW = "Allow";
private static final String HEADER_CONTENT_TYPE = "Content-Type";
private static final String HEADER_CONTENT_ENCODING = "Content-Encoding";
private static final String HEADER_CONTENT_LANGUAGE = "Content-Language";
private static final String HEADER_CONTENT_LENGHT = "Content-Length";
private static final String HEADER_CONTENT_LOCATION = "Content-Location";
private static final String HEADER_CONTENT_RANGE = "Content-Range";
private static final String HEADER_EXPIRES = "Expires";
private static final String HEADER_LAST_MODIFIED = "Last-Modified";
private static final String HEADER_CACHE_CONTROL = "Cache-Control";
private static final String HEADER_CONNECTION = "Connection";
private static final String HEADER_DATE = "Date";
private static final String HEADER_PRAGMA = "Pragma";
private static final String HEADER_TRAILER = "Trailer";
private static final String HEADER_TRANSFER_ENCODING = "Transfer-Encoding";
private static final String HEADER_UPGRADE = "Upgrade";
private static final String HEADER_VIA = "Via";
private static final String HEADER_WARNING = "Warning";
private static final String HEADER_ACCEPT = "Accept";
private static final String HEADER_ACCEPT_CHARSET = "Accept-Charset";
private static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
private static final String HEADER_ACCEPT_LANGUAGE = "Accept-Language";
private static final String HEADER_AUTHORIZATION = "Authorization";
private static final String HEADER_EXPECT = "Expect";
private static final String HEADER_FROM = "From";
private static final String HEADER_HOST = "Host";
private static final String HEADER_IF_MATCH = "If-Match";
private static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since";
private static final String HEADER_IF_NONE_MATCH = "If-None-Match";
private static final String HEADER_IF_RANGE = "If-Range";
private static final String HEADER_IF_UNMODIFIED_SINCE =
"If-Unmodified-Since";
private static final String HEADER_MAX_FORWARDS = "Max-Forwards";
private static final String HEADER_PROXY_AUTHORIZATION =
"Proxy-Authorization";
private static final String HEADER_RANGE = "Range";
private static final String HEADER_REFERER = "Referer";
private static final String HEADER_TE = "TE";
private static final String HEADER_USER_AGENT = "User-Agent";
/**
* This class checks e-mail string about RFC 822.
*/
public static class MailboxValidator
{
private static final char[] SPECIAL =
{ '(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '.', '[', ']' };
/**
* Validates e-mail string.
* @param mailbox e-mail string
* @return boolean true if e-mail string is conform to RFC 822, false otherwise.
*/
public static boolean validateMailbox(String mailbox)
{
if (!isFullAddr(mailbox) && !isShortAddr(mailbox))
return false;
return true;
}
/**
* Method isSimpleAddr.
* @param mailbox
* @return boolean
*/
private static boolean isShortAddr(String mailbox)
{
int indexAt = mailbox.indexOf('@');
if (indexAt == -1)
return false;
if (!isLocalPart(mailbox.substring(0, indexAt))
|| !isDomain(mailbox.substring(indexAt + 1)))
return false;
return true;
}
/**
* Method isDomaim.
* @param string
* return boolean
*/
private static boolean isDomain(String string)
{
if (string.trim().length() == 0)
return false;
StringTokenizer st = new StringTokenizer(string, ".");
while (st.hasMoreTokens())
{
String subDomain = st.nextToken();
if (!isAtom(subDomain) && !isDomainLiteral(subDomain))
return false;
}
return true;
}
/**
* Method isDomainLiteral.
* @param subDomain
* @return boolean
*/
private static boolean isDomainLiteral(String subDomain)
{
if (getLastDomainLiteral(subDomain, 0) == subDomain.length())
{
return true;
}
else
{
return false;
}
}
private static int getLastDomainLiteral(String str, int startIndex)
{
int index = startIndex;
//int newIndex = 0;
// if end if the string
if (startIndex == str.length())
return startIndex;
// if the begin is not '['
if (str.charAt(index) != '[')
return startIndex;
index++;
while (true)
{
index = getLastDtext(str, index);
if (index == str.length())
return startIndex;
if (BasicRules.isQuotedPair(str, index - 1))
{
index++;
if (index == str.length())
return startIndex;
}
else
break;
}
// if the end is not ']'
if (str.charAt(index) != ']')
return startIndex;
index++;
return index;
}
private static int getLastDtext(String str, int startIndex)
{
if (str.length() == startIndex)
return startIndex;
int i = 0;
for (; i < str.length(); i++)
{
char ch = str.charAt(i);
i = BasicRules.getLastIndexLWS(str, i);
if (!BasicRules.isCHAR(ch)
|| str.charAt(i) == '['
|| str.charAt(i) == ']'
|| str.charAt(i) == '\\'
|| str.charAt(i) == BasicRules.CR)
{
return i + 1;
}
}
return i + 1;
}
/**
* Method isLocalPart.
* @param string
* @return boolean
*/
private static boolean isLocalPart(String string)
{
if (string.trim().length() == 0)
return false;
StringTokenizer st = new StringTokenizer(string, ".");
while (st.hasMoreTokens())
{
if (!isWord(st.nextToken()))
return false;
}
return true;
}
/**
* Method isWord.
* @param string
* @return boolean
*/
private static boolean isWord(String string)
{
if (!isAtom(string) && !isQuotedString(string))
return false;
return true;
}
/**
* Method isAtom.
* @param string
* @return boolean
*/
private static boolean isAtom(String string)
{
if (string.length() == 0)
return false;
for (int i = 0; i < string.length(); i++)
{
if (!BasicRules.isCHAR(string.charAt(i))
|| isSpecial(string.charAt(i))
|| string.charAt(i) == ' '
|| BasicRules.isCTL(string.charAt(i)))
{
return false;
}
}
return true;
}
/**
* Method isSpecial.
* @param c
* @return boolean
*/
private static boolean isSpecial(char ch)
{
for (int index = 0; index < SPECIAL.length; index++)
{
if (ch == SPECIAL[index])
return true;
}
return false;
}
/**
* Method isFullAddr.
* @param mailbox
* @return boolean
*/
private static boolean isFullAddr(String mailbox)
{
if (mailbox.length() == 0)
return false;
int idxLT = mailbox.indexOf('<');
if (idxLT == -1)
return false;
//is phrase
String phrase = mailbox.substring(0, idxLT);
StringTokenizer st = new StringTokenizer(phrase, " ");
if (st.countTokens() == 0)
return false;
while (st.hasMoreTokens())
{
if (!isWord(st.nextToken()))
return false;
}
if (phrase.charAt(phrase.length() - 1) != BasicRules.SP)
{
return false;
}
//is route-addr
String routeAddr = mailbox.substring(idxLT + 1);
// is route
int idxTwoSpot = routeAddr.indexOf(':');
if (idxTwoSpot != -1)
{
StringTokenizer stRouteAddr =
new StringTokenizer(routeAddr.substring(0, idxTwoSpot), ",");
if (!stRouteAddr.hasMoreTokens())
return false;
while (stRouteAddr.hasMoreTokens())
{
if (!isDomain(stRouteAddr.nextToken()))
return false;
}
}
//is addr spec
int idxGT = routeAddr.indexOf('>');
if (idxGT == -1 || idxGT != (routeAddr.length() - 1))
return false;
if (!isShortAddr(routeAddr.substring(idxTwoSpot + 1, idxGT)))
return false;
return true;
}
}
/**
* Validates HTTP request headers.
* @param headers HTTP request headers
* @return boolean true if all HTTP headers string is conform to RFC 2616, false otherwise.
*/
public static boolean validateHttpRequestHeaders(String headers)
{
MessageHeader mh = new MessageHeader();
try
{
mh.parseHeader(new ByteArrayInputStream(headers.getBytes()));
}
catch (IOException e)
{
return false;
}
String header = null;
String value = null;
header = mh.getKey(0);
if (header != null)
return false;
value = mh.getValue(0);
if (value == null)
return false;
//method
StringTokenizer st = new StringTokenizer(value, " ");
if (!st.hasMoreElements())
return false;
String str = st.nextToken();
if (!isToken(str))
return false;
if (!st.hasMoreElements())
return false;
str = st.nextToken();
if (!isURI(str) && !str.equals("*"))
return false;
if (!st.hasMoreElements())
return false;
str = st.nextToken();
if (!isHTTPVersion(str))
return false;
int i = 1;
try
{
while ((header = mh.getKey(i)) != null)
{
value = mh.getValue(i);
i++;
// is message-header token
if (!isToken(header))
return false;
//---- entity-headers
if (header.equals(HEADER_ALLOW))
{
if (!isValidAllow(value))
return false;
else
continue;
}
if (header.equals(HEADER_CONTENT_TYPE))
{
if (!isMediaType(value))
return false;
else
continue;
}
if (header.equals(HEADER_CONTENT_ENCODING))
{
if (!isToken(value))
return false;
else
continue;
}
if (header.equals(HEADER_CONTENT_LANGUAGE))
{
if (!isLanguageTag(value))
return false;
else
continue;
}
if (header.equals(HEADER_CONTENT_LENGHT))
{
if (!isDidgit(value))
return false;
else
continue;
}
if (header.equals(HEADER_CONTENT_LOCATION))
{
if (!isURI(value))
return false;
else
continue;
}
if (header.equals(HEADER_CONTENT_RANGE))
{
if (!isValidContentRange(value))
return false;
else
continue;
}
if (header.equals(HEADER_EXPIRES)
|| header.equals(HEADER_LAST_MODIFIED))
{
if (!isHTTPDate(value))
return false;
else
continue;
}
//---- general-headers
if (header.equals(HEADER_CACHE_CONTROL))
{
if (!isValidCacheControl(value))
return false;
continue;
//return true;
}
if (header.equals(HEADER_CONNECTION))
{
if (!isToken(value))
return false;
else
continue;
}
if (header.equals(HEADER_DATE))
{
if (!isHTTPDate(value))
return false;
else
continue;
}
if (header.equals(HEADER_PRAGMA))
{
if (!isPragmaDerective(value))
return false;
else
continue;
}
if (header.equals(HEADER_TRAILER))
{
if (!isToken(value))
return false;
else
continue;
}
if (header.equals(HEADER_TRANSFER_ENCODING))
{
if (!isTransferCoding(value))
return false;
else
continue;
}
if (header.equals(HEADER_UPGRADE))
{
if (!isValidUpgrade(value))
return false;
else
continue;
}
if (header.equals(HEADER_VIA))
{
if (!isValidVia(value))
return false;
else
continue;
}
if (header.equals(HEADER_WARNING))
{
if (!isValidWarning(value))
return false;
else
continue;
}
if (header.equals(HEADER_ACCEPT))
{
if (!isValidAccept(value))
return false;
else
continue;
}
if (header.equals(HEADER_ACCEPT_CHARSET))
{
if (!isValidAcceptCharSet(value))
return false;
else
continue;
}
if (header.equals(HEADER_ACCEPT_ENCODING))
{
if (!isValidAcceptEncoding(value))
return false;
else
continue;
}
if (header.equals(HEADER_ACCEPT_LANGUAGE))
{
if (!isValidAcceptLanguage(value))
return false;
else
continue;
}
if (header.equals(HEADER_AUTHORIZATION)
|| header.equals(HEADER_PROXY_AUTHORIZATION))
{
if (!isCredentials(value))
return false;
else
continue;
}
if (header.equals(HEADER_EXPECT))
{
if (!isExpectation(value))
return false;
else
continue;
}
if (header.equals(HEADER_FROM))
{
if (!MailboxValidator.validateMailbox(value))
return false;
else
continue;
}
if (header.equals(HEADER_IF_MATCH)
|| header.equals(HEADER_IF_NONE_MATCH))
{
if (!isValidIfMatch(value))
return false;
else
continue;
}
if (header.equals(HEADER_IF_RANGE))
{
if (!isEntityTag(value) && !isHTTPDate(value))
return false;
else
continue;
}
//---
if (header.equals(HEADER_IF_MODIFIED_SINCE))
{
if (!isHTTPDate(value))
return false;
else
continue;
}
if (header.equals(HEADER_IF_UNMODIFIED_SINCE))
{
if (!isHTTPDate(value))
return false;
else
continue;
}
if (header.equals(HEADER_MAX_FORWARDS))
{
if (!isDidgit(value))
return false;
else
continue;
}
if (header.equals(HEADER_USER_AGENT))
{
if (!isValidUserAgent(value))
return false;
else
continue;
}
if (header.equals(HEADER_TE))
{
if (!isValidTE(value))
return false;
else
continue;
}
if (header.equals(HEADER_RANGE))
{
if (!isRange(value))
return false;
else
continue;
}
if (header.equals(HEADER_HOST))
{
if (!isHost(value))
return false;
else
continue;
}
if (header.equals(HEADER_REFERER))
{
if (!isURI(value))
return false;
else
continue;
}
}
}
catch (Exception e)
{
return false;
}
return true;
}
/**
* Method isValidIfMatch.
* @param value
* @return boolean
*/
private static boolean isValidIfMatch(String value)
{
if (value.trim().length() == 0)
return true;
if ("*".equals(value.trim()))
return true;
StringTokenizer st = new StringTokenizer(value, ",");
while (st.hasMoreElements())
{
String str = st.nextToken().trim();
if (!isEntityTag(str))
return false;
}
return true;
}
/**
* Method isValidUpgrade.
* @param value
* @return boolean
*/
private static boolean isValidUpgrade(String value)
{
if (value.trim().length() == 0)
return false;
StringTokenizer st = new StringTokenizer(value, ",");
while (st.hasMoreElements())
{
String str = st.nextToken().trim();
if (!isProduct(str))
return false;
}
return true;
}
/**
* Method isValidCacheControl.
* @param value
* @return boolean
*/
private static boolean isValidCacheControl(String value)
{
if (value.trim().length() == 0)
return false;
StringTokenizer st = new StringTokenizer(value, ",");
while (st.hasMoreElements())
{
String str = st.nextToken().trim();
int index = str.indexOf('=');
if (index == -1)
{
}
else
{
if (!isToken(str.substring(0, index)))
return false;
String strAfterEq = str.substring(index + 1);
if (!isToken(strAfterEq) && !isQuotedString(strAfterEq))
{
return false;
}
}
}
return true;
}
/**
* Method isHTTPVersion.
* @param str
* @return boolean
*/
private static boolean isHTTPVersion(String str)
{
if (!str.startsWith("HTTP/"))
return false;
int idx = "HTTP/".length();
int idx2 = str.indexOf(".");
// 1*DIGIT
String s = str.substring(idx, idx2);
if (!isDidgit(s))
return false;
s = str.substring(idx2 + 1);
if (!isDidgit(s))
return false;
return true;
}
/**
* Method isValidWarning.
* @param value
* @return boolean
*/
private static boolean isValidWarning(String value)
{
if (value.length() == 0)
return false;
value = value.trim();
StringTokenizer st = new StringTokenizer(value, " ");
String str = st.nextToken();
if (str.length() > 3 || !isDidgit(str))
return false;
if (!st.hasMoreTokens())
return false;
str = st.nextToken();
if (!isHost(str) && !isToken(str))
return false;
//if(!st.hasMoreTokens()) return false;
str = st.nextToken("").trim();
//???
int lastQuotedString = BasicRules.getLastQuotedString(str, 0);
if (lastQuotedString == str.length())
{
return true;
}
else
{
String data = str.substring(lastQuotedString);
if (data.charAt(data.length()) != '\"')
return false;
if (str.charAt(0) != '\"')
return false;
if (!isHTTPDate(str.substring(1, data.length() - 1)))
return false;
}
return true;
}
/**
* Method isValidVia.
* @param value
* @return boolean
*/
private static boolean isValidVia(String value)
{
if (value.trim().length() == 0)
return false;
StringTokenizer st = new StringTokenizer(value, ",");
while (st.hasMoreElements())
{
String str = st.nextToken().trim();
StringTokenizer st2 = new StringTokenizer(str, " ");
// protocol/version
str = st2.nextToken();
int idx = str.indexOf("/");
if (idx == -1)
{
if (!isToken(str))
return false;
}
else
{
if (!isToken(str.substring(0, idx))
|| !isToken(str.substring(idx + 1)))
return false;
}
//host
str = st2.nextToken();
if (!isHost(str) && !isToken(str))
return false;
//comment
if (st2.hasMoreTokens())
{
str = st2.nextToken("");
if (!isComment(str.trim()))
return false;
}
}
return true;
}
/**
* Method isHost.
* @param value
* @return boolean
*/
private static boolean isHost(String value)
{
try
{
new URL("http://" + value);
}
catch (MalformedURLException e)
{
return false;
}
return true;
}
/**
* Method isValidAllow.
* @param value
* @return boolean
*/
private static boolean isValidAllow(String value)
{
if (value.trim().length() == 0)
return true;
StringTokenizer st = new StringTokenizer(value, ",");
while (st.hasMoreElements())
{
String str = st.nextToken().trim();
if (!isToken(str))
return false;
}
return true;
}
/**
* Method isValidContentRange.
* @param value
* @return boolean
*/
private static boolean isValidContentRange(String value)
{
if (value.length() == 0)
return false;
if (!value.startsWith("bytes"))
return false;
String str = value.substring("bytes".length()).trim();
int idx = str.indexOf("/");
if (idx == -1)
return false;
String byteRange = str.substring(0, idx);
int idx2 = byteRange.indexOf("-");
if (idx2 == -1)
{
if (!byteRange.equals("*"))
return false;
}
else
{
if (!isDidgit(byteRange.substring(0, idx2))
|| !isDidgit(byteRange.substring(idx2 + 1)))
return false;
}
if (!isDidgit(str.substring(idx + 1))
&& !str.substring(idx + 1).equals("*"))
return false;
return true;
}
/**
* Method isRange.
* @param value
* @return boolean
*/
private static boolean isRange(String value)
{
if (value.length() == 0)
return false;
if (!value.startsWith("bytes="))
return false;
String strByteRange = value.substring("bytes=".length());
StringTokenizer st = new StringTokenizer(strByteRange, ",");
while (st.hasMoreElements())
{
String str = st.nextToken();
int idx = str.indexOf("-");
if (idx == -1)
return false;
if (idx == 0)
{
if (!isDidgit(str.substring(1)))
return false;
}
else
{
if (idx == (str.length() - 1))
{
if (!isDidgit(str.substring(0, str.length() - 1)))
return false;
}
else
{
if (!isDidgit(str.substring(0, idx))
|| !isDidgit(str.substring(idx + 1)))
return false;
}
}
}
return true;
}
/**
* Method isValidTE.
* @param value
* @return boolean
*/
private static boolean isValidTE(String value)
{
if (value.trim().length() == 0)
return true;
StringTokenizer st = new StringTokenizer(value, ",");
while (st.hasMoreElements())
{
String str = st.nextToken().trim();
if (st.equals("trailers"))
return true;
int idx = str.indexOf(";");
if (idx == -1)
{
if (!isLanguageRange(str))
return false;
}
else
{
String _1 = str.substring(0, idx).trim();
String _2 = str.substring(idx + 1).trim();
if (!isLanguageRange(_1))
return false;
if (!isQAndQValue(_2))
return false;
}
}
return true;
}
/**
* Method isValidUserAgent.
* @param value
* @return boolean
*/
private static boolean isValidUserAgent(String value)
{
if (value.length() == 0)
return false;
StringTokenizer st = new StringTokenizer(value, " ");
while (st.hasMoreElements())
{
String str = st.nextToken();
if (!isProduct(str) && !isComment(str))
return false;
}
return true;
}
/**
* Method isComment.
* @param str
* @return boolean
*/
private static boolean isComment(String str)
{
if (BasicRules.getLastComment(str, 0) != str.length())
return false;
return true;
}
/**
* Method isValidAcceptLanguage.
* @param value
* @return boolean
*/
private static boolean isValidAcceptLanguage(String value)
{
if (value.trim().length() == 0)
return false;
StringTokenizer st = new StringTokenizer(value, ",");
while (st.hasMoreElements())
{
String str = st.nextToken().trim();
int idx = str.indexOf(";");
if (idx == -1)
{
if (!isToken(str))
return false;
}
else
{
String _1 = str.substring(0, idx).trim();
String _2 = str.substring(idx + 1).trim();
if (!isToken(_1))
return false;
if (!isAcceptParams(_2))
return false;
}
}
return true;
}
/**
* Method isLanguageRange.
* @param str
* @return boolean
*/
private static boolean isLanguageRange(String str)
{
if (str.trim().equals("*"))
return true;
StringTokenizer st = new StringTokenizer(str, "-");
while (st.hasMoreElements())
{
if (!is8ALPHA(st.nextToken()))
return false;
}
return true;
}
/**
* Method isValidAcceptEncoding.
* @param value
* @return boolean
*/
private static boolean isValidAcceptEncoding(String value)
{
if (value.trim().length() == 0)
return false;
StringTokenizer st = new StringTokenizer(value, ",");
while (st.hasMoreElements())
{
String str = st.nextToken().trim();
int idx = str.indexOf(";");
if (idx == -1)
{
if (!isToken(str) && !str.equals("*"))
return false;
}
else
{
String _1 = str.substring(0, idx).trim();
String _2 = str.substring(idx + 1).trim();
if ((!isToken(_1) && !_1.equals("*")))
return false;
if (!isQAndQValue(_2))
return false;
}
}
return true;
}
/**
* Method isValidAcceptCharSet.
* @param value
* @return boolean
*/
private static boolean isValidAcceptCharSet(String value)
{
if (value.trim().length() == 0)
return false;
StringTokenizer st = new StringTokenizer(value, ",");
while (st.hasMoreElements())
{
String str = st.nextToken().trim();
int idx = str.indexOf(";");
if (idx == -1)
{
if (!isToken(str) && !str.equals("*"))
return false;
}
else
{
String _1 = str.substring(0, idx).trim();
String _2 = str.substring(idx + 1).trim();
if ((!isToken(_1) && !_1.equals("*")))
return false;
if (!isQAndQValue(_2))
return false;
}
}
return true;
}
/**
* Method isValidAccept.
* @param value
* @return boolean
*/
private static boolean isValidAccept(String value)
{
if (value.trim().length() == 0)
return true;
StringTokenizer st = new StringTokenizer(value, ",");
while (st.hasMoreElements())
{
String str = st.nextToken().trim();
int idx = str.indexOf(";");
if (idx == -1)
{
if (!isMediaRange(str))
return false;
}
else
{
if (!isMediaRange(str.substring(0, idx).trim())
|| !isAcceptParams(str.substring(idx + 1).trim()))
return false;
}
}
return true;
}
/**
* Method isAcceptParams.
* @param string
* @return boolean
*/
private static boolean isAcceptParams(String string)
{
if (string.trim().length() == 0)
return false;
StringTokenizer st = new StringTokenizer(string, ";");
String str = st.nextToken();
int idx = str.indexOf("=");
if (idx == -1)
{
if (str.equals("q") || !isToken(str))
return false;
}
else
{
if (str.substring(0, idx).equals("q"))
{
if (!isQValue(str.substring(idx + 1)))
return false;
}
else
{
if (!isParameterWithoutValue(str))
return false;
}
}
while (st.hasMoreElements())
{
str = st.nextToken();
if (!isParameterWithoutValue(str))
return false;
}
return true;
}
/**
* Method isQAndQValue.
* @param str
* @return boolean
*/
private static boolean isQAndQValue(String str)
{
str = str.trim();
if (!str.trim().startsWith("q="))
return false;
if (!isQValue(str.substring("q=".length())))
return false;
return true;
}
/**
* Method isQValue.
* @param string
* @return boolean
*/
private static boolean isQValue(String string)
{
if (string.trim().length() == 0)
return false;
int idx = string.indexOf(".");
if (idx == -1)
{
if (!"0".equals(string) && !"1".equals(string))
return false;
}
else
{
String strDig = string.substring(idx + 1);
if (strDig.length() > 3)
return false;
if (string.substring(0, idx).equals("0"))
{
if (!isDidgit(strDig))
return false;
}
else
{
if (!string.substring(0, idx).equals("1"))
return false;
for (int i = 0; i < strDig.length(); i++)
{
if (strDig.charAt(i) != '0')
return false;
}
}
}
return true;
}
/**
* Method isMediaRange.
* @param str
* @return boolean
*/
private static boolean isMediaRange(String str)
{
if (str.trim().length() == 0)
return false;
int idx = str.indexOf("/");
if (idx == -1)
return false;
if (!isToken(str.substring(0, idx)) && !str.substring(0, idx).equals("*"))
return false;
if (!isToken(str.substring(idx + 1))
&& !str.substring(idx + 1).equals("*"))
return false;
return true;
}
/**
* Method isEntityTag.
* @param value
* @return boolean
*/
private static boolean isEntityTag(String value)
{
int idx = 0;
if (value.startsWith("W/"))
idx = 2;
if (!isQuotedString(value.substring(idx)))
return false;
return true;
}
/**
* Method isExpectation.
* @param value
* @return boolean
*/
private static boolean isExpectation(String value)
{
if (value.equals("100-continue"))
return true;
StringTokenizer st = new StringTokenizer(value, ";");
while (st.hasMoreElements())
{
if (!isParameterWithoutValue(st.nextToken()))
return false;
}
return true;
}
/**
* Method isCredentials.
* @param value
* @return boolean
*/
private static boolean isCredentials(String value)
{
StringTokenizer st = new StringTokenizer(value, " ");
if (!isToken(st.nextToken()))
return false;
while (st.hasMoreElements())
{
String param = st.nextToken(",");
if (!isParameter(param))
return false;
}
return true;
}
/**
* Method isProduct.
* @param value
* @return boolean
*/
private static boolean isProduct(String value)
{
int idx = value.indexOf("/");
if (idx == -1)
{
if (!isToken(value))
return false;
}
else
{
if (!isToken(value.substring(0, idx))
|| !isToken(value.substring(idx + 1)))
return false;
}
return true;
}
/**
* Method isTransferCoding.
* @param value
* @return boolean
*/
private static boolean isTransferCoding(String value)
{
if (value.equals("chunked"))
{
return true;
}
else
{
StringTokenizer st = new StringTokenizer(value, ";");
if (!isToken(st.nextToken()))
return false;
while (st.hasMoreElements())
{
if (!isParameter(st.nextToken()))
return false;
}
}
return true;
}
/**
* Method isParameter.
* @param string
* @return boolean
*/
private static boolean isParameter(String string)
{
// check parameter
int idx = string.indexOf("=");
if (!isToken(string.substring(0, idx)))
return false;
String parValue = string.substring(idx + 1);
if (!isToken(parValue) && !isQuotedString(parValue))
return false;
return true;
}
/**
* Method isParameterWithoutValue.
* @param string
* @return boolean
*/
private static boolean isParameterWithoutValue(String string)
{
// check parameter
int idx = string.indexOf("=");
if (idx != -1)
{
if (!isToken(string.substring(0, idx)))
return false;
String parValue = string.substring(idx + 1);
if (!isToken(parValue) && !isQuotedString(parValue))
return false;
}
else
{
if (!isToken(string))
return false;
}
return true;
}
/**
* Method isPragmaDerective.
* @param value
* @return boolean
*/
private static boolean isPragmaDerective(String value)
{
if (value.equals("no-cache"))
return true;
else
{
int idx = value.indexOf("=");
if (idx == -1)
{
if (isToken(value))
return true;
}
else
{
String str = value.substring(idx + 1);
if (isToken(value.substring(0, idx))
&& (isToken(str) || isQuotedString(str)))
return true;
}
}
return true;
}
/**
* Method isHTTPDate.
* @param value
* @return boolean
*/
private static boolean isHTTPDate(String value)
{
String rfc1123_date = "EEE, dd MMM yyyy hh:mm:ss 'GMT'";
String rfc850_date = "EEEE, dd-MMM-yy hh:mm:ss 'GMT'";
String asctime_date = "EEE MMM d hh:mm:ss yyyy";
try
{
SimpleDateFormat sdf = new SimpleDateFormat(rfc1123_date, Locale.US);
if (sdf.parse(value) != null)
return true;
}
catch (ParseException e)
{
}
try
{
SimpleDateFormat sdf = new SimpleDateFormat(rfc850_date, Locale.US);
if (sdf.parse(value) != null)
return true;
}
catch (ParseException e)
{
}
try
{
SimpleDateFormat sdf = new SimpleDateFormat(asctime_date, Locale.US);
if (sdf.parse(value) != null)
return true;
}
catch (ParseException e)
{
}
return false;
}
/**
* Method isURI.
* @param value
* @return boolean
*/
private static boolean isURI(String value)
{
try
{
new URL(value);
}
catch (MalformedURLException e)
{
try
{
new URL("http://localhost" + value);
}
catch (MalformedURLException e2)
{
return false;
}
}
return true;
}
/**
* Method isLanguageTag.
* @param value
* @return boolean
*/
private static boolean isLanguageTag(String value)
{
int idx = value.indexOf("-");
if (idx == -1)
{
return is8ALPHA(value);
}
else
{
if (!is8ALPHA(value.substring(0, idx))
|| !is8ALPHA(value.substring(idx + 1)))
return false;
else
return true;
}
}
/**
* Method is8ALPHA.
* @param string
* @return boolean
*/
private static boolean is8ALPHA(String string)
{
if (string.length() > 8 || !isALPHA(string))
return false;
else
return true;
}
/**
* Method isALPHA.
* @param string
* @return boolean
*/
private static boolean isALPHA(String string)
{
for (int i = 0; i < string.length(); i++)
{
if (!BasicRules.isCHAR(string.charAt(i)))
return false;
}
return true;
}
/**
* Method isDidgit.
* @param value
* @return boolean
*/
private static boolean isDidgit(String value)
{
if (value.length() == 0)
return false;
char[] chs = value.toCharArray();
for (int i = 0; i < chs.length; i++)
{
if (chs[i] < '0' || chs[i] > '9')
return false;
}
return true;
}
/**
* Method isMediaType.
* @param value
* @return boolean
*/
private static boolean isMediaType(String value)
{
StringTokenizer st = new StringTokenizer(value, ";");
String mediaType = st.nextToken();
int idx = mediaType.indexOf("/");
if (!isToken(mediaType.substring(0, idx))
|| !isToken(mediaType.substring(idx + 1)))
{
return false;
}
while (st.hasMoreElements())
{
if (!isParameter(st.nextToken(";").trim()))
return false;
}
return true;
}
/**
* Method isQuotedString.
* @param parValue
* @return boolean
*/
private static boolean isQuotedString(String parValue)
{
if (BasicRules.getLastQuotedString(parValue, 0) != parValue.length())
{
return false;
}
return true;
}
/**
* Method isToken.
* @param value
* @return boolean
*/
private static boolean isToken(String value)
{
return BasicRules.isToken(value);
}
}