Skip to content
Permalink
Browse files

fix: return a 415 for unsupported content-type headers

  • Loading branch information
philbooth committed Nov 27, 2018
1 parent 16040f8 commit 0704c45d7d98c5ea0cce17423da5e544cc98319f
Showing with 42 additions and 5 deletions.
  1. +1 −1 src/error.rs
  2. +24 −0 src/server/test.rs
  3. +16 −2 src/web/error.rs
  4. +1 −2 src/web/extractors.rs
@@ -75,7 +75,7 @@ impl From<Context<ApiErrorKind>> for ApiError {
ApiErrorKind::Db(error) => error.status,
ApiErrorKind::Hawk(_) => StatusCode::UNAUTHORIZED,
ApiErrorKind::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
ApiErrorKind::Validation(_) => StatusCode::BAD_REQUEST,
ApiErrorKind::Validation(error) => error.status,
};

Self { inner, status }
@@ -271,3 +271,27 @@ fn put_bso() {
}
};
}

#[test]
fn invalid_content_type() {
let mut server = setup();
let request = server
.client(http::Method::PUT, "/1.5/42/storage/bookmarks/wibble")
.set_header(
"Authorization",
create_hawk_header(
"PUT",
server.addr().port(),
"/1.5/42/storage/bookmarks/wibble",
),
).set_header("Content-Type", "application/javascript")
.json(BsoBody {
id: Some("wibble".to_string()),
sortindex: Some(0),
payload: Some("wibble".to_string()),
ttl: Some(31536000),
}).unwrap();

let response = server.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::UNSUPPORTED_MEDIA_TYPE);
}
@@ -2,7 +2,7 @@

use std::fmt;

use actix_web::http::header::ToStrError;
use actix_web::http::{header::ToStrError, StatusCode};
use actix_web::Error as ActixError;
use base64::DecodeError;
use failure::{Backtrace, Context, Fail, SyncFailure};
@@ -68,6 +68,7 @@ pub enum HawkErrorKind {
#[derive(Debug)]
pub struct ValidationError {
inner: Context<ValidationErrorKind>,
pub status: StatusCode,
}

/// Causes of extractor errors.
@@ -97,7 +98,20 @@ impl From<Context<HawkErrorKind>> for HawkError {

impl From<Context<ValidationErrorKind>> for ValidationError {
fn from(inner: Context<ValidationErrorKind>) -> Self {
Self { inner }
let status = match inner.get_context() {
ValidationErrorKind::FromDetails(ref _description, ref location, ref name) => {
if *location == RequestErrorLocation::Header
&& *name == Some("Content-Type".to_owned())
{
StatusCode::UNSUPPORTED_MEDIA_TYPE
} else {
StatusCode::BAD_REQUEST
}
}
_ => StatusCode::BAD_REQUEST,
};

Self { inner, status }
}
}

@@ -201,12 +201,11 @@ impl FromRequest<ServerState> for BsoBody {
match headers.get(CONTENT_TYPE).unwrap_or(&default).as_bytes() {
b"application/json" | b"text/plain" | b"" => (),
_ => {
// TODO: This is supposed to return a 415 status for unknown content-type
return Box::new(future::err(
ValidationErrorKind::FromDetails(
"Invalid content-type".to_owned(),
RequestErrorLocation::Header,
Some("content-type".to_owned()),
Some("Content-Type".to_owned()),
).into(),
));
}

0 comments on commit 0704c45

Please sign in to comment.
You can’t perform that action at this time.