private static int decodeAttributes( final Buffer requestContent, int offset, final AjpHttpRequest req, final boolean tomcatAuthentication) { final DataChunk tmpDataChunk = req.tmpDataChunk; boolean moreAttr = true; while (moreAttr) { final byte attributeCode = requestContent.get(offset++); if (attributeCode == AjpConstants.SC_A_ARE_DONE) { return offset; } /* Special case ( XXX in future API make it separate type !) */ if (attributeCode == AjpConstants.SC_A_SSL_KEY_SIZE) { // Bug 1326: it's an Integer. req.setAttribute(SSLSupport.KEY_SIZE_KEY, readShort(requestContent, offset)); offset += 2; } if (attributeCode == AjpConstants.SC_A_REQ_ATTRIBUTE) { // 2 strings ???... offset = setStringAttribute(req, requestContent, offset); } // 1 string attributes switch (attributeCode) { case AjpConstants.SC_A_CONTEXT: // nothing offset = skipBytes(requestContent, offset); break; case AjpConstants.SC_A_REMOTE_USER: if (tomcatAuthentication) { // ignore server offset = skipBytes(requestContent, offset); } else { offset = getBytesToDataChunk(requestContent, offset, req.remoteUser()); } break; case AjpConstants.SC_A_AUTH_TYPE: if (tomcatAuthentication) { // ignore server offset = skipBytes(requestContent, offset); } else { offset = getBytesToDataChunk(requestContent, offset, req.authType()); } break; case AjpConstants.SC_A_QUERY_STRING: offset = getBytesToDataChunk(requestContent, offset, req.getQueryStringDC()); break; case AjpConstants.SC_A_JVM_ROUTE: offset = getBytesToDataChunk(requestContent, offset, req.instanceId()); break; case AjpConstants.SC_A_SSL_CERT: req.setSecure(true); // SSL certificate extraction is costy, initialize on demand offset = getBytesToDataChunk(requestContent, offset, req.sslCert()); break; case AjpConstants.SC_A_SSL_CIPHER: req.setSecure(true); offset = setStringAttributeValue(req, SSLSupport.CIPHER_SUITE_KEY, requestContent, offset); break; case AjpConstants.SC_A_SSL_SESSION: req.setSecure(true); offset = setStringAttributeValue(req, SSLSupport.SESSION_ID_KEY, requestContent, offset); break; case AjpConstants.SC_A_SECRET: offset = getBytesToDataChunk(requestContent, offset, tmpDataChunk); req.setSecret(tmpDataChunk.toString()); tmpDataChunk.recycle(); break; case AjpConstants.SC_A_STORED_METHOD: offset = getBytesToDataChunk(requestContent, offset, req.getMethodDC()); break; default: break; // ignore, we don't know about it - backward compat } } return offset; }