Akka-HTTP: how to know if Content-type header was explicitly set in received response - scala

Is the a way in akka-http to know if 'Content-type' header was explicitly set in HttpResponse that we received?
From sniffed Http dump I see, that there was no 'Content-Type' header, but
httpResponse.header[`Content-Type`].get.contentType.mediaType.toString()
and
httpResponse.entity.getContentType().mediaType.toString
stil return application/octet-stream.

This is default Content type not only for Akka-HTTP, but perhaps for other frameworks like Play too. Akka-http and other HTTP based technologies need to know how to parse content internally, based on this header. application/octet-stream means that it considers request body as just byte-stream.
Rule of thumb: if it is possible - try to specify Content-type.

Related

Does gatling use Accept-Encoding: gzip,deflate on every request?

After executing some performance using gatling, i have noticed more bandwidth results than expected on the server side.
I think/thought galitng encoding (gzig, deflate) by default on every request, but now I am not sure about that.
By activating the logging (to see what request headers are sent), the "Accept-Encoding" header is not displayed.
I think/thought Gatling encoding (gzig, deflate) by default on every request, but now I am not sure about that.
Why would that be? No, it's not, that's something you have to specify, for example as a default header on the HTTP protocol.

GET & POST passing parameters

I've read many question on stackoverflow about passing parameters with GET and POST methods, but none of them satisfied my curiosity.
I use GETs to retrieve data passing parameters as path/query params and use POSTs to save data passing parameters as request body with Content-Type: application/json and sometimes request body + path/query params (depending on other APIs I've created for simmetry purpose only).
My question is when to use Content-Type: application/x-www-form-urlencoded. Say I want to call a POST without a request body of Content-Type: application/json but with params, do I have to use the application/x-www-form-urlencoded Content-Type or I can use path/query params as best practice?
What's the difference between sending data as path/query params and key-value params with Content-Type: application/x-www-form-urlencoded? Does the data size have to do with it?
What's the difference between sending data as path/query params and key-value params with Content-Type: application/x-www-form-urlencoded?
Consider this example
PUT /example?a=b&c=d
Content-Type: application/x-www-form-urlencoded
d=e&f=g
What's happening here? This is a request that the server replace its current representation of the resource identified by
/example?a=b&c=d
With the payload. In other words, after successful processing, we would expect
GET /example?a=b&c=d
to produce a response like
200 OK
Content-Type: application/x-www-form-urlencoded
d=e&f=g
POST /example?a=b&c=d
Content-Type: application/x-www-form-urlencoded
d=e&f=g
For POST, it's the same idea, except that instead of "replace the current representation", POST stands in for "process the payload according to the specific semantics of /example?a=b&c=d".
GETs to retrieve data passing parameters as path/query params
It might help to reframe your thinking here. We use GET to retrieve the current representation of a resource. We aren't passing parameters, we're passing a document (resource) identifier.
The fact that the origin server's implementation is going to parse that identifier is an implementation detail.
A URI Template is a compact sequence of characters for describing a
range of Uniform Resource Identifiers through variable expansion.
-- RFC 6570
I want to call a POST without a request body of Content-Type: application/json but with params, do I have to use the application/x-www-form-urlencoded Content-Type or I can use path/query params as best practice?
POST /example?a=b&c=d
Content-Type: application/json
{"d":"e","f":"g"}
Is a perfectly normal HTTP request.
Content-Type describes the payload only - it has nothing at all to do with the target URI, and how information might be encoded within it.

Content-Type application/octet-stream or something more specific?

I writing an end point to accept binary data. I see in Google's API for uploading photos, they use application/octet-stream for the Content-Type and custom header X-Goog-Upload-Content-Type for the MIME type. I am leaning towards just asking for the MIME type, e.g. audio/wav or audio/mp3 in the Content-Type header. Is this an acceptable approach or should all raw binary uploads use application/octet-stream?
No. "application/octet-stream" essentially means "I don't know the type". If you know the type, by all means specify it.

Is Accept header needed for a POST method which doesn't return any content to client?

I have an endpoint which supports POST method with content-type as json(only). But the POST request doesn't return any content in its response body other than status codes. In this scenario, what is the correct behavior?
Client sends POST with Accept header as application/json
Client sends POST with Accept header as application/xml
Should the server return error in case 2?
RFC 7231 describes the semantics of the Accept header
A request without any Accept header field implies that the user agent will accept any media type in response.
If the header field is present in a request and none of the available representations for the response have a media type that is listed as acceptable, the origin server can either honor the header field by sending a 406 (Not Acceptable) response or disregard the header field by treating the response as if it is not subject to content negotiation.
The Accept header provided by the client should probably reflect the context of the request as seen by the client; for instance, a web browser might reasonably use a different Accept header for <img> than for <script>, in each case encouraging the server to provide useful representations.
In the case of a POST, what you are trying to negotiate is the representation of "the status of, or results obtained from, the action", rather than a representation of resource itself.
If the representation of the response is zero bytes long when the media-type is application/json, then I would expect the response to also be zero bytes long when the media-type is application/xml. So it isn't obvious to me to accept one but not the other.
Servers may ignore the Accept header.
If you're not returning anything in your response, it's kind of meaningless. It's up to you to decide whether you want to reject requests with Accept headers or not.
But I think most systems will not reject these requests.
https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2
A request without any Accept header field implies that the user agent
will accept any media type in response. If the header field is
present in a request and none of the available representations for
the response have a media type that is listed as acceptable, the
origin server can either honor the header field by sending a 406 (Not
Acceptable) response or disregard the header field by treating the
response as if it is not subject to content negotiation.
so either off 2 we can do

What are some differences between encoding vs content-type in Alamofire

Alamofire.request(url, method: .post, parameters: param, encoding: JSONEncoding.default, headers: [content-type: multipart/form-data])
In header of request I see that there a field called content-type which can be set as application/json, application/x-www-form-urlencoded, multipart/form-data. But the problem is that in encoding param we can also set as JSONEncoding.default. Then what are some differences between encoding vs content-type in Alamofire.
encoding: for parameter which we sending to server
content-type: for specifying the response type
The encoding parameter sets how should Alamofire parse the passed parameters. For example, if it's set to URLEncoding.default, Alamofire will append the parameters to the URL.
The Content-Type header, on the other hand, tells the web server what type of content do we want to semd.
From the MDN web docs:
The Content-Type entity header is used to indicate the media type of the resource.
In responses, a Content-Type header tells the client what the content type of the returned content actually is.
Since Alamofire is an HTTP request wrapper, it provides a parameter for settings HTTP headers. As described by W3C, HTTP headers define how your request will be handled by server : W3C' Header Field Definitions.
An additional encoding parameter is available in Alamofire since you have to describe how to format an input response. Briefly, server cannot understand how to process a Swift Array or Dictionary, you need to explicitly write what kind of encoding is required. Alamofire provides several solutions to encode Swift object : Alamofire Encoding Options.
In this way, according to your request method (PUT, GET, POST, ...) you could have an Header ["Accept": "application/json"] and differents Alamofire encoding options.