def chunkedResponseToNetty()

in finagle-netty4-http/src/main/scala/com/twitter/finagle/netty4/http/Bijections.scala [162:239]


    def chunkedResponseToNetty(r: Response): NettyHttp.HttpResponse =
      new NettyHttp.DefaultHttpResponse(
        versionToNetty(r.version),
        statusToNetty(r.status),
        headersToNetty(r.headerMap)
      )

    def fullResponseToNetty(r: Response): NettyHttp.FullHttpResponse =
      new NettyHttp.DefaultFullHttpResponse(
        versionToNetty(r.version),
        statusToNetty(r.status),
        ByteBufConversion.bufAsByteBuf(r.content),
        headersToNetty(r.headerMap),
        NettyHttp.EmptyHttpHeaders.INSTANCE // trailers are only propagated from chunked messages
      )

    def methodToNetty(m: Method): NettyHttp.HttpMethod =
      NettyHttp.HttpMethod.valueOf(m.toString)

    def requestToNetty(r: Request, contentLengthHeader: Option[Long]): NettyHttp.HttpRequest = {
      if (r.isChunked) {
        val result = new NettyHttp.DefaultHttpRequest(
          versionToNetty(r.version),
          methodToNetty(r.method),
          r.uri,
          headersToNetty(r.headerMap)
        )
        // We only set the Transfer-Encoding to "chunked" if the request does not have
        // Content-Length set. This mimics Netty 3 behavior, wherein a request can be "chunked"
        // and not have a "Transfer-Encoding: chunked" header (instead, it has a Content-Length).
        if (!r.headerMap.contains(Fields.ContentLength)) {
          result.headers
            .add(NettyHttp.HttpHeaderNames.TRANSFER_ENCODING, NettyHttp.HttpHeaderValues.CHUNKED)
        } else {
          // Make sure we don't have a `Transfer-Encoding: chunked` header and `Content-Length` headers
          result.headers.remove(NettyHttp.HttpHeaderNames.TRANSFER_ENCODING)
        }
        result
      } else {
        val result = new NettyHttp.DefaultFullHttpRequest(
          versionToNetty(r.version),
          methodToNetty(r.method),
          r.uri,
          ByteBufConversion.bufAsByteBuf(r.content),
          headersToNetty(r.headerMap),
          NettyHttp.EmptyHttpHeaders.INSTANCE // trailers are only propagated from chunked messages
        )

        if (contentLengthHeader.isDefined) {
          result.headers.remove(NettyHttp.HttpHeaderNames.TRANSFER_ENCODING)
        }

        val realLength = r.content.length
        // see https://tools.ietf.org/html/rfc7230#section-3.3.2
        contentLengthHeader match {
          case Some(l) if realLength != l =>
            // need to clean up the content length header
            result.headers.set(NettyHttp.HttpHeaderNames.CONTENT_LENGTH, realLength.toString)

          case None if realLength > 0 =>
            // Set the content length if we are sure there is content.
            result.headers.set(NettyHttp.HttpHeaderNames.CONTENT_LENGTH, realLength.toString)

          case None if shouldHaveLengthHeader(r.method) =>
            // RFC 7230: "A user agent SHOULD send a Content-Length in a request message
            // when no Transfer-Encoding is sent and the request method defines a meaning
            // for an enclosed payload body."
            result.headers.set(NettyHttp.HttpHeaderNames.CONTENT_LENGTH, realLength.toString)

          case _ =>
          // NOP. Either the content length header already matches or
          // it doesn't exist for messages that should not have 0 value (see allowEmpty),
          // so there is nothing to do.
        }

        result
      }
    }