*/
private boolean scanHeaders()
throws IOException
{
boolean isLoggable = log.isLoggable(Level.FINE);
ReadStream is = getRawRead();
WriteStream os = getRawWrite();
CharBuffer cb = getCharBuffer();
int code;
int len;
while (true) {
_rawWrite.flush();
code = is.read();
Server server = getServer();
if (server == null || server.isDestroyed()) {
log.fine(dbgId() + " request after server close");
killKeepalive("after server close");
return false;
}
switch (code) {
case -1:
if (isLoggable)
log.fine(dbgId() + "r: end of file");
_filter.setClientClosed(true);
killKeepalive("hmux end of file");
return false;
case HMUX_CHANNEL:
int channel = (is.read() << 8) + is.read();
if (isLoggable)
log.fine(dbgId() + "channel-r " + channel);
break;
case HMUX_YIELD:
if (log.isLoggable(Level.FINER))
log.finer(dbgId() + (char) code + "-r: yield");
os.write(HMUX_ACK);
os.write(0);
os.write(0);
os.flush();
break;
case HMUX_QUIT:
if (isLoggable)
log.fine(dbgId() + (char) code + "-r: end of request");
return true;
case HMUX_EXIT:
if (isLoggable)
log.fine(dbgId() + (char) code + "-r: end of socket");
killKeepalive("hmux exit");
return true;
case HMUX_PROTOCOL:
len = (is.read() << 8) + is.read();
if (len != 4) {
log.fine(dbgId() + (char) code + "-r: protocol length (" + len + ") must be 4.");
killKeepalive("hmux protocol");
return false;
}
int value = ((is.read() << 24)
+ (is.read() << 16)
+ (is.read() << 8)
+ (is.read()));
dispatchProtocol(is, code, value);
return true;
case HMUX_URI:
len = (is.read() << 8) + is.read();
_uri.setLength(len);
is.readAll(_uri.getBuffer(), 0, len);
if (isLoggable)
log.fine(dbgId() + (char) code + ":uri " + _uri);
_hasRequest = true;
break;
case HMUX_METHOD:
len = (is.read() << 8) + is.read();
is.readAll(_method, len);
if (isLoggable)
log.fine(dbgId() +
(char) code + ":method " + _method);
break;
case CSE_REAL_PATH:
len = (is.read() << 8) + is.read();
_cb1.clear();
is.readAll(_cb1, len);
code = is.read();
if (code != HMUX_STRING)
throw new IOException("protocol expected HMUX_STRING");
_cb2.clear();
is.readAll(_cb2, readLength(is));
//http.setRealPath(cb1.toString(), cb2.toString());
if (isLoggable)
log.fine(dbgId() + (char) code + " " +
_cb1.toString() + "->" + _cb2.toString());
//throw new RuntimeException();
break;
case CSE_REMOTE_HOST:
len = (is.read() << 8) + is.read();
is.readAll(_remoteHost, len);
if (isLoggable)
log.fine(dbgId() + (char) code + " " + _remoteHost);
break;
case CSE_REMOTE_ADDR:
len = (is.read() << 8) + is.read();
is.readAll(_remoteAddr, len);
if (isLoggable)
log.fine(dbgId() + (char) code + " " + _remoteAddr);
break;
case HMUX_SERVER_NAME:
len = (is.read() << 8) + is.read();
is.readAll(_serverName, len);
if (isLoggable)
log.fine(dbgId() + (char) code + " server-host: " + _serverName);
break;
case CSE_REMOTE_PORT:
len = (is.read() << 8) + is.read();
is.readAll(_remotePort, len);
if (isLoggable)
log.fine(dbgId() + (char) code +
" remote-port: " + _remotePort);
break;
case CSE_SERVER_PORT:
len = (is.read() << 8) + is.read();
is.readAll(_serverPort, len);
if (isLoggable)
log.fine(dbgId() + (char) code +
" server-port: " + _serverPort);
break;
case CSE_QUERY_STRING:
len = (is.read() << 8) + is.read();
if (len > 0) {
_uri.add('?');
_uri.ensureCapacity(_uri.getLength() + len);
is.readAll(_uri.getBuffer(), _uri.getLength(), len);
_uri.setLength(_uri.getLength() + len);
}
break;
case CSE_PROTOCOL:
len = (is.read() << 8) + is.read();
is.readAll(_protocol, len);
if (isLoggable)
log.fine(dbgId() + (char) code + " protocol: " + _protocol);
for (int i = 0; i < len; i++) {
char ch = _protocol.charAt(i);
if ('0' <= ch && ch <= '9')
_version = 16 * _version + ch - '0';
else if (ch == '.')
_version = 16 * _version;
}
break;
case HMUX_HEADER:
len = (is.read() << 8) + is.read();
int headerSize = _headerSize;
CharBuffer key = _headerKeys[headerSize];
key.clear();
CharBuffer valueCb = _headerValues[headerSize];
valueCb.clear();
is.readAll(key, len);
code = is.read();
if (code != HMUX_STRING)
throw new IOException("protocol expected HMUX_STRING at " + (char) code);
is.readAll(valueCb, readLength(is));
if (isLoggable)
log.fine(dbgId() + "H " + key + "=" + valueCb);
if (addHeaderInt(key.getBuffer(), 0, key.length(), valueCb)) {
_headerSize++;
}
break;
case CSE_CONTENT_LENGTH:
len = (is.read() << 8) + is.read();
if (_headerKeys.length <= _headerSize)
resizeHeaders();
_headerKeys[_headerSize].clear();
_headerKeys[_headerSize].append("Content-Length");
_headerValues[_headerSize].clear();
is.readAll(_headerValues[_headerSize], len);
setContentLength(_headerValues[_headerSize]);
if (isLoggable)
log.fine(dbgId() + (char) code + " content-length=" +
_headerValues[_headerSize]);
_headerSize++;
break;
case CSE_CONTENT_TYPE:
len = (is.read() << 8) + is.read();
if (_headerKeys.length <= _headerSize)
resizeHeaders();
_headerKeys[_headerSize].clear();
_headerKeys[_headerSize].append("Content-Type");
_headerValues[_headerSize].clear();
is.readAll(_headerValues[_headerSize], len);
if (isLoggable)
log.fine(dbgId() + (char) code
+ " content-type=" + _headerValues[_headerSize]);
_headerSize++;
break;
case CSE_IS_SECURE:
len = (is.read() << 8) + is.read();
_isSecure = true;
if (isLoggable)
log.fine(dbgId() + "secure");
is.skip(len);
break;
case CSE_CLIENT_CERT:
len = (is.read() << 8) + is.read();
_clientCert.clear();
_clientCert.setLength(len);
is.readAll(_clientCert.getBuffer(), 0, len);
if (isLoggable)
log.fine(dbgId() + (char) code + " cert=" + _clientCert
+ " len:" + len);
break;
case CSE_SERVER_TYPE:
len = (is.read() << 8) + is.read();
_cb1.clear();
is.readAll(_cb1, len);
if (isLoggable)
log.fine(dbgId() + (char) code + " server=" + _cb1);
if (_cb1.length() > 0)
_serverType = _cb1.charAt(0);
break;
case CSE_REMOTE_USER:
len = (is.read() << 8) + is.read();
cb.clear();
is.readAll(cb, len);
if (isLoggable)
log.fine(dbgId() + (char) code + " " + cb);
getRequestFacade().setAttribute(com.caucho.security.AbstractLogin.LOGIN_USER_NAME,
new com.caucho.security.BasicPrincipal(cb.toString()));
break;
case HMUX_DATA:
len = (is.read() << 8) + is.read();
_pendingData = len;
if (isLoggable)
log.fine(dbgId() + (char) code + " post-data: " + len);
if (len > 0)
return true;
break;
case HMUX_TO_UNIDIR_HMTP:
case HMUX_SWITCH_TO_HMTP: {
if (_hasRequest)
throw new IllegalStateException();
is.unread();
if (isLoggable)
log.fine(dbgId() + (char) code + "-r switch-to-hmtp");
_isHmtpRequest = true;
boolean result = _hmtpRequest.handleRequest();
return result;
}
case ' ': case '\n':
// skip for debugging
break;
default:
{
int d1 = is.read();
int d2 = is.read();
if (d2 < 0) {
if (isLoggable)
log.fine(dbgId() + "r: unexpected end of file");
killKeepalive("hmux data end of file");
return false;
}
len = (d1 << 8) + d2;
if (isLoggable)
log.fine(dbgId() + (char) code + " " + len);
is.skip(len);
break;
}
}
}
}