fastcgiservlet.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 856 行 · 第 1/2 页
JAVA
856 行
for (int i = 0; i < key.length(); i++) { char ch = key.charAt(i); if (ch == '-') cb.append('_'); else if (ch >= 'a' && ch <= 'z') cb.append((char) (ch + 'A' - 'a')); else cb.append(ch); } return cb; } private int parseHeaders(HttpServletResponse res, InputStream is) throws IOException { CharBuffer key = new CharBuffer(); CharBuffer value = new CharBuffer(); int ch = is.read(); if (ch < 0) { log.fine("Can't contact FastCGI"); res.sendError(404); return -1; } while (ch >= 0) { key.clear(); value.clear(); for (; ch >= 0 && ch != ' ' && ch != '\r' && ch != '\n' && ch != ':'; ch = is.read()) { key.append((char) ch); } for (; ch >= 0 && ch == ' ' || ch == ':'; ch = is.read()) { } for (; ch >= 0 && ch != '\r' && ch != '\n'; ch = is.read()) { value.append((char) ch); } if (ch == '\r') { ch = is.read(); if (ch == '\n') ch = is.read(); } if (key.length() == 0) return ch; if (log.isLoggable(Level.FINE)) log.fine("fastcgi:" + key + ": " + value); if (key.equalsIgnoreCase("status")) { int status = 0; int len = value.length(); for (int i = 0; i < len; i++) { char digit = value.charAt(i); if ('0' <= digit && digit <= '9') status = 10 * status + digit - '0'; else break; } res.setStatus(status); } else if (key.startsWith("http") || key.startsWith("HTTP")) { } else if (key.equalsIgnoreCase("location")) { res.sendRedirect(value.toString()); } else res.addHeader(key.toString(), value.toString()); } return ch; } private void addHeader(FastCGISocket fcgiSocket, WriteStream ws, String key, String value) throws IOException { int keyLen = key.length(); int valLen = value.length(); int len = keyLen + valLen; if (keyLen < 0x80) len += 1; else len += 4; if (valLen < 0x80) len += 1; else len += 4; writeHeader(fcgiSocket, ws, FCGI_PARAMS, len); if (keyLen < 0x80) ws.write(keyLen); else { ws.write(0x80 | (keyLen >> 24)); ws.write(keyLen >> 16); ws.write(keyLen >> 8); ws.write(keyLen); } if (valLen < 0x80) ws.write(valLen); else { ws.write(0x80 | (valLen >> 24)); ws.write(valLen >> 16); ws.write(valLen >> 8); ws.write(valLen); } ws.print(key); ws.print(value); } private void addHeader(FastCGISocket fcgiSocket, WriteStream ws, CharBuffer key, String value) throws IOException { int keyLen = key.getLength(); int valLen = value.length(); int len = keyLen + valLen; if (keyLen < 0x80) len += 1; else len += 4; if (valLen < 0x80) len += 1; else len += 4; writeHeader(fcgiSocket, ws, FCGI_PARAMS, len); if (keyLen < 0x80) ws.write(keyLen); else { ws.write(0x80 | (keyLen >> 24)); ws.write(keyLen >> 16); ws.write(keyLen >> 8); ws.write(keyLen); } if (valLen < 0x80) ws.write(valLen); else { ws.write(0x80 | (valLen >> 24)); ws.write(valLen >> 16); ws.write(valLen >> 8); ws.write(valLen); } ws.print(key.getBuffer(), 0, keyLen); ws.print(value); } private void writeHeader(FastCGISocket fcgiSocket, WriteStream ws, int type, int length) throws IOException { int id = 1; int pad = 0; ws.write(FCGI_VERSION); ws.write(type); ws.write(id >> 8); ws.write(id); ws.write(length >> 8); ws.write(length); ws.write(pad); ws.write(0); } public void destroy() { FastCGISocket socket; while ((socket = _freeSockets.allocate()) != null) { try { socket.close(); } catch (Throwable e) { } } _fcgiServlets.remove(new Integer(_servletId)); } static class FastCGIInputStream extends InputStream { private FastCGISocket _fcgiSocket; private InputStream _is; private int _chunkLength; private int _padLength; private boolean _isDead; public FastCGIInputStream() { } public FastCGIInputStream(FastCGISocket fcgiSocket) { init(fcgiSocket); } public void init(FastCGISocket fcgiSocket) { _fcgiSocket = fcgiSocket; _is = fcgiSocket.getReadStream(); _chunkLength = 0; _isDead = false; } public boolean isDead() { return _isDead; } public int read() throws IOException { do { if (_chunkLength > 0) { _chunkLength--; return _is.read(); } } while (readNext()); return -1; } private boolean readNext() throws IOException { if (_is == null) return false; if (_padLength > 0) { _is.skip(_padLength); _padLength = 0; } int version; while ((version = _is.read()) >= 0) { int type = _is.read(); int id = (_is.read() << 8) + _is.read(); int length = (_is.read() << 8) + _is.read(); int padding = _is.read(); _is.read(); switch (type) { case FCGI_END_REQUEST: { int appStatus = ((_is.read() << 24) + (_is.read() << 16) + (_is.read() << 8) + (_is.read())); int pStatus = _is.read(); if (log.isLoggable(Level.FINER)) { log.finer(_fcgiSocket + ": FCGI_END_REQUEST(appStatus:" + appStatus + ", pStatus:" + pStatus + ")"); } if (appStatus != 0) _isDead = true; if (pStatus != FCGI_REQUEST_COMPLETE) _isDead = true; _is.skip(3); _is = null; return false; } case FCGI_STDOUT: if (log.isLoggable(Level.FINER)) { log.finer(_fcgiSocket + ": FCGI_STDOUT(length:" + length + ", padding:" + padding + ")"); } if (length == 0) { if (padding > 0) _is.skip(padding); break; } else { _chunkLength = length; _padLength = padding; return true; } case FCGI_STDERR: if (log.isLoggable(Level.FINER)) { log.finer(_fcgiSocket + ": FCGI_STDERR(length:" + length + ", padding:" + padding + ")"); } byte []buf = new byte[length]; _is.read(buf, 0, length); log.warning(new String(buf, 0, length)); if (padding > 0) _is.skip(padding); break; default: log.warning(_fcgiSocket + ": Unknown Protocol(" + type + ")"); _isDead = true; _is.skip(length + padding); break; } } _isDead = true; return false; } } static class FastCGISocket { private int _id; private int _keepaliveCount; private long _expireTime; private Socket _socket; private SocketStream _socketStream; private ReadStream _rs; private WriteStream _ws; FastCGISocket(int id, Socket socket, int maxKeepaliveCount) { _id = id; _socket = socket; _keepaliveCount = maxKeepaliveCount; _socketStream = new SocketStream(_socket); _ws = new WriteStream(_socketStream); _ws.setDisableClose(true); _rs = new ReadStream(_socketStream, _ws); _rs.setDisableClose(true); log.fine(this + ": open()"); } int getId() { return _id; } void setExpire(long expireTime) { _expireTime = expireTime; } ReadStream getReadStream() { return _rs; } WriteStream getWriteStream() { return _ws; } boolean isValid() { return _socket != null && Alarm.getCurrentTime() < _expireTime; } boolean allocateKeepalive() { if (! isValid()) return false; else return --_keepaliveCount > 0; } boolean isKeepalive() { return _keepaliveCount > 0; } void close() { try { log.fine(this + ": close()"); Socket socket = _socket; _socket = null; _socketStream = null; if (socket != null) socket.close(); _ws.close(); _rs.close(); } catch (Throwable e) { log.log(Level.FINER, e.toString(), e); } } public String toString() { return "FastCGISocket[" + _id + "," + _socket + "]"; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?