httpstream.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 868 行 · 第 1/2 页

JAVA
868
字号
  /**   * Read data from the connection.  If the request hasn't yet been sent   * to the server, send it.   */  public int read(byte []buf, int offset, int length) throws IOException  {    try {      return readInt(buf, offset, length);    } catch (IOException e) {      _isKeepalive = false;      throw e;    } catch (RuntimeException e) {      _isKeepalive = false;      throw e;    }  }    /**   * Read data from the connection.  If the request hasn't yet been sent   * to the server, send it.   */  public int readInt(byte []buf, int offset, int length) throws IOException  {    if (! _didGet)      getConnInput();    if (_isRequestDone)      return -1;    try {      int len = length;      if (_isChunked) {	if (_chunkLength == 0) {	  int ch;	  for (ch = _rs.read();	       ch >= 0 && (ch == '\r' || ch == '\n' || ch == ' ');	       ch = _rs.read()) {	  }        	  for (; ch >= 0 && ch != '\n'; ch = _rs.read()) {	    if (ch >= '0' && ch <= '9')	      _chunkLength = 16 * _chunkLength + ch - '0';	    else if (ch >= 'a' && ch <= 'f')	      _chunkLength = 16 * _chunkLength + ch - 'a' + 10;	    else if (ch >= 'A' && ch <= 'F')	      _chunkLength = 16 * _chunkLength + ch - 'A' + 10;	  }	  if (_chunkLength == 0) {	    _isRequestDone = true;	    return -1;	  }	}	else if (_chunkLength < 0)	  return -1;      	if (_chunkLength < len)	  len = _chunkLength;      }      else if (_contentLength < 0) {      }      else if (_contentLength == 0) {	_isRequestDone = true;	return -1;      }      else if (_contentLength < len)	len = _contentLength;      len = _rs.read(buf, offset, len);      if (len < 0) {      }      else if (_isChunked)	_chunkLength -= len;      else if (_contentLength > 0)	_contentLength -= len;      return len;    } catch (IOException e) {      _isKeepalive = false;      throw e;    } catch (RuntimeException e) {      _isKeepalive = false;      throw e;    }  }  /**   * Sends the request and initializes the response.   */  private void getConnInput() throws IOException  {    if (_didGet)      return;    try {      getConnInputImpl();    } catch (IOException e) {      _isKeepalive = false;      throw e;    } catch (RuntimeException e) {      _isKeepalive = false;      throw e;    }  }  /**   * Send the request to the server, wait for the response and parse   * the headers.   */  private void getConnInputImpl() throws IOException  {    if (_didGet)      return;    _didGet = true;    if (_method != null) {      _ws.print(_method);      _ws.print(' ');    }    else if (_isPost)      _ws.print("POST ");    else if (_isHead)      _ws.print("HEAD ");    else      _ws.print("GET ");    // Not splitting query? Also fullpath?    _ws.print(_path.getPath());    if (_path.getQuery() != null) {      _ws.print("?");      _ws.print(_path.getQuery());    }    _ws.print(" HTTP/1.1\r\n");    Object host = getAttribute("host");    _ws.print("Host: ");    if (host != null) {      _ws.print(host);    }    else if (_virtualHost != null)      _ws.print(_virtualHost);    else {      _ws.print(_path.getHost());      if (_path.getPort() != 80) {	_ws.print(":");	_ws.print(String.valueOf(_path.getPort()));      }    }    _ws.print("\r\n");        Object userAgent = getAttribute("User-Agent");    if (userAgent == null)      _ws.print("User-Agent: Mozilla/4.0 (compatible; Resin 1.0; JDK)\r\n");    else      _ws.print("User-Agent: " + userAgent + "\r\n");    Iterator iter = getAttributeNames();    while (iter.hasNext()) {      String name = (String) iter.next();      if (_reserved.get(name.toLowerCase()) == null) {	Object value = getAttribute(name);	if (value instanceof String[]) {	  String []values = (String []) value;	  for (int i = 0; i < values.length; i++) {	    _ws.print(name + ": " + values[i] + "\r\n");	  }	}	else	  _ws.print(name + ": " + value + "\r\n");      }    }    if (! _isKeepalive)      _ws.print("Connection: close\r\n");        if (_isPost) {      int length = 0;      if (_tempStream != null)	length = _tempStream.getLength();      _ws.print("Content-Length: ");      _ws.print(length);      _ws.print("\r\n");    }    _ws.print("\r\n");    if (_isPost) {      MemoryStream tempStream = _tempStream;      _tempStream = null;      if (tempStream != null) {	tempStream.writeToStream(_ws);	tempStream.destroy();      }    }    _attributes.clear();    parseHeaders();    if (_isHead)      _isRequestDone = true;  }  /**   * Parse the headers returned from the server.   */  private void parseHeaders() throws IOException  {    CharBuffer line = new CharBuffer();    // Skip blank lines    int count = 0;    do {      line.clear();      if (! _rs.readln(line)) {        _isKeepalive = false;        return;      }    } while (line.length() == 0 && ++count < 10);    if (line.length() == 0) {      _isKeepalive = false;      return;    }    if (line.startsWith("HTTP/1.1 100")) {      count = 100;      do {	line.clear();	if (! _rs.readln(line)) {	  _isKeepalive = false;	  return;	}      } while (line.length() != 0 && count-- > 0);            count = 100;      do {	line.clear();	if (! _rs.readln(line)) {	  _isKeepalive = false;	  return;	}      } while (line.length() == 0 && count-- > 0);    }    if (line.length() == 0) {      _isKeepalive = false;      return;    }    int i = 0;    for (i = 0; i < line.length() && line.charAt(i) != ' '; i++) {    }        for (; i < line.length() && line.charAt(i) == ' '; i++) {    }        int status = 0;    for (; i < line.length(); i++) {      char ch = line.charAt(i);      if (ch >= '0' && ch <= '9')        status = 10 * status + ch - '0';      else        break;    }    if (status != 200)      _isKeepalive = false;    else if (! line.startsWith("HTTP/1.1 "))      _isKeepalive = false;    _attributes.put("status", String.valueOf(status));    CharBuffer key = new CharBuffer();    while (true) {      line.clear();      if (! _rs.readln(line) || line.length() == 0)  	break;      int lineLength = line.length();            for (i = 0;           i < lineLength && Character.isWhitespace(line.charAt(i));           i++) {      }      key.clear();      for (;           i < lineLength && ! Character.isWhitespace(line.charAt(i))             && line.charAt(i) != ':';           i++) {        key.append((char) line.charAt(i));      }      for (;           i < lineLength && Character.isWhitespace(line.charAt(i));           i++) {      }      if (key.length() == 0 || lineLength <= i || line.charAt(i) != ':')        continue;      for (i++;           i < lineLength && Character.isWhitespace(line.charAt(i));           i++) {      }      key.toLowerCase();      String value = line.substring(i);      if (log.isLoggable(Level.FINE))        log.fine(key + ": " + value);            if (key.matchesIgnoreCase("content-length")) {        _contentLength = Integer.parseInt(value);      }      else if (key.matchesIgnoreCase("connection")               && value.equalsIgnoreCase("close")) {        _isKeepalive = false;      }      else if (key.matchesIgnoreCase("transfer-encoding")               && value.equalsIgnoreCase("chunked")) {                _isChunked = true;        _chunkLength = 0;      }      _attributes.put(key.toLowerCase().toString(), value);    }  }  /**   * Returns the bytes still available.   */  public int getAvailable() throws IOException  {    if (! _didGet)      getConnInput();    if (_contentLength > 0)      return _contentLength;    else      return _rs.getAvailable();  }  /**   * Close the connection.   */  public void close() throws IOException  {    if (_isKeepalive) {      // If recycling, read any unread data      if (! _didGet)        getConnInput();      if (! _isRequestDone) {        if (_tempBuffer == null)          _tempBuffer = new byte[256];        try {          while (read(_tempBuffer, 0, _tempBuffer.length) > 0) {          }        } catch (IOException e) {          _isKeepalive = false;        }      }    }    if (com.caucho.util.Alarm.isTest())      _isKeepalive = false; // XXX:        if (_isKeepalive) {      HttpStream oldSaved;      long now = Alarm.getCurrentTime();      synchronized (LOCK) {        oldSaved = _savedStream;        _savedStream = this;        _saveTime = now;      }      if (oldSaved != null && oldSaved != this) {        oldSaved._isKeepalive = false;        oldSaved.close();      }      return;    }    try {      try {        if (_ws != null)          _ws.close();      } catch (Throwable e) {      }      _ws = null;      try {        if (_rs != null)          _rs.close();      } catch (Throwable e) {      }      _rs = null;      try {        if (_os != null)          _os.close();      } catch (Throwable e) {      }      _os = null;      try {        if (_is != null)          _is.close();      } catch (Throwable e) {      }      _is = null;    } finally {      if (_s != null)	_s.close();      _s = null;    }  }  static {    _reserved = new HashMap<String,String>();    _reserved.put("user-agent", "");    _reserved.put("content-length", "");    _reserved.put("content-encoding", "");    _reserved.put("connection", "");    _reserved.put("host", "");  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?