3.03 KB, patch
|Details | Diff | Splinter Review|
7.48 KB, patch
|Details | Diff | Splinter Review|
5.23 KB, patch
|Details | Diff | Splinter Review|
5.23 KB, patch
|Details | Diff | Splinter Review|
3.52 KB, patch
|Details | Diff | Splinter Review|
Created attachment 18025 [details] [diff] [review] adds stds supported to Accept, uses "q" to reflect preferences
Declaring that "MIME based content negotiation has died" is foolish. Consider that Apache _already_ supports content negotiation. Sure, right now the only real use is for server-side negotation, but the negotiation algorithm has been written for user agents that send useful "Accept:" headers. At least one real practical use of content negotiation is for serving XML content with XSL stylesheets to user agents that accept those types. I'm certain I'm /not/ the only person that was anticipating using MIME based content negotiation for this.
Accept headers should also reflect supported types of inline resources (like IMG, EMBED, and OBJECT sources, or images specified in background attributes). For example, given the HTML snipet: ... <img src="/image" /> <object src="/object" /> ... The corresponding accept headers could be sent in their respective requests (assuming the appropriate plugins are installed and enabled): Accept: image/png, video/x-mng, image/x-jng, image/jpeg, image/pjpeg, \ text/*; qs=0, application/*; qs=0 Accept: video/quicktime, audio/x-pn-realaudio, application/x-shockwave-flash, \ application/java, text/*; qs=0 This indicates that only image types that can be displayed inline are acceptable variants for the IMG tag, and that only embeddable objects are acceptable for the OBJECT tag. The basic idea here is to only specify Accept headers for what Mozilla really can accept in the context of that request. The most inclusive set of Accept headers will most likely be sent when requesting the resource specified in a link, bookmark, or a typed in URL. But any types that can only be displayed inline should have "qs" value of zero for these type of requests. For example, the Accept header when I type in http://foo.net/object into my URL textfield would be: Accept: text/*, image/*, ... application/x-shockwave-flash; qs=0, ... since Flash can only be viewed inline. If the resource http://foo.net/object is a negotiable resource, but only the object.swf variant is available, the server will respond with "406 Not Acceptable" and a list of variants with the single entry "object.swf". The user can then request the variant explicitly or Mozilla can just display the "pick an application or save to disk" dialog directly.
i personally don't like your detection algorithm for svg or mathml. The code should do simple enumeration of plugins and components instead of cheating based on compile time flags (which may or may not reflect the real world install) marking patch and review. I'd expect a real reviewer to have other suggestions. Thank you for offering this start.
Created attachment 19160 [details] [diff] [review] revised to enumerate plugins within Accept as per suggestions
Rumors of content negotiation's death are greatly exaggerated. Let's not try to kill it with harmful and worthless headers like "Accept: */*". Even something as simple as "text/html, */*;qs=0" would be a great improvement, for sites that serve WML or HTML content based on the content of the Accept: header.
I'm all for the goal of this patch, but I think that the accept header generation should be moved into the HTTP handler, with appropriate pref change notifications.
reassigning to myself.
*** Bug 68425 has been marked as a duplicate of this bug. ***
text/ecmascript is not a valid MIME type; don't use it. Also, what about ;version= parameters? Hmm. Some versions of mosaic, back in the infancy of the web, sent over 4K of Accept: header value. Do not get me wrong in what I'm about to write: real, working, scalable content negotiation is a laudable goal that should be implemented well and standardized based on proven practice. However, in my opinion, sending that >4K Accept header was more foolish than sending */*, because in the real world, */* performs *much* better, and *almost always* does the right thing, compared to such exhaustive but never quite right (version? plugins?) bandwidth pigs. Any Mozilla patch has to be hard-headed about the trade-offs here. I do not think we should send an Accept: header of unbounded length on every (or even on every initial, for a kept connection) HTTP operation. Can we find a compromise position, perhaps not as degenerate as Robin's text/html, */*;qs=0 ? /be
email@example.com - how long is the Accept header under your patch? Gerv
Putting a future milestone on this for now... will change when we come to a conclusion about what we're going to do.
At the very least, the Accept header (IMO) should explicitly list those MIME types that it can handle internally and is most likely to encounter, namely text/html, image/png, image/jpeg, and image/gif (with the appropriate q values, something few browsers seem to bother with), with something on the order of */*;q=0.1 This would at least enable servers to selectively send PNG images to Mozilla and GIF to older versions of Navigator, or send HTML to Mozilla and WML to WAP browsers. This would also put it on par with Communicator's support for the header. It would be very useful to have even this basic support, with the arguments about whether to include plugin or helper MIME types coming after the header actually does something. At the moment it's basically worthless.
Netscape added a progressive jpeg type to the useless */* when it started supporting progressive jpegs (3.x?). The same could be done for PNGs and MNGs. I don't see the point of text/html, image/jpeg or image/gif, however. /be
Not listing text/html in the Accept header on browsers like Mozilla and IE has made it tricky to implement HTML vs. WML content negotiation. Sure, I could maintain a big long list of every WAP browser, emulator, and cell phone out there, and update it every time someone released a new one, but I'd much prefer to use the Accept header. The problem is that Mozilla's */* string indicates that it accepts both text/html and text/vnd.wap.wml EQUALLY. Clearly, Mozilla would prefer HTML over WML, but it expects the server to guess this rather than telling it. (Kind of like the classic, "If you don't know what's wrong, I'm not going to tell you!" syndrome.) If you list text/html explicitly, and give */* a lower q value, you can eliminate this type of problem (at least for Mozilla). Incidentally, the Reject: header someone mentioned isn't necessary. If I remember the specs correctly, you can do this in the Accept header by including something like "text/whatever;q=0"
> Regarding your point (a), what about the plugin-find/download/install > capability of many modern browsers? Why should my server not ship my > compelling and expensively developed flash content to someone who may > well be able to download and interpret it? Sending meaningful Accept headers doesn't preclude sites from continuing to foist whatever content they want upon user's browsers. It does mean that sites have reliable information from which to make a decision of which version to send. When the choice is between sending your compelling flash content versus sending the also expensively developed, not quite so compelling, but more widely supported animated GIF content, having meaningful Accept headers can mean the difference between transmitting a version that the user will see or won't because they don't have flash and don't want to be bothered downloading. I value being able to browse without constantly being interrupted by dialog boxes asking me to go off on some entirely different task than the one I was doing. I don't buy the argument that choosing a less optimum version -- but doing so transparently -- results in less user satisfaction than prompting the user to go install additional software just to complete the task at hand. > We need something more than an "I currently accept" header. > Perhaps an exclusion list, a Reject: header? That's what "qs=0" is for.
> When the choice is between sending your compelling flash content versus > sending the also expensively developed, not quite so compelling, but more > widely supported animated GIF content, having meaningful Accept headers can > mean the difference between transmitting a version that the user will see or > won't because they don't have flash and don't want to be bothered downloading. Most flash sites I know of do not have any expensively developed animated GIF alternate content. But we're trading synthetic arguments. Someone could survey the popular sites and report back, but that doesn't alter my fundamental point: Mozilla should not send long, unbounded Accept headers. Someone please propose a short, bounded, useful Accept header. > That's what "qs=0" is for. Right, q=0. /be
IMO, someone should propose a set of Accept: headers we should send depending on context. Contexts could include: General (<A> tag, typed in HTTP URL, FRAME src) IMG href OBJECT src APPLET src SCRIPT src This way, we keep the length of the header down in many cases. The General one could be less detailed, and the other ones more specific. However, there's a possible disadvantage to this in that a server could theoretically send back different content if an image is requested directly as opposed to as part of a page (because different Accept: headers would be sent.) Gerv
Gerv: in HTTP all content is referenced individually and therefore directly.
Gerv: The server side Vary header disables caching on most of today's caching proxies. So from the application developer's view, it is much more clever to use content negotiation only for the *containing* HTML, generating non-negotiating links to inline objects. So the application implementor needs a full Accept header on the *first* object she sends. Why does nobody suggest to provide a similar interface as Preferences/Navigator/Languages to help people compose their Accept header?
I like the idea of the Accept header being a preference. I'm not sure about making it a user friendly preference... what would that look like? Just an edit box perhaps? ...but that's not very user friendly (and this preference would have the side effect of preventing a server from doing user-agent based content-negotiation). Anyways, I'd really like us to *at least* settle on a simple static Accept header that would be useful. From the discussion, it sounds like we could come up with something simple, static, and far better than */*. The issue of whether or not to expose plugins via Accept is IMO less urgent. So just to get the ball rolling, how about: Accept: text/html, image/jpeg, image/png, */*;q=0.1 I've left image/gif out, thinking that image/png should take precidence... but this is something I'm totally not sure about.
> a user friendly preference... what would that look like? Two columns: type and preference. Two buttons: add and edit Clicking on a line highlights the line, enables editing. Clicking on Edit opens a window to edit the selected preference. Doubleclicking does both at once. Clicking on Add opens the Edit window empty. The window has only the two fields. The type field takes MIME types. The preference field takes numbers between 0 and 1. Columns should be sortable.
Darin: I know all content is referenced directly. That doesn't stop the reference having a context, though. The network library would need to be told the context in order to send the appropriate Accept: header. If we make the Accept: header a preference, we can rely on it not being changed by the vast majority of users. So, the question then morphs into: "what will the default preferences be?" and we are no further forward. Also, making it a preference may well lead to some hard-to-debug problems, if one person's Mozilla 1.0 gets sent different content from the same URL as another person's. However, there definitely needs to be an official, generic way of e.g. MathML, SVG etc. and plugins to register their types for addition to the Accept: header. Surely there was a design document for this? What did it say? Is it available? Gerv
Indicating support for XML types is important for people who want to use MathML and serve fallback pages to browsers that don't support XML. It is important that XML types have a higher q value than text/html. People might have the permissions to set up alternative pages with Apache's built-in content negotiation but not have the permissions to execute elaborate Perl scripts. I'd expect something like: Accept: text/xml;q=1, text/html;q=0.9, image/png;q=1, image/jpeg;q=1, image/gif;q=0.9, text/plain;q=0.8, text/css;q=1, */*;q=0.01 Of course application/xml and application/xhtml+xml should be added once the relevant bugs are fixed. Nominating for Mozilla 0.9.2 due to importance with authoring XHTML+MathML with a HTML fallback.
Right. Here's a proposal (which I will implement unless someone tells me why it's unacceptable.) We make the value a pref, with _no_ user UI. This should not be exposed to the user because its value is a function of the software they have installed, and is not something which depends on users tastes. I am lead to believe that prefs can be updated by XPIs using signed scripts (when that is working) so if you install MathML.xpi it could add application/mathml+xml, or whatever the type is, by modifying the pref. Having it as a pref also means that, in the end, people do have access to it if they _really_ need to change it (or, at a pinch, plugin providers can provide a script to fix it up), whereas if we hard code it, they don't. It also makes it much easier for _us_ to update it later (e.g. when application/xml is supported). Eventually, I think we should be implementing Tim Taylor/timeless' suggestion that we send a different value depending on the page context of the request. This would enable us to be more verbose while keeping header lengths down, but it requires substantially more work. In the mean time, unless someone wants to improve upon it, I plan to go with Henri's suggestion to begin with, for all requests. Gerv
Gervase, thanks for the vote of confidence on my context based Accept headers. The first half of my comment is the useful part. The second half where I recommend "q=0" for types that are typically embedded inline wasn't very well thought out. Specifically, flash can be viewed via a direct URL. Generally it's probably not a useful feature even assuming that web servers would respond as I described. Besides, "q=0" for a specific mimetype isn't that necessary when it would otherwise be "q=0.01" per Henri's suggestion.
OK, patch coming up. However, it doesn't compile :-( I need some help figuring out why. There's a function in nsHTTPHandler: SetAcceptEncodings. There are only three references to it in the entire source base - it's defined once and called twice. No headers. Yet, when I clone this function and rename it to SetAccept, the compile fails: nsHTTPHandler.cpp:651: no `nsresult nsHTTPHandler::SetAccept (const char *)' member function declared in class `nsHTTPHandler' Anyone see what I'm doing wrong? Gerv
Hmm. nsHTTPHandler.h is checked into CVS. Shouldn't it be generated from the IDL? Anyway, I got it to build. Patch coming... Gerv
OK, so the post-rearch patch is even simpler than the pre-rearch one :-) Coming right up, looking for r=. There's a thread about this on n.p.m.netlib and n.p.m.porkjockeys if people have comments (particularly about exactly what the Accept: header should be.) Gerv
darin: Can you review this, please? Discussion in the newsgroups is moving towards finding the "right" value for our default Accept: header, but I'd like to get the back end plumbing in before 0.9.1. We can change the header later with ease. Gerv
Setting milestone. darin: Will you be able to review this, or are you able to find someone else to do it? Gerv
I checked in the patches for Gerv.
VERIFIED with ethereal.