I'm new to OneM2M Protocol.
Searching for the OneM2M TS0001 documents, I don't get any idea of determining the Notification MIME type.
How do I determine MIME type(e.g. 'application/json', 'application/xml') of notification?
I couldn't find anything in Subscription's attributes.
This is an example of application developer guide from the site below. How did they decide to send this notification as the type of 'application/xml'?
Post a notification to ADN-AE1
HTTP Request with XML payload
POST / HTTP/1.1
Host: 192.168.0.10:9090
X-M2M-Origin: /mn-cse
X-M2M-RI: notif-12345
Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<m2m:sgn xmlns:m2m="http://www.onem2m.org/xml/protocols" rn="cin-394798749">
<nev>
<rep>
<m2m:cin>
<ty>4</ty>
<ri>cin-394798749</ri>
<pi>cnt-790965889</pi>
<ct>20150925T050534</ct>
<lt>20150925T050534</lt>
<et>20151107T154802</et>
<st>0</st>
<cnf>text/plain:0</cnf>
<cs>3</cs>
<con>ON</con>
</m2m:cin>
</rep>
</nev>
<sur>/mn-cse/sub-856593979</sur>
</m2m:sgn>
http://www.onem2m.org/application-developer-guide/implementation/notifications
You should have a look at TS-0004 "Service Layer Core Protocol Specification", section 6.7 "oneM2M specific MIME media types". There you can find all the oneM2M specific MIME types.
According to that table, the correct MIME type for a notification and XML encoding is application/vnd.onem2m-ntfy+xml.
That said, you might also check TS-0009 "HTTP Protocol Binding", sections 6.4.2 "Accept" and 6.4.3 "Content-Type". Here, the specification says, for example for Content-Type:
Any HTTP request or response containing message-body shall include the Content-type header set to one of “application/xml”, “application/json”, or the oneM2M defined media types defined in clause 6.7 of oneM2M TS-0004.
Since one can determine unambiguously the type of the resource by looking at the element *m2m:sgn", setting *application/xml" as the Content-Type for XML encoded resources is usually enough.
You can download the latest versions of the oneM2M specifications at http://www.onem2m.org/technical/published-drafts
Update
The CSE determines the encoding type (xml, json or cbor) for the notification message by looking at the optional ty parameter of the notificationURI attribute.
This is specified in TS-0001, section 9.6.8 "Resource Type subscription". The subscriber of a notification can add a type parameter (e.g. ty=xml) to the notificationURI. If this is left out, then the CSE chooses a default encoding.
Related
When connecting to a website using Net::HTTP you can parse the URL and output each of the URL headers by using #.each_header. I understand what the encoding and the user agent and such means, but not what the "accept"=>["*/*"] part is. Is this the accepted payload? Or is it something else?
require 'net/http'
uri = URI('http://www.bible-history.com/subcat.php?id=2')
http://www.bible-history.com/subcat.php?id=2>
http_request = Net::HTTP::Get.new(uri)
http_request.each_header { |header| puts header }
# => {"accept-encoding"=>["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"], "accept"=>["*/*"], "user-agent"=>["Ruby"], "host"=>["www.bible-history.com"]}
From https://www.w3.org/Protocols/HTTP/HTRQ_Headers.html#z3
This field contains a semicolon-separated list of representation schemes ( Content-Type metainformation values) which will be accepted in the response to this request.
Basically, it specifies what kinds of content you can read back. If you write an api client, you may only be interested in application/json, for example (and you couldn't care less about text/html).
In this case, your header would look like this:
Accept: application/json
And the app will know not to send any html your way.
Using the Accept header, the client can specify MIME types they are willing to accept for the requested URL. If the requested resource is e.g. available in multiple representations (e.g an image as PNG, JPG or SVG), the user agent can specify that they want the PNG version only. It is up to the server to honor this request.
In your example, the request header specifies that you are willing to accept any content type.
The header is defined in RFC 2616.
I know OData supports responding in JSON format when it's given the appropriate Accept header:
Accept: application/json
Some articles say you'll need to specify odata verbosity otherwise you'll get the default xml format, but I have not seen this to be actually true. But let me mention it anyway:
Accept: application/json;odata=verbose
But (how) can I make my request using JSON instead of a querystring?
OData doesn't provide a way to specify the query in a request body, it only supports the query in the URL. So the answer is that there's no way to do that in JSON. Note that it applies to GET requests. Modification requests (POST/PUT/...) do accept JSON as the payload (typically representing an entity for example), in which case simply specify the content type of the request in its Content-Type header.
There are java script libraries which let you build the query string using more structured code (as compared to just strings). For example the datajs http://datajs.codeplex.com/.
In my application I'm making some javascript requests to my Api Controllers to get some html formatted strings. When those requests are made with Accept: */* HTTP header (jQuery $.get method), so by default JsonMediaTypeFormatter is used and the data is returned with Content-Type: application/json in JSON format.
What I would like is to handle */* requests as text/html. So I tried to create a custom MediaTypeFormatter that supports */* media type, but it gives me the following error
The 'MediaTypeHeaderValue' of */* cannot be used as a supported
media type because it is a media range.`
Alternatively I could always provide correct expected data types in my requests, but I'm curious if there's a way to handle */* media types.
The above behavior is due to the following:
The default con-neg algorithm in Web API has the following precedence order of choosing the formatter for response:
Formatter match based on Media Type Mapping.
Formatter match based on Request Accept header's media type.
Formatter match based on Request Content-Type header's media type.
Formatter match based on if it can serialize the response data’s Type.
Now, JsonMediaTypeFormatter comes with a built-in media type mapping called XmlHttpRequestHeaderMapping which inspects an incoming request and sees if the request has the header x-requested-with: XMLHttpRequest and also if there is no accept header or if the Accept header is only having */*.
Since your request is mostly probably looking like below, according to the precedence order JsonMediaTypeFormatter is chosen as the one writing the response:
GET /api/something
Accept: */*
x-requested-with: XMLHttpRequest
A solution for your issue would be is to explicitly ask for "text/html" as this is what you are expecting.
GET /api/something
Accept: text/html
x-requested-with: XMLHttpRequest
Couple of very old blog posts about Content negotiation that I wrote:
http://blogs.msdn.com/b/kiranchalla/archive/2012/02/25/content-negotiation-in-asp-net-mvc4-web-api-beta-part-1.aspx
http://blogs.msdn.com/b/kiranchalla/archive/2012/02/27/content-negotiation-in-asp-net-mvc4-web-api-beta-part-2.aspx
Great question.
You can't set */* to be a supported media type, but what you can do is set your formatter to be the first one. Web API will pick the first formatter in the formatter collection that can write out the type if there is no Accept header or if the Accept header is */*.
So you'd want to configure your Web API like this:
config.Formatters.Insert(0, new MyHtmlFormatter());
Is there another multipart/form-data like enctype but not form-data?
EDIT
Especially,what others are used in web applications?
multipart/byteranges is used for partial data.
However this is typically used in the Server -> Client direction (whereby form-data is in the other direction). The "Form submitting" tag and other hints in the question indicate that this may not be the kind of encoding the OP is looking for.
other multipart subtypes include
multipart/mixed
multipart/alternative
multipart/parallel
Which too would be more likely (but not necessarily) used in the context of server responses rather that of client requests.
Here is a more comprehensive list of MIME multipart subtypes from Wikipedia
Do I have to specify a MIME type if the uploaded file has no extension?
In other words is there a default general MIME type?
You can use application/octet-stream for unknown types.
RFC 2046 states in section 4.5.1:
The "octet-stream" subtype is used to
indicate that a body contains
arbitrary binary data.
RFC resources:
We should use RFC-7231 (HTTP/1.1 Semantics and Content) as reference instead of RFC-2046 (Media Types) because question was clearly about HTTP Content-Type.
Also RFC-2046 does not clearly define unknown types but RFC-7231 does.
Short answer:
Do not send MIME type for unknown data.
To be more clear: Do not use Content-Type header at all.
References:
RFC-7231Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content3.1.1.5. Content-Type
A sender that generates a message containing a payload body SHOULD
generate a Content-Type header field in that message unless the
intended media type of the enclosed representation is unknown to the
sender.
That section clearly tells you to leave it out if you don't know it for sure.
It also tells that receiver could assume that type is application/octet-stream but thing is that it might also be something else.
What's different then?
RFC-20464.5.1. Octet-Stream Subtype
The recommended action for an implementation that receives an
"application/octet-stream" entity is to simply offer to put the data
in a file, with any Content-Transfer-Encoding undone, or perhaps to
use it as input to a user-specified process.
And, as already stated above:
RFC-72313.1.1.5. Content-Type
If a Content-Type header field is not present, the recipient
MAY either assume a media type of "application/octet-stream"
([RFC2046], Section 4.5.1) or examine the data to determine its type.
Conclusion:
If you define it as "application/octet-stream" then you are telling that you know that it is "application/octet-stream".
If you don't define it then you are telling that you don't know what it is and leave decision to receiver and receiver could then check if it walks like duck and...
I prefer application/unknown, but result will be surely the same as application/octet-stream