public static HttpRequest readHttpRequest()

in java/io/bazel/rules/closure/http/HttpParser.java [35:145]


  public static HttpRequest readHttpRequest(InputStream stream) throws IOException {
    HttpRequest request = new HttpRequest();
    StringBuilder builder = new StringBuilder(256);
    State state = State.METHOD;
    String key = "";
    int toto = 0;
    try {
      while (true) {
        int c = stream.read();
        if (c == -1) {
          if (toto == 0) {
            return null;
          } else {
            throw new HttpParserError();  // RFC7230 § 3.4
          }
        }
        if (++toto == 1024 * 1024) {
          throw new HttpParserError();  // RFC7230 § 3.2.5
        }
        switch (state) {
          case METHOD:
            if (c == ' ') {
              if (builder.length() == 0) {
                throw new HttpParserError();
              }
              request.setMethod(builder);
              builder.setLength(0);
              state = State.URI;
            } else if (c == '\r' || c == '\n') {
              break;  // RFC7230 § 3.5
            } else {
              builder.append((char) c);
            }
            break;
          case URI:
            if (c == ' ') {
              if (builder.length() == 0) {
                throw new HttpParserError();
              }
              request.setUri(URI.create(builder.toString()));
              builder.setLength(0);
              state = State.VERSION;
            } else {
              builder.append((char) c);
            }
            break;
          case VERSION:
            if (c == '\r' || c == '\n') {
              request.setVersion(builder);
              builder.setLength(0);
              state = c == '\r' ? State.CR1 : State.LF1;
            } else {
              builder.append((char) c);
            }
            break;
          case CR1:
            if (c == '\n') {
              state = State.LF1;
              break;
            }
            throw new HttpParserError();
          case LF1:
            if (c == '\r') {
              state = State.LF2;
              break;
            } else if (c == '\n') {
              request.setPayload(stream);
              return request;
            } else if (c == ' ' || c == '\t') {
              throw new HttpParserError("Line folding unacceptable");  // RFC7230 § 3.2.4
            }
            state = State.HKEY;
            // epsilon transition
          case HKEY:
            if (c == ':') {
              key = builder.toString();
              builder.setLength(0);
              state = State.HSEP;
            } else {
              builder.append((char) c);
            }
            break;
          case HSEP:
            if (c == ' ' || c == '\t') {
              break;
            }
            state = State.HVAL;
            // epsilon transition
          case HVAL:
            if (c == '\r' || c == '\n') {
              request.setHeader(key, builder.toString());
              builder.setLength(0);
              state = c == '\r' ? State.CR1 : State.LF1;
            } else {
              builder.append((char) c);
            }
            break;
          case LF2:
            if (c == '\n') {
              request.setPayload(stream);
              return request;
            }
            throw new HttpParserError();
          default:
            throw new AssertionError();
        }
      }
    } catch (IllegalArgumentException e) {
      throw new HttpParserError();
    }
  }