Repository: actix/actix-web
File: actix-web/src/response/builder.rs (Rust)

Code before:
    #[inline]
    pub fn streaming<S, E>(&mut self, stream: S) -> HttpResponse
    where
        S: Stream<Item = Result<Bytes, E>> + 'static,
        E: Into<BoxError> + 'static,
    {
        self.body(BodyStream::new(stream))
    }

    /// Set a JSON body and build the `HttpResponse`.
    ///
    /// `HttpResponseBuilder` can not be used after this call.
    pub fn json(&mut self, value: impl Serialize) -> HttpResponse {
        match serde_json::to_string(&value) {
            Ok(body) => {
                let contains = if let Some(parts) = self.inner() {
                    parts.headers.contains_key(header::CONTENT_TYPE)
                } else {
                    true
                };

                if !contains {
                    self.insert_header((header::CONTENT_TYPE, mime::APPLICATION_JSON));
                }

                self.body(body)
            }
            Err(err) => HttpResponse::from_error(JsonPayloadError::Serialize(err)),
        }
    }

    /// Set an empty body and build the `HttpResponse`.
    ///
    /// `HttpResponseBuilder` can not be used after this call.
    #[inline]
    pub fn finish(&mut self) -> HttpResponse {
        self.body(())
    }

    /// This method construct new `HttpResponseBuilder`
    pub fn take(&mut self) -> Self {
        Self {
            res: self.res.take(),
            error: self.error.take(),
        }
    }

    fn inner(&mut self) -> Option<&mut ResponseHead> {
        if self.error.is_some() {
            return None;
        }

Review comment (suggestion):
this won't do anything due to https://github.com/actix/actix-web/blob/8996198f2c922e7c052a85d69022515440cac66d/actix-http/src/h1/encoder.rs#L147

we should encourage using SizedStream if the size is known, also plays better with body-altering middleware like compression

Code after:
    ///
    /// If `Content-Type` is not set, then it is automatically set to `application/octet-stream`.
    ///
    /// If `Content-Length` is set, then [`no_chunking()`](Self::no_chunking) is automatically called.
    #[inline]
    pub fn streaming<S, E>(&mut self, stream: S) -> HttpResponse
    where
        S: Stream<Item = Result<Bytes, E>> + 'static,
        E: Into<BoxError> + 'static,
    {
        // Set mime type to application/octet-stream if it is not set
        if let Some(parts) = self.inner() {
            if !parts.headers.contains_key(header::CONTENT_TYPE) {
                self.insert_header((header::CONTENT_TYPE, mime::APPLICATION_OCTET_STREAM));
            }
        }

        if let Some(parts) = self.inner() {
            if let Some(length) = parts.headers.get(header::CONTENT_LENGTH) {
                if let Ok(length) = length.to_str() {
                    if let Ok(length) = length.parse::<u64>() {
                        self.no_chunking(length);
                    }
                }
            }
        }

        self.body(BodyStream::new(stream))
    }

    /// Set a JSON body and build the `HttpResponse`.
    ///
    /// `HttpResponseBuilder` can not be used after this call.
    pub fn json(&mut self, value: impl Serialize) -> HttpResponse {
        match serde_json::to_string(&value) {
            Ok(body) => {
                let contains = if let Some(parts) = self.inner() {
                    parts.headers.contains_key(header::CONTENT_TYPE)
                } else {
                    true
                };

                if !contains {
                    self.insert_header((header::CONTENT_TYPE, mime::APPLICATION_JSON));
                }

                self.body(body)
            }
            Err(err) => HttpResponse::from_error(JsonPayloadError::Serialize(err)),
        }
    }