示例#1
0
  /* Quick lookahead for the start state looking for a request method or a HTTP version,
   * otherwise skip white space until something else to parse.
   */
  private boolean quickStart(ByteBuffer buffer) {
    if (_requestHandler != null) {
      _method = HttpMethod.lookAheadGet(buffer);
      if (_method != null) {
        _methodString = _method.asString();
        buffer.position(buffer.position() + _methodString.length() + 1);
        setState(State.SPACE1);
        return false;
      }
    } else if (_responseHandler != null) {
      _version = HttpVersion.lookAheadGet(buffer);
      if (_version != null) {
        buffer.position(buffer.position() + _version.asString().length() + 1);
        setState(State.SPACE1);
        return false;
      }
    }

    // Quick start look
    while (_state == State.START && buffer.hasRemaining()) {
      int ch = next(buffer);

      if (ch > HttpTokens.SPACE) {
        _string.setLength(0);
        _string.append((char) ch);
        setState(_requestHandler != null ? State.METHOD : State.RESPONSE_VERSION);
        return false;
      } else if (ch == 0) break;
      else if (ch < 0) throw new BadMessage();
    }
    return false;
  }
 @Override
 protected HttpMessage createMessage(String[] initialLine) {
   return new DefaultHttpResponse(
       HttpVersion.valueOf(initialLine[0]),
       new HttpResponseStatus(Integer.parseInt(initialLine[1]), initialLine[2]),
       validateHeaders);
 }
示例#3
0
  @Override
  public void failover(FullHttpRequest request, FullHttpResponse response) {
    Response dumpedResponse = failoverResponse(request);
    response.setProtocolVersion(HttpVersion.valueOf(dumpedResponse.getVersion()));
    response.setStatus(HttpResponseStatus.valueOf(dumpedResponse.getStatusCode()));
    for (Map.Entry<String, String> entry : dumpedResponse.getHeaders().entrySet()) {
      response.headers().add(entry.getKey(), entry.getValue());
    }

    response.content().writeBytes(dumpedResponse.getContent().getBytes());
  }
示例#4
0
 public DefaultRequest(
     Instant timestamp,
     Headers headers,
     io.netty.handler.codec.http.HttpMethod method,
     HttpVersion protocol,
     String rawUri,
     InetSocketAddress remoteSocket,
     InetSocketAddress localSocket,
     ServerConfig serverConfig,
     @Nullable RequestBodyReader bodyReader) {
   this.headers = headers;
   this.bodyReader = bodyReader;
   this.method = DefaultHttpMethod.valueOf(method);
   this.protocol = protocol.toString();
   this.rawUri = rawUri;
   this.remoteSocket = remoteSocket;
   this.localSocket = localSocket;
   this.timestamp = timestamp;
   this.serverConfig = serverConfig;
 }
 @Override
 protected HttpMessage createMessage(String[] initialLine) throws Exception {
   return new DefaultHttpRequest(
       HttpVersion.valueOf(initialLine[2]), HttpMethod.valueOf(initialLine[0]), initialLine[1]);
 }
示例#6
0
  /* Parse a request or response line
   */
  private boolean parseLine(ByteBuffer buffer) {
    boolean handle = false;

    // Process headers
    while (_state.ordinal() < State.HEADER.ordinal() && buffer.hasRemaining() && !handle) {
      // process each character
      byte ch = next(buffer);
      if (ch == 0) break;

      if (_maxHeaderBytes > 0 && ++_headerBytes > _maxHeaderBytes) {
        if (_state == State.URI) {
          LOG.warn("URI is too large >" + _maxHeaderBytes);
          throw new BadMessage(HttpStatus.REQUEST_URI_TOO_LONG_414);
        } else {
          if (_requestHandler != null) LOG.warn("request is too large >" + _maxHeaderBytes);
          else LOG.warn("response is too large >" + _maxHeaderBytes);
          throw new BadMessage(HttpStatus.REQUEST_ENTITY_TOO_LARGE_413);
        }
      }

      switch (_state) {
        case METHOD:
          if (ch == HttpTokens.SPACE) {
            _length = _string.length();
            _methodString = takeString();
            HttpMethod method = HttpMethod.CACHE.get(_methodString);
            if (method != null && !_strict) _methodString = method.asString();
            setState(State.SPACE1);
          } else if (ch < HttpTokens.SPACE)
            throw new BadMessage(ch < 0 ? "Illegal character" : "No URI");
          else _string.append((char) ch);
          break;

        case RESPONSE_VERSION:
          if (ch == HttpTokens.SPACE) {
            _length = _string.length();
            String version = takeString();
            _version = HttpVersion.CACHE.get(version);
            if (_version == null)
              throw new BadMessage(HttpStatus.BAD_REQUEST_400, "Unknown Version");
            setState(State.SPACE1);
          } else if (ch < HttpTokens.SPACE)
            throw new BadMessage(ch < 0 ? "Illegal character" : "No Status");
          else _string.append((char) ch);
          break;

        case SPACE1:
          if (ch > HttpTokens.SPACE || ch < 0) {
            if (_responseHandler != null) {
              setState(State.STATUS);
              setResponseStatus(ch - '0');
            } else {
              _uri.clear();
              setState(State.URI);
              // quick scan for space or EoBuffer
              if (buffer.hasArray()) {
                byte[] array = buffer.array();
                int p = buffer.arrayOffset() + buffer.position();
                int l = buffer.arrayOffset() + buffer.limit();
                int i = p;
                while (i < l && array[i] > HttpTokens.SPACE) i++;

                int len = i - p;
                _headerBytes += len;

                if (_maxHeaderBytes > 0 && ++_headerBytes > _maxHeaderBytes) {
                  LOG.warn("URI is too large >" + _maxHeaderBytes);
                  throw new BadMessage(HttpStatus.REQUEST_URI_TOO_LONG_414);
                }
                if (_uri.remaining() <= len) {
                  ByteBuffer uri = ByteBuffer.allocate(_uri.capacity() + 2 * len);
                  _uri.flip();
                  uri.put(_uri);
                  _uri = uri;
                }
                _uri.put(array, p - 1, len + 1);
                buffer.position(i - buffer.arrayOffset());
              } else _uri.put(ch);
            }
          } else if (ch < HttpTokens.SPACE) {
            throw new BadMessage(
                HttpStatus.BAD_REQUEST_400, _requestHandler != null ? "No URI" : "No Status");
          }
          break;

        case STATUS:
          if (ch == HttpTokens.SPACE) {
            setState(State.SPACE2);
          } else if (ch >= '0' && ch <= '9') {
            _responseStatus = _responseStatus * 10 + (ch - '0');
          } else if (ch < HttpTokens.SPACE && ch >= 0) {
            handle = _responseHandler.startResponse(_version, _responseStatus, null) || handle;
            setState(State.HEADER);
          } else {
            throw new BadMessage();
          }
          break;

        case URI:
          if (ch == HttpTokens.SPACE) {
            setState(State.SPACE2);
          } else if (ch < HttpTokens.SPACE && ch >= 0) {
            // HTTP/0.9
            _uri.flip();
            handle = _requestHandler.startRequest(_method, _methodString, _uri, null) || handle;
            setState(State.END);
            BufferUtil.clear(buffer);
            handle = _handler.headerComplete() || handle;
            handle = _handler.messageComplete() || handle;
          } else {
            if (!_uri.hasRemaining()) {
              ByteBuffer uri = ByteBuffer.allocate(_uri.capacity() * 2);
              _uri.flip();
              uri.put(_uri);
              _uri = uri;
            }
            _uri.put(ch);
          }
          break;

        case SPACE2:
          if (ch > HttpTokens.SPACE) {
            _string.setLength(0);
            _string.append((char) ch);
            if (_responseHandler != null) {
              _length = 1;
              setState(State.REASON);
            } else {
              setState(State.REQUEST_VERSION);

              // try quick look ahead for HTTP Version
              HttpVersion version;
              if (buffer.position() > 0 && buffer.hasArray())
                version =
                    HttpVersion.lookAheadGet(
                        buffer.array(),
                        buffer.arrayOffset() + buffer.position() - 1,
                        buffer.arrayOffset() + buffer.limit());
              else version = HttpVersion.CACHE.getBest(buffer, 0, buffer.remaining());
              if (version != null) {
                int pos = buffer.position() + version.asString().length() - 1;
                if (pos < buffer.limit()) {
                  byte n = buffer.get(pos);
                  if (n == HttpTokens.CARRIAGE_RETURN) {
                    _cr = true;
                    _version = version;
                    _string.setLength(0);
                    buffer.position(pos + 1);
                  } else if (n == HttpTokens.LINE_FEED) {
                    _version = version;
                    _string.setLength(0);
                    buffer.position(pos);
                  }
                }
              }
            }
          } else if (ch == HttpTokens.LINE_FEED) {
            if (_responseHandler != null) {
              handle = _responseHandler.startResponse(_version, _responseStatus, null) || handle;
              setState(State.HEADER);
            } else {
              // HTTP/0.9
              _uri.flip();
              handle = _requestHandler.startRequest(_method, _methodString, _uri, null) || handle;
              setState(State.END);
              BufferUtil.clear(buffer);
              handle = _handler.headerComplete() || handle;
              handle = _handler.messageComplete() || handle;
            }
          } else if (ch < 0) throw new BadMessage();
          break;

        case REQUEST_VERSION:
          if (ch == HttpTokens.LINE_FEED) {
            if (_version == null) {
              _length = _string.length();
              _version = HttpVersion.CACHE.get(takeString());
            }
            if (_version == null)
              throw new BadMessage(HttpStatus.BAD_REQUEST_400, "Unknown Version");

            // Should we try to cache header fields?
            if (_connectionFields == null
                && _version.getVersion() >= HttpVersion.HTTP_1_1.getVersion()) {
              int header_cache = _handler.getHeaderCacheSize();
              if (header_cache > 0) _connectionFields = new ArrayTernaryTrie<>(header_cache);
            }

            setState(State.HEADER);
            _uri.flip();
            handle = _requestHandler.startRequest(_method, _methodString, _uri, _version) || handle;
            continue;
          } else if (ch >= HttpTokens.SPACE) _string.append((char) ch);
          else throw new BadMessage();

          break;

        case REASON:
          if (ch == HttpTokens.LINE_FEED) {
            String reason = takeString();

            setState(State.HEADER);
            handle = _responseHandler.startResponse(_version, _responseStatus, reason) || handle;
            continue;
          } else if (ch >= HttpTokens.SPACE) {
            _string.append((char) ch);
            if (ch != ' ' && ch != '\t') _length = _string.length();
          } else throw new BadMessage();
          break;

        default:
          throw new IllegalStateException(_state.toString());
      }
    }

    return handle;
  }