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 + -
显示快捷键?