httprequest.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,500 行 · 第 1/3 页
JAVA
1,500 行
_method.setLength(offset); // skip whitespace while (ch == ' ' || ch == '\t') { if (readOffset >= readLength) { if ((readLength = s.fillBuffer()) < 0) return false; readOffset = 0; } ch = readBuffer[readOffset++]; } byte []uriBuffer = _uri; int uriLength = 0; // skip 'http:' if (ch != '/') { while (ch > ' ' && ch != '/') { if (readOffset >= readLength) { if ((readLength = s.fillBuffer()) < 0) return false; readOffset = 0; } ch = readBuffer[readOffset++]; } if (readOffset >= readLength) { if ((readLength = s.fillBuffer()) < 0) { if (ch == '/') { uriBuffer[uriLength++] = (byte) ch; _uriLength = uriLength; } return true; } readOffset = 0; } int ch1 = readBuffer[readOffset++]; if (ch1 != '/') { uriBuffer[uriLength++] = (byte) ch; ch = ch1; } else { // read host host: while (true) { if (readOffset >= readLength) { if ((readLength = s.fillBuffer()) < 0) { return true; } readOffset = 0; } ch = readBuffer[readOffset++]; switch (ch) { case ' ': case '\t': case '\n': case '\r': break host; case '?': break host; case '/': break host; default: _uriHost.append((char) ch); break; } } } } // read URI uri: while (true) { switch (ch) { case ' ': case '\t': case '\n': case '\r': break uri; default: // There's no check for overrunning the length because // allowing resizing would allow a DOS memory attack and // also lets us save a bit of efficiency. uriBuffer[uriLength++] = (byte) ch; break; } if (readOffset >= readLength) { readOffset = 0; if ((readLength = s.fillBuffer()) < 0) { _uriLength = uriLength; return true; } } ch = readBuffer[readOffset++]; } _uriLength = uriLength; // skip whitespace while (ch == ' ' || ch == '\t') { if (readOffset >= readLength) { readOffset = 0; if ((readLength = s.fillBuffer()) < 0) return true; } ch = readBuffer[readOffset++]; } buffer = _protocol.getBuffer(); length = buffer.length; offset = 0; // scan protocol while (ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n') { if (offset >= length) { } else if (ch >= 'a' && ch <= 'z') buffer[offset++] = ((char) (ch + 'A' - 'a')); else buffer[offset++] = (char) ch; if (readOffset >= readLength) { readOffset = 0; if ((readLength = s.fillBuffer()) < 0) { _protocol.setLength(offset); return true; } } ch = readBuffer[readOffset++]; } _protocol.setLength(offset); if (offset != 8) { _protocol.append("HTTP/0.9"); _version = HTTP_0_9; } else if (buffer[7] == '1') // && _protocol.equals(_http11Cb)) _version = HTTP_1_1; else if (buffer[7] == '0') // && _protocol.equals(_http10Cb)) _version = HTTP_1_0; else _version = HTTP_0_9; // skip to end of line while (ch != '\n') { if (readOffset >= readLength) { if ((readLength = s.fillBuffer()) < 0) return true; readOffset = 0; } ch = readBuffer[readOffset++]; } s.setOffset(readOffset); return true; } /** * Parses headers from the read stream. * * @param s the input read stream */ private void parseHeaders(ReadStream s) throws IOException { // This is still slowest part of the web server. I don't see how // to improve it much more, but there must be a way. int version = getVersion(); if (version < HTTP_1_0) { return; } if (version < HTTP_1_1) killKeepalive(); byte []readBuffer = s.getBuffer(); int readOffset = s.getOffset(); int readLength = s.getLength(); char []headerBuffer = _headerBuffer; int headerOffset = 1; int headerBufferSize = headerBuffer.length; headerBuffer[0] = 'z'; int headerSize = 0; _headerSize = 0; CharSegment []headerKeys = _headerKeys; CharSegment []headerValues = _headerValues; boolean debug = log.isLoggable(Level.FINE); while (true) { int ch; int keyOffset = headerOffset; // scan the key while (true) { if (readLength <= readOffset) { readOffset = 0; if ((readLength = s.fillBuffer()) <= 0) return; } ch = readBuffer[readOffset++]; if (ch == '\n') { s.setOffset(readOffset); return; } else if (ch == ':') break; headerBuffer[headerOffset++] = (char) ch; } while (headerBuffer[headerOffset - 1] == ' ') headerOffset--; int keyLength = headerOffset - keyOffset; headerKeys[headerSize].init(headerBuffer, keyOffset, keyLength); do { if (readLength <= readOffset) { readOffset = 0; if ((readLength = s.fillBuffer()) <= 0) return; } ch = readBuffer[readOffset++]; } while (ch == ' ' || ch == '\t'); int valueOffset = headerOffset; // scan the value while (true) { if (readLength <= readOffset) { readOffset = 0; if ((readLength = s.fillBuffer()) <= 0) break; } if (ch == '\n') { int ch1 = readBuffer[readOffset]; if (ch1 == ' ' || ch1 == '\t') { ch = ' '; readOffset++; if (headerBuffer[headerOffset - 1] == '\r') headerOffset--; } else break; } headerBuffer[headerOffset++] = (char) ch; ch = readBuffer[readOffset++]; } while (headerBuffer[headerOffset - 1] <= ' ') headerOffset--; int valueLength = headerOffset - valueOffset; headerValues[headerSize].init(headerBuffer, valueOffset, valueLength); if (debug) { log.fine(dbgId() + headerKeys[headerSize] + ": " + headerValues[headerSize]); } if (addHeaderInt(headerBuffer, keyOffset, keyLength, headerValues[headerSize])) { headerSize++; } _headerSize = headerSize; } } /** * Returns the HTTP version of the request based on getProtocol(). */ int getVersion() { if (_version > 0) return _version; CharSegment protocol = getProtocolBuffer(); if (protocol.length() < 8) { _version = HTTP_0_9; return _version; } if (protocol.equals("HTTP/1.0")) { _version = HTTP_1_0; return _version; } else if (protocol.equals("HTTP/1.1")) { _version = HTTP_1_1; return HTTP_1_1; } else if (protocol.equals("HTTP/0.9")) { _version = HTTP_0_9; return HTTP_0_9; } int i = protocol.indexOf('/'); int len = protocol.length(); int major = 0; for (i++; i < len; i++) { char ch = protocol.charAt(i); if (ch >= '0' && ch <= '9') major = 10 * major + ch - '0'; else if (ch == '.') break; else { _version = HTTP_1_0; return _version; } } int minor = 0; for (i++; i < len; i++) { char ch = protocol.charAt(i); if (ch >= '0' && ch <= '9') minor = 10 * minor + ch - '0'; else break; } _version = 256 * major + minor; return _version; } /** * Returns the header. */ public String getMethod() { if (_methodString == null) { CharSegment cb = getMethodBuffer(); if (cb.length() == 0) { _methodString = "GET"; return _methodString; } switch (cb.charAt(0)) { case 'G': _methodString = cb.equals(_getCb) ? "GET" : cb.toString(); break; case 'H': _methodString = cb.equals(_headCb) ? "HEAD" : cb.toString(); break; case 'P': _methodString = cb.equals(_postCb) ? "POST" : cb.toString(); break; default: _methodString = cb.toString(); } } return _methodString; } /** * Returns a buffer containing the request method. */ public CharSegment getMethodBuffer() { return _method; } /** * Returns the virtual host of the request */ protected CharSequence getHost() { if (_host != null) return _host; String virtualHost = _conn.getVirtualHost(); if (virtualHost != null) _host = virtualHost; else if (_uriHost.length() > 0) _host = _uriHost; else _host = _hostHeader; return _host; } /** * Returns the byte buffer containing the request URI */ public byte []getUriBuffer() { return _uri; } /** * Returns the length of the request URI */ public int getUriLength() { return _uriLength; } /** * Returns the protocol. */ public String getProtocol() { switch (_version) { case HTTP_1_1: return "HTTP/1.1"; case HTTP_1_0: return "HTTP/1.0"; case HTTP_0_9: default: return "HTTP/0.9"; } } /** * Returns a char segment containing the protocol. */ public CharSegment getProtocolBuffer() { return _protocol; } /** * Adds a new header. Used only by the caching to simulate * If-Modified-Since. * * @param key the key of the new header * @param value the value for the new header */ public void setHeader(String key, String value) { int tail; if (_headerSize > 0) { tail = (_headerValues[_headerSize - 1].getOffset() + _headerValues[_headerSize - 1].getLength()); } else tail = 0; char []headerBuffer = _headerBuffer; for (int i = key.length() - 1; i >= 0; i--) headerBuffer[tail + i] = key.charAt(i); _headerKeys[_headerSize].init(headerBuffer, tail, key.length()); tail += key.length(); for (int i = value.length() - 1; i >= 0; i--) headerBuffer[tail + i] = value.charAt(i); _headerValues[_headerSize].init(headerBuffer, tail, value.length()); _headerSize++; } /** * Returns the number of headers. */ @Override public int getHeaderSize() { return _headerSize; } /** * Returns the header key */ @Override public CharSegment getHeaderKey(int index) { return _headerKeys[index]; } /** * Returns the header value */ @Override public CharSegment getHeaderValue(int index) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?