default Content-Type and overriding it

400 views
Skip to first unread message

Todd Bradley

unread,
Jan 4, 2017, 4:16:40 PM1/4/17
to REST assured
Hi, I'd like to understand more about how REST-assured (or the underlying libraries) decide what Content-Type to send for a given request. I've found that if I specify a body that's a File or a String and I do NOT specify a Content-Type, the request comes out with Content-Type=text/plain anyhow.

Why/where/how does RA choose text/plain as the default Content-Type? Can I override the default? Can I tell RA to NOT use a default at all?

My simple code is like this:

File file = new File(filename);
log.info("Now sending PUT with File in the body");
given().body(file).when().log().all().put(url).then().log().all();

log.info("Now sending PUT with ASCII characters in the body");
given().body("12345").when().log().all().put(url).then().log().all();


Thanks,
Todd.

Johan Haleby

unread,
Jan 5, 2017, 1:51:01 AM1/5/17
to rest-a...@googlegroups.com
Hi Todd, 

It's admittedly been a while since I looked into this but if I remember it correctly then it can be a bit of qualified guesswork (and of course and not proud to say this). Unless you've specified it yourself (which you should) it's decided by either Apache HTTP Client or REST Assured (to be honest it might be decided by the HttpBuilder fork that RA wraps) depending on the HTTP verb and/or content. What you can do is to specify default charset (I know this is not what you're asking) for various content types using the EncoderConfig. In the EncoderConfig you can also tell RA to encode the content using another encoder in cases where RA doesn't know what it should do. For example if you specify a content-type of "helloworld" and pass in a Java object then RA doesn't know what to do with it. You can then instruct RA to treat "helloworld" as JSON by using encoderConfig.encodeContentTypeAs("helloworld", ContentType.JSON). 

Now back to your specific example RA chose text/plain because you're sending text (I assume?) using PUT. If you where to send the file as multipart data instead it would not use text/plain (but rather multipart/form-data with application/octet-stream as the "part" content-type unless specified explicitly).

The gist of the matter is that if you want to control it you should explicitly specify a content-type other Rest Assured (et al) will try to "guess".

You can specify a default content-type for all requests by using a RequestSpecification and define the content-type there. Then you can either supply this spec to the DSL (given().spec(mySpec). ..)  or attach it statically (RestAssured.requestSpecification = mySpec).

/Johan


--
You received this message because you are subscribed to the Google Groups "REST assured" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rest-assured+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Todd Bradley

unread,
Jan 5, 2017, 9:31:39 AM1/5/17
to rest-a...@googlegroups.com
On Wed, Jan 4, 2017 at 11:50 PM, Johan Haleby <johan....@gmail.com> wrote:
[...]
Now back to your specific example RA chose text/plain because you're sending text (I assume?) using PUT. If you where to send the file as multipart data instead it would not use text/plain (but rather multipart/form-data with application/octet-stream as the "part" content-type unless specified explicitly).

Nope. It seems that RA chooses text/plain regardless of what I'm sending. I didn't show it in the example, but the file is a JPG. I also tried it with a PDF, a PNG, and a couple other files. In all cases, the HTTP request gets sent out with a content type of text/plain.
 

The gist of the matter is that if you want to control it you should explicitly specify a content-type other Rest Assured (et al) will try to "guess".

You can specify a default content-type for all requests by using a RequestSpecification and define the content-type there. Then you can either supply this spec to the DSL (given().spec(mySpec). ..)  or attach it statically (RestAssured.requestSpecification = mySpec).

OK, it sounds like that's the best approach. I was hoping there was something that would let me tell RA, "If I haven't explicitly told you a Content-Type to use, please use this one." In the same way you can tell EncoderConfig, "If I haven't explicitly told you an encoding to use, please use this one."


Thanks for the help,
Todd.

Johan Haleby

unread,
Jan 5, 2017, 10:02:21 AM1/5/17
to rest-a...@googlegroups.com
On Thu, Jan 5, 2017 at 3:31 PM, Todd Bradley <to...@toddbradley.com> wrote:
On Wed, Jan 4, 2017 at 11:50 PM, Johan Haleby <johan....@gmail.com> wrote:
[...]
Now back to your specific example RA chose text/plain because you're sending text (I assume?) using PUT. If you where to send the file as multipart data instead it would not use text/plain (but rather multipart/form-data with application/octet-stream as the "part" content-type unless specified explicitly).

Nope. It seems that RA chooses text/plain regardless of what I'm sending. I didn't show it in the example, but the file is a JPG. I also tried it with a PDF, a PNG, and a couple other files. In all cases, the HTTP request gets sent out with a content type of text/plain.

Interesting, I didn't know this. Would it make sense to try to recognize the file extension and determine try to determine the content-type based on it? For example if you supply a file that points to "/tmp/pic.jpg" the content-type would resolve to "image/jpeg"? This could be made configurable in the EncoderConfig (1), something like encoderConfig.contentTypeForFileExtension("jpg", "application/octet-stream"). If so would you mind creating an issue for it?
 
 

The gist of the matter is that if you want to control it you should explicitly specify a content-type other Rest Assured (et al) will try to "guess".

You can specify a default content-type for all requests by using a RequestSpecification and define the content-type there. Then you can either supply this spec to the DSL (given().spec(mySpec). ..)  or attach it statically (RestAssured.requestSpecification = mySpec).

OK, it sounds like that's the best approach. I was hoping there was something that would let me tell RA, "If I haven't explicitly told you a Content-Type to use, please use this one." In the same way you can tell EncoderConfig, "If I haven't explicitly told you an encoding to use, please use this one."


Yeah this would be useful. But let's say that we implement (1) as well then I suppose that (1) should have priority over this configuration?!
 


Thanks for the help,
Todd.

Todd Bradley

unread,
Jan 6, 2017, 1:26:16 PM1/6/17
to rest-a...@googlegroups.com
On Thu, Jan 5, 2017 at 8:01 AM, Johan Haleby <johan....@gmail.com> wrote:

On Thu, Jan 5, 2017 at 3:31 PM, Todd Bradley <to...@toddbradley.com> wrote:
Nope. It seems that RA chooses text/plain regardless of what I'm sending. I didn't show it in the example, but the file is a JPG. I also tried it with a PDF, a PNG, and a couple other files. In all cases, the HTTP request gets sent out with a content type of text/plain.

Interesting, I didn't know this. Would it make sense to try to recognize the file extension and determine try to determine the content-type based on it? For example if you supply a file that points to "/tmp/pic.jpg" the content-type would resolve to "image/jpeg"? This could be made configurable in the EncoderConfig (1), something like encoderConfig.contentTypeForFileExtension("jpg", "application/octet-stream"). If so would you mind creating an issue for it?

I've given this topic a lot of thought over the past couple weeks, because I've been testing an object storage system that can guess a Content-Type based on the contents of the object.

I actually think that REST-assured shouldn't ever guess a Content-Type for the body of a PUT request, either by filename or content. I think that if the user doesn't specify one, RA should send out some default. But the default should always be the same, and ideally configurable.


OK, it sounds like that's the best approach. I was hoping there was something that would let me tell RA, "If I haven't explicitly told you a Content-Type to use, please use this one." In the same way you can tell EncoderConfig, "If I haven't explicitly told you an encoding to use, please use this one."


Yeah this would be useful. But let's say that we implement (1) as well then I suppose that (1) should have priority over this configuration?!

Well, I don't think that (1) is a great idea. If a tester wants his tests to work that way, changing Content-Type based on the filename, then he should build that into his own tests. That's my opinion, anyhow.


Cheers,
Todd.


Johan Haleby

unread,
Jan 7, 2017, 1:50:26 AM1/7/17
to rest-a...@googlegroups.com
On Fri, Jan 6, 2017 at 7:26 PM, Todd Bradley <to...@toddbradley.com> wrote:
On Thu, Jan 5, 2017 at 8:01 AM, Johan Haleby <johan....@gmail.com> wrote:

On Thu, Jan 5, 2017 at 3:31 PM, Todd Bradley <to...@toddbradley.com> wrote:
Nope. It seems that RA chooses text/plain regardless of what I'm sending. I didn't show it in the example, but the file is a JPG. I also tried it with a PDF, a PNG, and a couple other files. In all cases, the HTTP request gets sent out with a content type of text/plain.

Interesting, I didn't know this. Would it make sense to try to recognize the file extension and determine try to determine the content-type based on it? For example if you supply a file that points to "/tmp/pic.jpg" the content-type would resolve to "image/jpeg"? This could be made configurable in the EncoderConfig (1), something like encoderConfig.contentTypeForFileExtension("jpg", "application/octet-stream"). If so would you mind creating an issue for it?

I've given this topic a lot of thought over the past couple weeks, because I've been testing an object storage system that can guess a Content-Type based on the contents of the object.

I actually think that REST-assured shouldn't ever guess a Content-Type for the body of a PUT request, either by filename or content. I think that if the user doesn't specify one, RA should send out some default. But the default should always be the same, and ideally configurable.


Thanks for your insights, very valuable. It's hard to make the right trade-offs when you haven't experienced the problem yourself.
 

OK, it sounds like that's the best approach. I was hoping there was something that would let me tell RA, "If I haven't explicitly told you a Content-Type to use, please use this one." In the same way you can tell EncoderConfig, "If I haven't explicitly told you an encoding to use, please use this one."


Yeah this would be useful. But let's say that we implement (1) as well then I suppose that (1) should have priority over this configuration?!

Well, I don't think that (1) is a great idea. If a tester wants his tests to work that way, changing Content-Type based on the filename, then he should build that into his own tests. That's my opinion, anyhow.

Not implementing (1) would make it easier to understand and reason about as well which is nice.
 


Cheers,
Todd.


Todd Bradley

unread,
Jan 8, 2017, 5:22:16 PM1/8/17
to rest-a...@googlegroups.com
On Fri, Jan 6, 2017 at 11:50 PM, Johan Haleby <johan....@gmail.com> wrote:

Well, I don't think that (1) is a great idea. If a tester wants his tests to work that way, changing Content-Type based on the filename, then he should build that into his own tests. That's my opinion, anyhow.

Not implementing (1) would make it easier to understand and reason about as well which is nice.

So, should I write this up as a bug or enhancement? You could argue that it's a bug because the value that RA uses is inconsistent. You could also argue that it's an enhancement because RA doesn't make any claims about a default content type, so being able to set one seems like a new feature.


Johan Haleby

unread,
Jan 9, 2017, 1:13:59 AM1/9/17
to rest-a...@googlegroups.com
I don't mind whether it's a bug or enhancement, but it should at the very least be documented and consistent.

Todd Bradley

unread,
Jan 13, 2017, 6:11:39 AM1/13/17
to rest-a...@googlegroups.com

Johan Haleby

unread,
Jan 13, 2017, 6:43:38 AM1/13/17
to rest-a...@googlegroups.com
Thanks!

Reply all
Reply to author
Forward
0 new messages