def render()

in http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/framing/FrameRenderer.scala [31:149]


  def render(frame: FrameEvent): ByteString =
    frame match {
      case GoAwayFrame(lastStreamId, errorCode, debug) =>
        Frame(
          8 + debug.length,
          Http2Protocol.FrameType.GOAWAY,
          Http2Protocol.Flags.NO_FLAGS,
          Http2Protocol.NoStreamId)
          .putInt32(lastStreamId)
          .putInt32(errorCode.id)
          // appends debug data, if any
          .put(debug)
          .build()

      case DataFrame(streamId, endStream, payload) =>
        // TODO: should padding be emitted? In which cases?
        Frame(
          payload.length,
          Http2Protocol.FrameType.DATA,
          Http2Protocol.Flags.END_STREAM.ifSet(endStream),
          streamId)
          .put(payload)
          .build()
      case HeadersFrame(streamId, endStream, endHeaders, headerBlockFragment, prioInfo) =>
        Frame(
          (if (prioInfo.isDefined) 5 else 0) + headerBlockFragment.length,
          Http2Protocol.FrameType.HEADERS,
          Http2Protocol.Flags.END_STREAM.ifSet(endStream) |
          Http2Protocol.Flags.END_HEADERS.ifSet(endHeaders) |
          Http2Protocol.Flags.PRIORITY.ifSet(prioInfo.isDefined),
          streamId)
          .putPriorityInfo(prioInfo)
          .put(headerBlockFragment)
          .build()

      case WindowUpdateFrame(streamId, windowSizeIncrement) =>
        Frame(
          4,
          Http2Protocol.FrameType.WINDOW_UPDATE,
          Http2Protocol.Flags.NO_FLAGS,
          streamId)
          .putInt32(windowSizeIncrement)
          .build()

      case ContinuationFrame(streamId, endHeaders, payload) =>
        Frame(
          payload.length,
          Http2Protocol.FrameType.CONTINUATION,
          Http2Protocol.Flags.END_HEADERS.ifSet(endHeaders),
          streamId)
          .put(payload)
          .build()

      case SettingsFrame(settings) =>
        val b = Frame(
          settings.length * 6,
          Http2Protocol.FrameType.SETTINGS,
          Http2Protocol.Flags.NO_FLAGS,
          Http2Protocol.NoStreamId)

        @tailrec def renderNext(remaining: Seq[Setting]): Unit =
          remaining match {
            case Setting(id, value) +: remaining =>
              b.putInt16(id.id)
              b.putInt32(value)

              renderNext(remaining)
            case Nil =>
          }

        renderNext(settings)
        b.build()

      case _: SettingsAckFrame =>
        Frame(
          0,
          Http2Protocol.FrameType.SETTINGS,
          Http2Protocol.Flags.ACK,
          Http2Protocol.NoStreamId)
          .build()

      case PingFrame(ack, data) =>
        Frame(
          data.length,
          Http2Protocol.FrameType.PING,
          Http2Protocol.Flags.ACK.ifSet(ack),
          Http2Protocol.NoStreamId)
          .put(data)
          .build()

      case RstStreamFrame(streamId, errorCode) =>
        Frame(
          4,
          Http2Protocol.FrameType.RST_STREAM,
          Http2Protocol.Flags.NO_FLAGS,
          streamId)
          .putInt32(errorCode.id)
          .build()

      case PushPromiseFrame(streamId, endHeaders, promisedStreamId, headerBlockFragment) =>
        Frame(
          4 + headerBlockFragment.length,
          Http2Protocol.FrameType.PUSH_PROMISE,
          Http2Protocol.Flags.END_HEADERS.ifSet(endHeaders),
          streamId)
          .putInt32(promisedStreamId)
          .put(headerBlockFragment)
          .build()

      case frame @ PriorityFrame(streamId, _, _, _) =>
        Frame(
          5,
          Http2Protocol.FrameType.PRIORITY,
          Http2Protocol.Flags.NO_FLAGS,
          streamId)
          .putPriorityInfo(frame)
          .build()
      case _ => throw new IllegalStateException(s"Unexpected frame type ${frame.frameTypeName}.")
    }