hmuxrequest.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,842 行 · 第 1/3 页
JAVA
1,842 行
} public final byte []getUriBuffer() { return _uri.getBuffer(); } public final int getUriLength() { return _uri.getLength(); } /** * Returns the protocol. */ public String getProtocol() { return _protocol.toString(); } public CharSegment getProtocolBuffer() { return _protocol; } final int getVersion() { return _version; } /** * Returns true if the request is secure. */ @Override public boolean isSecure() { return _isSecure; } /** * Returns the header. */ public String getHeader(String key) { CharSegment buf = getHeaderBuffer(key); if (buf != null) return buf.toString(); else return null; } @Override public CharSegment getHeaderBuffer(String key) { for (int i = 0; i < _headerSize; i++) { CharBuffer test = _headerKeys[i]; if (test.equalsIgnoreCase(key)) return _headerValues[i]; } return null; } public CharSegment getHeaderBuffer(char []buf, int length) { for (int i = 0; i < _headerSize; i++) { CharBuffer test = _headerKeys[i]; if (test.length() != length) continue; char []keyBuf = test.getBuffer(); int j; for (j = 0; j < length; j++) { char a = buf[j]; char b = keyBuf[j]; if (a == b) continue; if (a >= 'A' && a <= 'Z') a += 'a' - 'A'; if (b >= 'A' && b <= 'Z') b += 'a' - 'A'; if (a != b) break; } if (j == length) return _headerValues[i]; } return null; } @Override public void setHeader(String key, String value) { if (_headerKeys.length <= _headerSize) resizeHeaders(); _headerKeys[_headerSize].clear(); _headerKeys[_headerSize].append(key); _headerValues[_headerSize].clear(); _headerValues[_headerSize].append(value); _headerSize++; } @Override public void getHeaderBuffers(String key, ArrayList<CharSegment> values) { CharBuffer cb = _cb; cb.clear(); cb.append(key); int size = _headerSize; for (int i = 0; i < size; i++) { CharBuffer test = _headerKeys[i]; if (test.equalsIgnoreCase(cb)) values.add(_headerValues[i]); } } public Enumeration getHeaderNames() { HashSet<String> names = new HashSet<String>(); for (int i = 0; i < _headerSize; i++) names.add(_headerKeys[i].toString()); return Collections.enumeration(names); } /** * Returns the URI for the request, special casing the IIS issues. * Because IIS already escapes the URI before sending it, the URI * needs to be re-escaped. */ @Override public String getRequestURI() { if (_serverType == 'R') return super.getRequestURI(); String _rawURI = super.getRequestURI(); CharBuffer cb = CharBuffer.allocate(); for (int i = 0; i < _rawURI.length(); i++) { char ch = _rawURI.charAt(i); if (ch <= ' ' || ch >= 0x80 || ch == '%') { addHex(cb, ch); } else cb.append(ch); } return cb.close(); } /** * Adds a hex escape. * * @param cb the char buffer containing the escape. * @param ch the character to be escaped. */ private void addHex(CharBuffer cb, int ch) { cb.append('%'); int d = (ch >> 4) & 0xf; if (d < 10) cb.append((char) ('0' + d)); else cb.append((char) ('a' + d - 10)); d = ch & 0xf; if (d < 10) cb.append((char) ('0' + d)); else cb.append((char) ('a' + d - 10)); } /** * Returns the server name. */ @Override public String getServerName() { CharBuffer host = getHost(); if (host == null) { InetAddress addr = getConnection().getRemoteAddress(); return addr.getHostName(); } int p = host.indexOf(':'); if (p >= 0) return host.substring(0, p); else return host.toString(); } @Override public int getServerPort() { int len = _serverPort.length(); int port = 0; for (int i = 0; i < len; i++) { char ch = _serverPort.charAt(i); port = 10 * port + ch - '0'; } return port; } @Override public String getRemoteAddr() { return _remoteAddr.toString(); } public void getRemoteAddr(CharBuffer cb) { cb.append(_remoteAddr); } @Override public int printRemoteAddr(byte []buffer, int offset) throws IOException { char []buf = _remoteAddr.getBuffer(); int len = _remoteAddr.getLength(); for (int i = 0; i < len; i++) buffer[offset + i] = (byte) buf[i]; return offset + len; } @Override public String getRemoteHost() { return _remoteHost.toString(); } /** * Called for a connection: close */ @Override protected void connectionClose() { // ignore for hmux } // Response data void writeStatus(CharBuffer message) throws IOException { int channel = 2; WriteStream os = _rawWrite; os.write(HMUX_CHANNEL); os.write(channel >> 8); os.write(channel); writeString(HMUX_STATUS, message); } /** * Complete sending of all headers. */ void sendHeader() throws IOException { writeString(CSE_SEND_HEADER, ""); } /** * Writes a header to the plugin. * * @param key the header's key * @param value the header's value */ void writeHeader(String key, String value) throws IOException { writeString(HMUX_HEADER, key); writeString(HMUX_STRING, value); } /** * Writes a header to the plugin. * * @param key the header's key * @param value the header's value */ void writeHeader(String key, CharBuffer value) throws IOException { writeString(HMUX_HEADER, key); writeString(HMUX_STRING, value); } private void writeObject(WriteStream out, Serializable value) throws IOException { if (_out == null) _out = new Hessian2StreamingOutput(_rawWrite); _out.writeObject(value); _out.flush(); } private void writeLong(WriteStream out, long v) throws IOException { out.write((int) (v << 56)); out.write((int) (v << 48)); out.write((int) (v << 40)); out.write((int) (v << 32)); out.write((int) (v << 24)); out.write((int) (v << 16)); out.write((int) (v << 8)); out.write((int) (v << 0)); } void writeString(int code, String value) throws IOException { int len = value.length(); WriteStream os = _rawWrite; os.write(code); os.write(len >> 8); os.write(len); os.print(value); if (log.isLoggable(Level.FINE)) log.fine(dbgId() + (char)code + " " + value); } void writeString(int code, CharBuffer cb) throws IOException { int len = cb.length(); WriteStream os = _rawWrite; os.write(code); os.write(len >> 8); os.write(len); os.print(cb.getBuffer(), 0, len); if (log.isLoggable(Level.FINE)) log.fine(dbgId() + (char)code + " " + cb); } public void protocolCloseEvent() { } @Override public final String dbgId() { String id = _server.getServerId(); if (id.equals("")) return "Hmux[" + getConnection().getId() + "] "; else return "Hmux[" + id + ":" + getConnection().getId() + "] "; } @Override public String toString() { return "HmuxRequest" + dbgId(); } /** * Implements the protocol for data reads and writes. Data from the * web server to the JVM must be acked, except for the first data. * Data back to the web server needs no ack. */ static class ServletFilter extends StreamImpl { HmuxRequest _request; ReadStream _is; WriteStream _os; byte []_buffer = new byte[16]; int _pendingData; boolean _needsAck; boolean _isClosed; boolean _isClientClosed; ServletFilter() { } void init(HmuxRequest request, ReadStream nextRead, WriteStream nextWrite) { _request = request; _is = nextRead; _os = nextWrite; _pendingData = 0; _isClosed = false; _isClientClosed = false; _needsAck = false; } void setPending(int pendingData) { _pendingData = pendingData; } void setClientClosed(boolean isClientClosed) { _isClientClosed = isClientClosed; } @Override public boolean canRead() { return true; } @Override public int getAvailable() { return _pendingData; } /** * Reads available data. If the data needs an ack, then do so. */ @Override public int read(byte []buf, int offset, int length) throws IOException { int sublen = _pendingData; ReadStream is = _is; if (sublen <= 0) return -1; if (length < sublen) sublen = length; int readLen = is.read(buf, offset, sublen); _pendingData -= readLen; if (log.isLoggable(Level.FINEST)) log.finest(new String(buf, offset, readLen)); while (_pendingData == 0) { if (_needsAck) { int channel = 2; _os.write(HMUX_ACK); _os.write(channel >> 8); _os.write(channel); if (log.isLoggable(Level.FINE)) log.fine(_request.dbgId() + "A:ack channel 2"); } _needsAck = false; int code = is.read(); if (code == HMUX_DATA) { int len = (is.read() << 8) + is.read(); if (log.isLoggable(Level.FINE)) log.fine(_request.dbgId() + "D:post-data " + len); _pendingData = len; } else if (code == HMUX_QUIT) { if (log.isLoggable(Level.FINE)) log.fine(_request.dbgId() + "Q:quit"); return readLen; } else if (code == HMUX_EXIT) { if (log.isLoggable(Level.FINE)) log.fine(_request.dbgId() + "X:exit"); _request.killKeepalive(); return readLen; } else if (code == HMUX_YIELD) { _needsAck = true; } else if (code == HMUX_CHANNEL) { int channel = (is.read() << 8) + is.read(); if (log.isLoggable(Level.FINE)) log.fine(_request.dbgId() + "channel " + channel); } else if (code < 0) { _request.killKeepalive(); return readLen; } else { _request.killKeepalive(); int len = (is.read() << 8) + is.read(); if (log.isLoggable(Level.FINE)) log.fine(_request.dbgId() + "unknown `" + (char) code + "' " + len); is.skip(len); } } return readLen; } @Override public boolean canWrite() { return true; } /** * Send data back to the web server */ @Override public void write(byte []buf, int offset, int length, boolean isEnd) throws IOException { if (log.isLoggable(Level.FINE)) { log.fine(_request.dbgId() + (char) HMUX_DATA + ":data " + length); if (log.isLoggable(Level.FINEST)) log.finest(_request.dbgId() + "data <" + new String(buf, offset, length) + ">"); } byte []tempBuf = _buffer; while (length > 0) { int sublen = length; if (32 * 1024 < sublen) sublen = 32 * 1024; // The 3 bytes are already allocated by setPrefixWrite tempBuf[0] = HMUX_DATA; tempBuf[1] = (byte) (sublen >> 8); tempBuf[2] = (byte) sublen; _os.write(tempBuf, 0, 3); _os.write(buf, offset, sublen); length -= sublen; offset += sublen; } } @Override public void flush() throws IOException { if (log.isLoggable(Level.FINE)) log.fine(_request.dbgId() + (char) HMUX_FLUSH + ":flush"); _os.write(HMUX_FLUSH); _os.write(0); _os.write(0); _os.flush(); } @Override public void close() throws IOException { if (_isClosed) return; _isClosed = true; if (_pendingData > 0) { _is.skip(_pendingData); _pendingData = 0; } boolean keepalive = _request.allowKeepalive(); if (! _isClientClosed) { if (log.isLoggable(Level.FINE)) { if (keepalive) log.fine(_request.dbgId() + (char) HMUX_QUIT + ": quit channel"); else log.fine(_request.dbgId() + (char) HMUX_EXIT + ": exit socket"); } if (keepalive) _os.write(HMUX_QUIT); else _os.write(HMUX_EXIT); } if (keepalive) _os.flush(); else _os.close(); //nextRead.close(); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?