I am using Scala Akka HTTP to make an API call that requires a custom Content-Type (e.g. application/vnd+company.category+json). The API I am trying to use requires this content type in the header. Per Akka HTTP documentation, Content-Type can't be set explicitly into the headers of the HTTP request and must be set using the contentType property of the HttpEntity. I'm not sure what Akka does to the contentType set in the HttpEntity, but it is obviously not appearing in the headers sequence of the HTTP message (as defined here: http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0/scala/http/common/http-model.html). As a result, I consistently get Error 415: SRVE0295E, which translates to "415 Unsupported Media Type. The request entity has a media type which the server or resource does not support." I tried the API via curl with -H Content-Type of the same custom content type I have been using with Akka HTTP and I get a success response. Has anyone ever run into a similar problem?
As it turns out, the API I am consuming has multiple variants of the custom Content-Type, each specific to the API endpoint to be consumed. So this is not an Akka HTTP issue.
Related
I was trying to setup Jmeter for Salesforce API testing. However getting the below error during Salesforce authorization:
"error":"unsupported_grant_type","error_description":"grant type not
supported"
I am passing the parameters as in the screenshots attached. The same parameters when passed in Postman works fine, however I am getting this error in Jmeter. Please let me know if I am making some error in passing the parameters in Jmeter.
Jmeter_HTTP Header Manager
Jmeter_HTTP Request
Jmeter_Sampler Result
According to HTTP Status Code 400 documentation
The HyperText Transfer Protocol (HTTP) 400 Bad Request response status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
Looking into your request, you're sending Content-Type header as application/json therefore your server expects JSON and you're providing something different.
My expectation is that you should switch to Body Data tab of the HTTP Request sampler and set the request body to look like:
Check out REST API Testing - How to Do it Right article for more information on REST APIs testing using JMeter.
I struggle with the same issue but it finally worked for me by doing the following:
Use Content-Type application/x-www-form-urlencoded in an HTTP Header Manager
Make sure is a POST Method and that you're using https
Not sure if it is necessary but in the Parameters tab make sure all (grant_type, password, client_secret_ client_id and username) are Content-Type application/x-www-form-urlencoded and check the URL Encode option for all
Only check "Follow Redirects" and "Use KeepAlive" options in the HTTP Request
hope it works for you too
I'm trying to call a simple 'Hello World' REST API via the GET verb. The API is only expecting one HTTP Header, Accept application/json which i've set in the Advanced Settings>HTTP Headers of my tRestClient component. However, looking at the code tab, Talend seems to automatically create another entry for the contents of the Accept Type dropdown. When i run I’m getting HTTP 406 Not Acceptable back because the API is not expecting 2 headers.
I've tested this API with other software and it responds correctly so it must be down to Talend configuration. Anybody know a way around this or had a similar issue they've resolved?
I have screenshots but unfortunately they're being blocked by my firewall at work.
Thanks
tRESTClient defines its http headers based on the parameters you supply in the component settings. It has an "Accept Type" setting, which you can set to "JSON", this adds the http header "Accept: application/json" (this way you don't have to add it in the http headers section).
For your use case, you can also use tREST, which allows you to have complete control over http headers, it only sends those you set in the http headers section.
I'm piloting use of Cucumber for functional/integration testing within my development organization and have been using Citrus with the standard glue it provides for API testing. The hurdle I've encountered is how to dynamically change the REST URL given variables for a scenario. The capability seems to exist in the Java DSL but is not exposed in the Cucumber steps. I can configure the citrus-http:client with placeholders for system properties but these obviously need to be resolved when the application context is loaded by Spring. What I'd like to be able to do in my Background message definition is something like:
Given message todoListRequest
And <todoListRequest> header Content-Type is "application/json"
And <todoListRequest> header Accept is "application/json"
And <todoListRequest> uri is "/todo/${item-number}"
and then in a Scenario:
Scenario: Gets expected item for specified item number
Given variables
| item-number | 3 |
When <todoListClient> sends message <todoListRequest>
Then <todoListClient> should receive message <todoListResponse>
The service hostname and port could still be configured in the application context and the constructed URI appended to that value to create the target of the method (GET in this case, though I didn't specify and maybe that is something else that needs to be added?). Does that seem reasonable? Obviously, I could write my own glue for this but I wanted to see if there was an out of the box provided capability for what seems like a pretty obvious REST scenario before going that route. I understand the Cucumber integration is fairly recent (as of 2.6?) so it might still be maturing. This is an area where I would be interested in helping if that is welcome...
Thanks
You can use the Citrus internal message headers here:
And <todoListRequest> header citrus_http_method is "POST"
And <todoListRequest> header citrus_http_request_uri is "/todo/${item-number}"
The Citrus http client will read these special headers and remove those automatically before message is sent.
Edit: Since Citrus 2.7.1 there is a default REST Cucumber step API that provides brilliant access to sending and receiving messages over Http. So you can write
Given Content-Type: application/json
And Accept: application/json
When send POST /todo/${item-number}
Then receive status 200 OK
Read more about this here: http://www.citrusframework.org/reference/html/cucumber.html#http-steps
If you have a REST service that accepts multiple formats:
JSON
XML
HTML form data
Is there a widely accepted 'default' Content Type or:
You pick it yourself based on the most frequent / common use case
Don't accept a missing content type, require it explicitly by consumer
For example, according to W3C the default content type for POST via HTML, is application/x-www-form-urlencoded.
I strongly suggest that a server should reject a request that has a missing or inappropriate Content-Type header. RFC 7231 Has an explicit code for such:
6.5.13. 415 Unsupported Media Type
The 415 (Unsupported Media Type) status code indicates that the
origin server is refusing to service the request because the payload
is in a format not supported by this method on the target resource.
The format problem might be due to the request's indicated
Content-Type or Content-Encoding, or as a result of inspecting the
data directly.
Even though it doesn't explicitly mention a missing Content-Type, this is the accepted practice. See: HTTP status code for unaccepted Content-Type in request
Just as you should send the content-type in a response, you should also expect to have a content-type in the request.
Also, it's quite common to expect the correct content-type, see Jira REST API for instance:
Make sure the content type in the request is set to 'application/json', as shown in the example.
Or Twilio, where they have a list of accepted content-type and say:
If the content-type header does not match the media, Twilio will reject the request.
And I'm pretty sure that also the Outlook Mail REST API needs it to be correctly set.
So, yes, I'd say:"Don't accept a missing content type".
I developed a rest server, and I put it to run in localhost, and I'm trying to perform tests with JMeter, sending requests posts and gets (depends of called method).
I already send to Rest server and got result with JMeter in simple post requests, get requests, sending files with post, and sending a Json with post.
But I don't know how to send a Form-UrlEncoded object to server. My Rest server consumes application/x-www-form-urlencoded, and I need to send 3 String parameters.
There's some way to set the MimeType for every parameter and perform the test ?
I'm using Jmeter 2.7
[Update]
I solved this by disabling the option:
use multipart/form-data for post
And enabling:
redirect automatically
Instead of:
follow redirect
The parameters I put normally in the table "Send parameters with the Request" with each respective names.
For sending form parameters as application/x-www-form-urlencoded, add a header parameter Content-Type with value application/x-www-form-urlencoded.
The following steps is aplicable for Jmeter 2.3.4
Add a HTTP Header Manager under your http Request.
Add new parameter to HTTP Header Manager with name Content-Type and value application/x-www-form-urlencoded.
Uncheck "Use multipart/form-data for HTTP POST" of HTTP request.
Uncheck "Encode?" of each request parameter(not necessary).
kept "Content Encode:" text box of HTTP request as empty.
This won't work for PUT request.
For put request add parameters as path parameter and set Content-Type header then Jmeter will do by itself.
Here's the solution for HTTP POST with x-www-form-urlencoded testing with jmeter. You just folllow like these.
Go to Thread Group -> Add listener -> Views Result in table, View result Tree. To see the process of responding.
Have you tried to save your test using BadBoy or JMeter Proxy to see what your application actually sends?
To see what happens under the hood you can also use FireBug if you're using FireFox or Ctrl+Shift+i if you're on Chrome.
IllegalCharsetNameException will go immediately only after you will add the required content-type in HTTP Header Manager for HTTP request .
Hope this helps.
followed exact steps mentioned i still see an exception thrown
Response code: Non HTTP response code: java.nio.charset.IllegalCharsetNameException
Response message: Non HTTP response message: application/x-www-form-urlencoded
java.nio.charset.IllegalCharsetNameException: application/x-www-form-urlencoded
at java.nio.charset.Charset.checkName(Charset.java:315)
at java.nio.charset.Charset.lookup2(Charset.java:484)
at java.nio.charset.Charset.lookup(Charset.java:464)
at java.nio.charset.Charset.forName(Charset.java:528)
at org.apache.http.entity.ContentType.create(ContentType.java:210)
at org.apache.http.entity.StringEntity.<init>(StringEntity.java:116)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sendPostData(HTTPHC4Impl.java:1340)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.handleMethod(HTTPHC4Impl.java:592)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:409)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:74)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1166)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1155)
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:475)
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:418)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:249)
at java.lang.Thread.run(Thread.java:745)