Skip to content
\n
#[post(\n    \"/api/user/<username>/events/authorize\",\n    format = \"application/activity+json\",\n    data = \"<authorization>\"\n)]
\n
#[get(\"/.well-known/host-meta\", format = \"application/xrd+xml\")]
\n

And so forth. These are all well-known types (except for maybe application/activity+json which seems to be newer), but they aren't known to Rocket. I've dug through https://api.rocket.rs/v0.5-rc/rocket/http/struct.ContentType.html looking for ways to define them manually, but can't figure out how I would enable the post and get macros to use those. It's mostly an aesthetics thing since the manually specified unknown types work - the IDE just complains about it and I don't see a way to tell it to ignore it (and I'd also just like it to be right).

\n

Also, is there a way to use multiple media-types in a single definition? I've tried using a vec in the definition, but that doesn't work. I've considered just implementing duplicate endpoints with different media-types, but the ranking system complicates matters. Am I correct in my observation that the format does not play in to the rank at all? That seems like an oversight. I should be able to have two identical endpoints that differ only by format and Rocket should be able to route based on the Accept header.

","upvoteCount":1,"answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"

Unfortunately, there's no way to dynamically add a media type to the list of known media types. The challenge is that warnings are emitted at compile-time whereas configuration can be completely interpreted at runtime. That is, using Rocket.toml is the default configuration source, but it can be completely replaced by anything at all, including over the network, a different file, etc. So reading something like Rocket.toml at compile-time will work but changes the meaning of configuration.

\n

One idea I've had is to add a rocket::allow codegen attribute that can be used on routes to silence warnings:

\n
#[rocket::allow(unknown_media_type)]\n#[get(\"/.well-known/webfinger?<resource>\", format = \"application/jrd+json\", rank = 1)]
\n

Since the get attribute can read rocket::allow, it can use it to silence warnings that it would otherwise be emitted.

\n

Alternatively, we could add some special syntax that says \"hey, I know this isn't recognized, but I'm okay with it.\" Maybe even abuse raw strings to do so:

\n
#[get(\"/.well-known/webfinger?<resource>\", format = r\"application/jrd+json\", rank = 1)]
\n

That would work, but might semantically be too weird.

\n

In any case, I'm open to a solution/implementation of either. The former I would accept directly, the latter would require a bit more thought.

\n
\n

Also, is there a way to use multiple media-types in a single definition?

\n
\n

No, but I don't see why we couldn't allow multiple formats! I'd accept a PR implementing this.

\n
\n

Am I correct in my observation that the format does not play in to the rank at all? That seems like an oversight. I should be able to have two identical endpoints that differ only by format and Rocket should be able to route based on the Accept header.

\n
\n

That's right. It's not clear why Rocket should prefer a route that matches json more or less than one that matches msgpack, which would be what ranking would do. We might want to say that a route that has a format should be preferred over one that doesn't, however. That might make sense. But note that Rocket does route based on the accept header, and it does this via matching, not ranking. What ranking does is tell Rocket which routes to try to match first. That is, which route to prefer. A route matching or not has nothing to do with its rank.

\n

For example, we can have:

\n
#[get(\"/\", format = \"msgpack\")]\nfn msgpack() {}\n\n#[get(\"/\", format = \"json\", rank = 2)]\nfn json() {}
\n

A request with Accept: application/* would be routed to msgpack and not json, even though they both match, because msgpack is ranked higher than json. A request with Accept: application/json would only be routed to json (it doesn't match msgpack) and a request with Accept: application/msgpack would only be routed to msgpack (it doesn't match json).

","upvoteCount":2,"url":"https://github.com/rwf2/Rocket/discussions/2503#discussioncomment-5447420"}}}
Discussion options

You must be logged in to vote

Unfortunately, there's no way to dynamically add a media type to the list of known media types. The challenge is that warnings are emitted at compile-time whereas configuration can be completely interpreted at runtime. That is, using Rocket.toml is the default configuration source, but it can be completely replaced by anything at all, including over the network, a different file, etc. So reading something like Rocket.toml at compile-time will work but changes the meaning of configuration.

One idea I've had is to add a rocket::allow codegen attribute that can be used on routes to silence warnings:

#[rocket::allow(unknown_media_type)]
#[get("/.well-known/webfinger?<resource>", format = "app…

Replies: 1 comment 3 replies

Comment options

You must be logged in to vote
3 replies
@justindthomas
Comment options

@SergioBenitez
Comment options

@justindthomas
Comment options

Answer selected by justindthomas
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants
Converted from issue

This discussion was converted from issue #2469 on March 25, 2023 14:55.