I just noticed that if I upload an attachment and then I left-click on a link for it in the body of a forum post, the Discourse/Ember router doesn’t know what to do and I get a “Oops! That page doesn’t exist or is private.” error. The link will work fine if the user opens it in a new tab.
Here is an example of a forum post with a link (Opcode.cs) that doesn’t work when you left-click on it:
I tried to make an example attachment link on this forum that doesn’t work, but attachments for this forum are served from a different domain so I cannot trigger the bug. The bug only affects forums that are serving attachments from the same domain as forum posts.
Even though I have a limited understanding of front-end javascript routing stuff, I’ll repeat my suggestion: it seems like if the Discourse/Ember router does not recognize a URL, then it should trigger a full page load of that URL in order to give other parts of the web server stack a chance to respond to the URL instead (e.g. your web server or your back-end application). That way, the javascript router doesn’t have to know the full set of URLs that are valid on your web domain. It would prevent bugs like this one and it would allow people to host static files on their domain that are not part of the Discourse app, and successfully link to them from forum posts without having to hack the Discourse/Ember router. I run into variants of this bug regularly while using Discourse and it seems like the suggestion above would solve the bug for good. Thanks!
I just learned something new: the link that gets auto-generated by the Discourse post editor when you upload an attachment includes a class="attachment" attribute on its a tag. This apparently causes it to get treated as a server-side link and results in it being routed/handled correctly when I left-click on it. That will work in most cases, but it will not work if someone tries to copy the link address and use it in their own forum post.
So, to reproduce this problem, you need to have a forum that serves attachments form the same domain as posts, and you need to have a link without the “attachment” class.
Someone tagged this with “feature”. I think it is really a bug instead because the basic behavior of links that most internet users are used to is broken; you cannot link to certain pages if they happen to be on the same domain and are unknown to the Discourse/Ember router. Almost every other system for entering links to be displayed on the web allows the link to point to pages on the same domain, but Discourse has a lot of trouble with that because of the fancy javascript.
I don’t think that’s the entire story. I believe your attachments are using filetypes that the browser wants to load natively, like .html or .js.
Your easy solution is to enable a CDN, they are quite inexpensive these days, and offer much better performance as the required JS, CSS, etc is all served from a geographical location much closer to the user, wherever they are in the world.
The link I posted above shows how a “.cs” attachment is not working, and I don’t believe that is a file type that the browser wants to “load natively”.
What’s wrong with having the javascript router start a full page load whenever it doesn’t recognize a URL? It would fix all the numerous variations we have seen of this bug and also allow forum administrators to host any kind of content they want on their domain outside of the Discourse app. It would basically just make links work again in the way that most internet users expect.
We migrated our forum from phpBB to Discourse and we added redirects at the HTTP server level so that old-style URLs like https://forum.pololu.com/viewtopic.php?f=30&t=10092 will get redirected to the new Discourse-style URLs and continue to work. It is super common on our forum for people to post links to other forum threads that have related information, so it is common to find an old-style URL inside a link in the body of a forum post. All of those links are now broken because we assumed that the HTTP server redirects would be honored. They are not being honored because of the way the Discourse/Ember router was designed; it just assumes that because it does not know about the URL, the URL is invalid.
As an example, if I go to this thread and left-click “WS2812B LED app”, the link doesn’t work because of the Discourse/Ember router. It does work if I refresh or open the link in the new tab.
It’s not completely perfect because it doesn’t work URLs that are prefixed by existing Ember.js routes, but those can continue to be handled by the special case infrastructure introduced by @eviltrout here
There was some discussion on the PR about the approach of defaulting to asking the server side to handle all the client-side 404s. The Discourse core members are concerned that it will make the existing 404 routes worse, and @eviltrout wants to solve it on a case-by-case basis by building up the SERVER_SIDE_ONLY whitelist.