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

Code before:
///            Ok(HttpResponse::Ok().into())
///        }).responder()
/// }
/// # fn main() {}
/// ```
pub struct JsonBody<T: HttpMessage, U: DeserializeOwned> {
    limit: usize,
    length: Option<usize>,
    stream: Option<T::Stream>,
    err: Option<JsonPayloadError>,
    fut: Option<Box<Future<Item = U, Error = JsonPayloadError>>>,
}

impl<T: HttpMessage, U: DeserializeOwned> JsonBody<T, U> {
    /// Create `JsonBody` for request.
    pub fn new<S>(req: &T, cfg: Option<&JsonConfig<S>>) -> Self {
        // check content-type
        let json = if let Ok(Some(mime)) = req.mime_type() {
            if let Some(cfg) = cfg {
                cfg.content_types.iter().any(|ct| {
                    (ct.type_.is_none() || ct.type_.unwrap() == mime.type_()) &&
                        (ct.subtype.is_none() || ct.subtype.unwrap() == mime.subtype()) &&
                        (ct.suffix.is_none() || ct.suffix == mime.suffix())
                })
            } else {
                mime.subtype() == mime::JSON || mime.suffix() == Some(mime::JSON)
            }
        } else {
            false
        };
        if !json {
            return JsonBody {
                limit: 262_144,
                length: None,
                stream: None,
                fut: None,
                err: Some(JsonPayloadError::ContentType),
            };
        }

        let mut len = None;
        if let Some(l) = req.headers().get(CONTENT_LENGTH) {
            if let Ok(s) = l.to_str() {
                if let Ok(l) = s.parse::<usize>() {
                    len = Some(l)
                }
            }
        }

        JsonBody {
            limit: 262_144,

Review comment (suggestion):
This condition should be checked first before going into `if let Some(cfg) = cfg`

I think it would be better to treat extra content types as extra.

Code after:
                })
        } else {
            false
        };
        if !json {
            return JsonBody {
                limit: 262_144,
                length: None,
                stream: None,
                fut: None,
                err: Some(JsonPayloadError::ContentType),
            };
        }

        let mut len = None;
        if let Some(l) = req.headers().get(CONTENT_LENGTH) {
            if let Ok(s) = l.to_str() {
                if let Ok(l) = s.parse::<usize>() {
                    len = Some(l)
                }
            }
        }

        JsonBody {
            limit: 262_144,
            length: len,
            stream: Some(req.payload()),
            fut: None,
            err: None,
        }
    }

    /// Change max size of payload. By default max size is 256Kb
    pub fn limit(mut self, limit: usize) -> Self {
        self.limit = limit;
        self
    }
}

impl<T: HttpMessage + 'static, U: DeserializeOwned + 'static> Future for JsonBody<T, U> {
    type Item = U;
    type Error = JsonPayloadError;

    fn poll(&mut self) -> Poll<U, JsonPayloadError> {
        if let Some(ref mut fut) = self.fut {
            return fut.poll();
        }

        if let Some(err) = self.err.take() {
            return Err(err);
        }