public ByteBuffer generate(short version, Fields headers) {
    // TODO: ByteArrayOutputStream is quite inefficient, but grows on demand; optimize using
    // ByteBuffer ?
    final Charset iso1 = StandardCharsets.ISO_8859_1;
    ByteArrayOutputStream buffer = new ByteArrayOutputStream(headers.getSize() * 64);
    writeCount(version, buffer, headers.getSize());
    for (Fields.Field header : headers) {
      String name = header.getName().toLowerCase(Locale.ENGLISH);
      byte[] nameBytes = name.getBytes(iso1);
      writeNameLength(version, buffer, nameBytes.length);
      buffer.write(nameBytes, 0, nameBytes.length);

      // Most common path first
      String value = header.getValue();
      byte[] valueBytes = value.getBytes(iso1);
      if (header.hasMultipleValues()) {
        List<String> values = header.getValues();
        for (int i = 1; i < values.size(); ++i) {
          byte[] moreValueBytes = values.get(i).getBytes(iso1);
          byte[] newValueBytes = new byte[valueBytes.length + 1 + moreValueBytes.length];
          System.arraycopy(valueBytes, 0, newValueBytes, 0, valueBytes.length);
          newValueBytes[valueBytes.length] = 0;
          System.arraycopy(
              moreValueBytes, 0, newValueBytes, valueBytes.length + 1, moreValueBytes.length);
          valueBytes = newValueBytes;
        }
      }

      writeValueLength(version, buffer, valueBytes.length);
      buffer.write(valueBytes, 0, valueBytes.length);
    }

    return compress(version, buffer.toByteArray());
  }
  private static ByteBuffer convertFields(String contentDisposition, Fields fields) {
    try {
      if (fields == null || fields.isEmpty()) {
        contentDisposition += "\r\n";
        return ByteBuffer.wrap(contentDisposition.getBytes(StandardCharsets.US_ASCII));
      }

      ByteArrayOutputStream buffer =
          new ByteArrayOutputStream((fields.getSize() + 1) * contentDisposition.length());
      buffer.write(contentDisposition.getBytes(StandardCharsets.US_ASCII));
      for (Fields.Field field : fields) {
        buffer.write(field.getName().getBytes(StandardCharsets.US_ASCII));
        buffer.write(COLON_SPACE_BYTES);
        buffer.write(field.getValue().getBytes(StandardCharsets.UTF_8));
        buffer.write(CR_LF_BYTES);
      }
      buffer.write(CR_LF_BYTES);
      return ByteBuffer.wrap(buffer.toByteArray());
    } catch (IOException x) {
      throw new RuntimeIOException(x);
    }
  }
Exemplo n.º 3
0
  @Override
  public void onReply(Stream stream, ReplyInfo replyInfo) {
    HttpExchange exchange = getHttpExchange();
    if (exchange == null) return;

    try {
      HttpResponse response = exchange.getResponse();

      Fields fields = replyInfo.getHeaders();
      short spdy = stream.getSession().getVersion();
      HttpVersion version =
          HttpVersion.fromString(fields.get(HTTPSPDYHeader.VERSION.name(spdy)).getValue());
      response.version(version);
      String[] status = fields.get(HTTPSPDYHeader.STATUS.name(spdy)).getValue().split(" ", 2);

      Integer code = Integer.parseInt(status[0]);
      response.status(code);
      String reason = status.length < 2 ? HttpStatus.getMessage(code) : status[1];
      response.reason(reason);

      if (responseBegin(exchange)) {
        for (Fields.Field field : fields) {
          String name = field.getName();
          if (HTTPSPDYHeader.from(spdy, name) != null) continue;
          // TODO: handle multiple values properly
          HttpField httpField = new HttpField(name, field.getValue());
          responseHeader(exchange, httpField);
        }

        if (responseHeaders(exchange)) {
          if (replyInfo.isClose()) {
            responseSuccess(exchange);
          }
        }
      }
    } catch (Exception x) {
      responseFailure(x);
    }
  }