下面列出了org.xml.sax.ext.Locator2#org.apache.tomcat.util.buf.B2CConverter 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static B2CConverter createConverter(final Charset charset) throws IOException {
if (SecurityUtil.isPackageProtectionEnabled()) {
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction<B2CConverter>() {
@Override
public B2CConverter run() throws IOException {
return new B2CConverter(charset);
}
});
} catch (PrivilegedActionException ex) {
Exception e = ex.getException();
if (e instanceof IOException) {
throw (IOException) e;
} else {
throw new IOException(e);
}
}
} else {
return new B2CConverter(charset);
}
}
private static Charset getCharset(final String encoding) throws IOException {
if (Globals.IS_SECURITY_ENABLED) {
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction<Charset>() {
@Override
public Charset run() throws IOException {
return B2CConverter.getCharset(encoding);
}
});
} catch (PrivilegedActionException ex) {
Exception e = ex.getException();
if (e instanceof IOException) {
throw (IOException) e;
} else {
throw new IOException(ex);
}
}
} else {
return B2CConverter.getCharset(encoding);
}
}
/**
* Overrides the character encoding used in the body of the response. This
* method must be called prior to writing output using getWriter().
*
* @param characterEncoding The name of character encoding.
*/
public void setCharacterEncoding(String characterEncoding) {
if (isCommitted()) {
return;
}
if (characterEncoding == null) {
return;
}
try {
this.charset = B2CConverter.getCharset(characterEncoding);
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException(e);
}
this.characterEncoding = characterEncoding;
}
private String getWebSocketAccept(String key) throws ServletException {
MessageDigest sha1Helper = sha1Helpers.poll();
if (sha1Helper == null) {
try {
sha1Helper = MessageDigest.getInstance("SHA1");
} catch (NoSuchAlgorithmException e) {
throw new ServletException(e);
}
}
sha1Helper.reset();
sha1Helper.update(key.getBytes(B2CConverter.ISO_8859_1));
String result = Base64.encode(sha1Helper.digest(WS_ACCEPT));
sha1Helpers.add(sha1Helper);
return result;
}
private void doWriteText(CharBuffer buffer, boolean finalFragment)
throws IOException {
CharsetEncoder encoder = B2CConverter.UTF_8.newEncoder();
do {
CoderResult cr = encoder.encode(buffer, bb, true);
if (cr.isError()) {
cr.throwException();
}
bb.flip();
if (buffer.hasRemaining()) {
doWriteBytes(bb, false);
} else {
doWriteBytes(bb, finalFragment);
}
} while (buffer.hasRemaining());
// Reset - bb will be cleared in doWriteBytes()
cb.clear();
}
/**
* Append request parameters from the specified String to the specified
* Map. It is presumed that the specified Map is not accessed from any
* other thread, so no synchronization is performed.
* <p>
* <strong>IMPLEMENTATION NOTE</strong>: URL decoding is performed
* individually on the parsed name and value elements, rather than on
* the entire query string ahead of time, to properly deal with the case
* where the name or value includes an encoded "=" or "&" character
* that would otherwise be interpreted as a delimiter.
*
* @param map Map that accumulates the resulting parameters
* @param data Input string containing request parameters
* @param encoding The encoding to use; encoding must not be null.
* If an unsupported encoding is specified the parameters will not be
* parsed and the map will not be modified
*/
public static void parseParameters(Map<String,String[]> map, String data,
String encoding) {
if ((data != null) && (data.length() > 0)) {
// use the specified encoding to extract bytes out of the
// given string so that the encoding is not lost.
byte[] bytes = null;
try {
bytes = data.getBytes(B2CConverter.getCharset(encoding));
parseParameters(map, bytes, encoding);
} catch (UnsupportedEncodingException uee) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("requestUtil.parseParameters.uee",
encoding), uee);
}
}
}
}
/**
* Decode and return the specified URL-encoded String.
*
* @param str The url-encoded string
* @param enc The encoding to use; if null, the default encoding is used. If
* an unsupported encoding is specified null will be returned
* @param isQuery Is this a query string being processed
* @exception IllegalArgumentException if a '%' character is not followed
* by a valid 2-digit hexadecimal number
*/
public static String URLDecode(String str, String enc, boolean isQuery) {
if (str == null)
return (null);
// use the specified encoding to extract bytes out of the
// given string so that the encoding is not lost. If an
// encoding is not specified, let it use platform default
byte[] bytes = null;
try {
if (enc == null) {
bytes = str.getBytes(Charset.defaultCharset());
} else {
bytes = str.getBytes(B2CConverter.getCharset(enc));
}
} catch (UnsupportedEncodingException uee) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("requestUtil.urlDecode.uee", enc), uee);
}
}
return URLDecode(bytes, enc, isQuery);
}
private void doUtf8BodyTest(String description, int[] input,
String expected) throws Exception {
byte[] bytes = new byte[input.length];
for (int i = 0; i < input.length; i++) {
bytes[i] = (byte) input[i];
}
ByteChunk bc = new ByteChunk();
int rc = postUrl(bytes, "http://localhost:" + getPort() + "/test", bc,
null);
if (expected == null) {
Assert.assertEquals(description, HttpServletResponse.SC_OK, rc);
Assert.assertEquals(description, "FAILED", bc.toString());
} else if (expected.length() == 0) {
Assert.assertNull(description, bc.toString());
} else {
bc.setCharset(B2CConverter.UTF_8);
Assert.assertEquals(description, expected, bc.toString());
}
}
private void testInvalidPostWithRequestParams() throws Exception {
String validBody = Constants.CSRF_REST_NONCE_HEADER_NAME + "=" + validNonce;
String invalidbody1 = Constants.CSRF_REST_NONCE_HEADER_NAME + "=" + INVALID_NONCE_1;
String invalidbody2 = Constants.CSRF_REST_NONCE_HEADER_NAME + "="
+ Constants.CSRF_REST_NONCE_HEADER_FETCH_VALUE;
doTest(METHOD_POST, REMOVE_ALL_CUSTOMERS, CREDENTIALS,
validBody.getBytes(B2CConverter.ISO_8859_1), USE_COOKIES,
HttpServletResponse.SC_FORBIDDEN, null, null, true,
Constants.CSRF_REST_NONCE_HEADER_REQUIRED_VALUE);
doTest(METHOD_POST, REMOVE_CUSTOMER, CREDENTIALS,
invalidbody1.getBytes(B2CConverter.ISO_8859_1), USE_COOKIES,
HttpServletResponse.SC_FORBIDDEN, null, null, true,
Constants.CSRF_REST_NONCE_HEADER_REQUIRED_VALUE);
doTest(METHOD_POST, REMOVE_CUSTOMER, CREDENTIALS,
invalidbody2.getBytes(B2CConverter.ISO_8859_1), USE_COOKIES,
HttpServletResponse.SC_FORBIDDEN, null, null, true,
Constants.CSRF_REST_NONCE_HEADER_REQUIRED_VALUE);
}
private String getWebSocketAccept(String key) throws ServletException {
MessageDigest sha1Helper = sha1Helpers.poll();
if (sha1Helper == null) {
try {
sha1Helper = MessageDigest.getInstance("SHA1");
} catch (NoSuchAlgorithmException e) {
throw new ServletException(e);
}
}
sha1Helper.reset();
sha1Helper.update(key.getBytes(B2CConverter.ISO_8859_1));
String result = Base64.encode(sha1Helper.digest(WS_ACCEPT));
sha1Helpers.add(sha1Helper);
return result;
}
private void doWriteText(CharBuffer buffer, boolean finalFragment)
throws IOException {
CharsetEncoder encoder = B2CConverter.UTF_8.newEncoder();
do {
CoderResult cr = encoder.encode(buffer, bb, true);
if (cr.isError()) {
cr.throwException();
}
bb.flip();
if (buffer.hasRemaining()) {
doWriteBytes(bb, false);
} else {
doWriteBytes(bb, finalFragment);
}
} while (buffer.hasRemaining());
// Reset - bb will be cleared in doWriteBytes()
cb.clear();
}
/**
* Append request parameters from the specified String to the specified
* Map. It is presumed that the specified Map is not accessed from any
* other thread, so no synchronization is performed.
* <p>
* <strong>IMPLEMENTATION NOTE</strong>: URL decoding is performed
* individually on the parsed name and value elements, rather than on
* the entire query string ahead of time, to properly deal with the case
* where the name or value includes an encoded "=" or "&" character
* that would otherwise be interpreted as a delimiter.
*
* @param map Map that accumulates the resulting parameters
* @param data Input string containing request parameters
* @param encoding The encoding to use; encoding must not be null.
* If an unsupported encoding is specified the parameters will not be
* parsed and the map will not be modified
*/
public static void parseParameters(Map<String,String[]> map, String data,
String encoding) {
if ((data != null) && (data.length() > 0)) {
// use the specified encoding to extract bytes out of the
// given string so that the encoding is not lost.
byte[] bytes = null;
try {
bytes = data.getBytes(B2CConverter.getCharset(encoding));
parseParameters(map, bytes, encoding);
} catch (UnsupportedEncodingException uee) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("requestUtil.parseParameters.uee",
encoding), uee);
}
}
}
}
/**
* Decode and return the specified URL-encoded String.
*
* @param str The url-encoded string
* @param enc The encoding to use; if null, the default encoding is used. If
* an unsupported encoding is specified null will be returned
* @param isQuery Is this a query string being processed
* @exception IllegalArgumentException if a '%' character is not followed
* by a valid 2-digit hexadecimal number
*/
public static String URLDecode(String str, String enc, boolean isQuery) {
if (str == null)
return (null);
// use the specified encoding to extract bytes out of the
// given string so that the encoding is not lost. If an
// encoding is not specified, let it use platform default
byte[] bytes = null;
try {
if (enc == null) {
bytes = str.getBytes(Charset.defaultCharset());
} else {
bytes = str.getBytes(B2CConverter.getCharset(enc));
}
} catch (UnsupportedEncodingException uee) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("requestUtil.urlDecode.uee", enc), uee);
}
}
return URLDecode(bytes, enc, isQuery);
}
private void doUtf8BodyTest(String description, int[] input,
String expected) throws Exception {
byte[] bytes = new byte[input.length];
for (int i = 0; i < input.length; i++) {
bytes[i] = (byte) input[i];
}
ByteChunk bc = new ByteChunk();
int rc = postUrl(bytes, "http://localhost:" + getPort() + "/test", bc,
null);
if (expected == null) {
Assert.assertEquals(description, HttpServletResponse.SC_OK, rc);
Assert.assertEquals(description, "FAILED", bc.toString());
} else if (expected.length() == 0) {
Assert.assertNull(description, bc.toString());
} else {
bc.setCharset(B2CConverter.UTF_8);
Assert.assertEquals(description, expected, bc.toString());
}
}
public void checkConverter() throws IOException {
if (conv != null) {
return;
}
Charset charset = null;
if (coyoteRequest != null) {
charset = coyoteRequest.getCharset();
}
if (charset == null) {
if (enc == null) {
charset = org.apache.coyote.Constants.DEFAULT_BODY_CHARSET;
} else {
charset = B2CConverter.getCharset(enc);
}
}
SynchronizedStack<B2CConverter> stack = encoders.get(charset);
if (stack == null) {
stack = new SynchronizedStack<>();
encoders.putIfAbsent(charset, stack);
stack = encoders.get(charset);
}
conv = stack.pop();
if (conv == null) {
conv = createConverter(charset);
}
}
/**
* Set the URI encoding to be used for the URI.
*
* @param URIEncoding The new URI character encoding.
*/
public void setURIEncoding(String URIEncoding) {
try {
uriCharset = B2CConverter.getCharset(URIEncoding);
} catch (UnsupportedEncodingException e) {
log.warn(sm.getString("coyoteConnector.invalidEncoding",
URIEncoding, uriCharset.name()), e);
}
setProperty("uRIEncoding", URIEncoding);
}
/**
* Overrides the name of the character encoding used in the body of
* this request. This method must be called prior to reading request
* parameters or reading input using <code>getReader()</code>.
*
* @param enc The character encoding to be used
*
* @exception UnsupportedEncodingException if the specified encoding
* is not supported
*
* @since Servlet 2.3
*/
@Override
public void setCharacterEncoding(String enc) throws UnsupportedEncodingException {
if (usingReader) {
return;
}
// Confirm that the encoding name is valid
Charset charset = B2CConverter.getCharset(enc);
// Save the validated encoding
coyoteRequest.setCharset(charset);
}
/**
* Open the new log file for the date specified by <code>dateStamp</code>.
*/
protected synchronized void open() {
// Open the current log file
// If no rotate - no need for dateStamp in fileName
File pathname = getLogFile(rotatable && !renameOnRotate);
Charset charset = null;
if (encoding != null) {
try {
charset = B2CConverter.getCharset(encoding);
} catch (UnsupportedEncodingException ex) {
log.error(sm.getString(
"accessLogValve.unsupportedEncoding", encoding), ex);
}
}
if (charset == null) {
charset = StandardCharsets.ISO_8859_1;
}
try {
writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(pathname, true), charset), 128000),
false);
currentLogFile = pathname;
} catch (IOException e) {
writer = null;
currentLogFile = null;
log.error(sm.getString("accessLogValve.openFail", pathname), e);
}
// Rotating a log file will always trigger a new file to be opened so
// when a new file is opened, check to see if any old files need to be
// removed.
checkForOldLogs = true;
}
public void setEncoding(String encodingName) {
if (encodingName == null) {
encoding = StandardCharsets.UTF_8;
} else {
try {
this.encoding = B2CConverter.getCharset(encodingName);
} catch (UnsupportedEncodingException e) {
log.warn(sm.getString("mdCredentialHandler.unknownEncoding",
encodingName, encoding.name()));
}
}
}
private Charset getDigestCharset() throws UnsupportedEncodingException {
String charset = getDigestEncoding();
if (charset == null) {
return StandardCharsets.ISO_8859_1;
} else {
return B2CConverter.getCharset(charset);
}
}
/**
* URL encodes the provided path using the given encoding.
*
* @param path The path to encode
* @param encoding The encoding to use to convert the path to bytes
*
* @return The encoded path
*
* @deprecated This will be removed in Tomcat 9.0.x
*/
@Deprecated
public String encode(String path, String encoding) {
Charset charset;
try {
charset = B2CConverter.getCharset(encoding);
} catch (UnsupportedEncodingException e) {
charset = Charset.defaultCharset();
}
return encode(path, charset);
}
/**
* Get the character encoding used for this request.
*
* @return The value set via {@link #setCharacterEncoding(String)} or if no
* call has been made to that method try to obtain if from the
* content type.
*
* @throws UnsupportedEncodingException If the user agent has specified an
* invalid character encoding
*/
public Charset getCharset() throws UnsupportedEncodingException {
if (charset == null) {
getCharacterEncoding();
if (characterEncoding != null) {
charset = B2CConverter.getCharset(characterEncoding);
}
}
return charset;
}
private Charset getCharset(String encoding, Charset defaultCharset) {
if (encoding == null) {
return defaultCharset;
}
try {
return B2CConverter.getCharset(encoding);
} catch (UnsupportedEncodingException e) {
return defaultCharset;
}
}
/**
* Process notification of the beginning of the document being reached.
*
* @exception SAXException if a parsing error is to be reported
*/
@SuppressWarnings("deprecation")
@Override
public void startDocument() throws SAXException {
if (saxLog.isDebugEnabled()) {
saxLog.debug("startDocument()");
}
if (locator instanceof Locator2) {
if (root instanceof DocumentProperties.Charset) {
String enc = ((Locator2) locator).getEncoding();
if (enc != null) {
try {
((DocumentProperties.Charset) root).setCharset(B2CConverter.getCharset(enc));
} catch (UnsupportedEncodingException e) {
log.warn(sm.getString("disgester.encodingInvalid", enc), e);
}
}
} else if (root instanceof DocumentProperties.Encoding) {
((DocumentProperties.Encoding) root).setEncoding(((Locator2) locator).getEncoding());
}
}
// ensure that the digester is properly configured, as
// the digester could be used as a SAX ContentHandler
// rather than via the parse() methods.
configure();
}
/**
* @param encoding The encoding of the XML source that was used to
* populated this object.
* @deprecated This method will be removed in Tomcat 9
*/
@Deprecated
public void setEncoding(String encoding) {
try {
charset = B2CConverter.getCharset(encoding);
} catch (UnsupportedEncodingException e) {
log.warn(sm.getString("xmlEncodingBase.encodingInvalid", encoding, charset.name()), e);
}
}
private BasicCredentials(String aMethod, String aUsername, String aPassword) {
method = aMethod;
username = aUsername;
password = aPassword;
String userCredentials = username + ":" + password;
byte[] credentialsBytes = userCredentials.getBytes(B2CConverter.ISO_8859_1);
String base64auth = Base64.encodeBase64String(credentialsBytes);
credentials = method + " " + base64auth;
}
/**
* Overrides the name of the character encoding used in the body of
* this request. This method must be called prior to reading request
* parameters or reading input using <code>getReader()</code>.
*
* @param enc The character encoding to be used
*
* @exception UnsupportedEncodingException if the specified encoding
* is not supported
*
* @since Servlet 2.3
*/
@Override
public void setCharacterEncoding(String enc)
throws UnsupportedEncodingException {
if (usingReader) {
return;
}
// Confirm that the encoding name is valid
B2CConverter.getCharset(enc);
// Save the validated encoding
coyoteRequest.setCharacterEncoding(enc);
}
/**
* Generate a unique token. The token is generated according to the
* following pattern. NOnceToken = Base64 ( MD5 ( client-IP ":"
* time-stamp ":" private-key ) ).
*
* @param request HTTP Servlet request
*/
protected String generateNonce(Request request) {
long currentTime = System.currentTimeMillis();
synchronized (lastTimestampLock) {
if (currentTime > lastTimestamp) {
lastTimestamp = currentTime;
} else {
currentTime = ++lastTimestamp;
}
}
String ipTimeKey =
request.getRemoteAddr() + ":" + currentTime + ":" + getKey();
byte[] buffer = ConcurrentMessageDigest.digestMD5(
ipTimeKey.getBytes(B2CConverter.ISO_8859_1));
String nonce = currentTime + ":" + MD5Encoder.encode(buffer);
NonceInfo info = new NonceInfo(currentTime, getNonceCountWindowSize());
synchronized (nonces) {
nonces.put(nonce, info);
}
return nonce;
}
/**
* Open the new log file for the date specified by <code>dateStamp</code>.
*/
protected synchronized void open() {
// Open the current log file
// If no rotate - no need for dateStamp in fileName
File pathname = getLogFile(rotatable && !renameOnRotate);
Charset charset = null;
if (encoding != null) {
try {
charset = B2CConverter.getCharset(encoding);
} catch (UnsupportedEncodingException ex) {
log.error(sm.getString(
"accessLogValve.unsupportedEncoding", encoding), ex);
}
}
if (charset == null) {
charset = Charset.defaultCharset();
}
try {
writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(pathname, true), charset), 128000),
false);
currentLogFile = pathname;
} catch (IOException e) {
writer = null;
currentLogFile = null;
log.error(sm.getString("accessLogValve.openFail", pathname), e);
}
}
protected Charset getDigestCharset() throws UnsupportedEncodingException {
if (digestEncoding == null) {
return Charset.defaultCharset();
} else {
return B2CConverter.getCharset(getDigestEncoding());
}
}