MIME type handling API in MV3

71 views
Skip to first unread message

Adomas

unread,
Aug 9, 2022, 8:14:46 AM8/9/22
to Chromium Extensions
Hi,

I am a developer responsible for Zotero Connector - a 3M+ user extension. We are transitioning to Manifest V3 and one of the remaining features that we cannot easily implement is related to MIME type handling. The current MV2 extension uses blocking webRequest to check response headers, cancel requests and display a prompt for MIME types that Zotero understands natively. The user are prompted to either allow Zotero to import the file, or cancel, in which case we redirect the browser back to the file and do not block the request. We have two main categories for these:
1. Citation styles (.csl)
2. Bibliographic metadata files (.bibtex, .bib, .ris) and others

There was a bug created on the bugtracker (https://bugs.chromium.org/p/chromium/issues/detail?id=1141166) specifically related to MIME type handling, but it got merged into a more generic DNR bug for DNR filter rules for headers. That's the only discussion of this that I have managed to find.

I think a MIME type handling API could be useful for many uses-cases beyond Zotero, and cannot be rolled into the more generic DNR feature unless DNR allows to attach JS callbacks for captured rules (which seems very much against the design philosophy there). 

Our current dev implementation of MV3 Zotero Connector has a special rule to handle citation styles from www.zotero.org/styles (we cannot implement this with DNR for other websites with just URL filtering as any site can serve these files), where we redirect .csl style URLs to a #hash URL and then show a confirmation prompt. This flow would be almost fine, except that a DNR redirect to a #hash URL causes a full page reload, instead of only a history update. That leads to suboptimal UX (the MV2 version causes no page loads or refreshing). However, even if DNR rule redirects to #hash urls happened without a refresh, other websites may have JS that strips or otherwise handles #hash part of the URL and we wouldn't be able to capture that, so it is not a bulletproof solution either and the only way to properly address this is to add a separate MIME type handling API that supports JS handlers.

If necessary, I can either create a bug on the bugtracker, or post on that existing bug marked as duplicate.

Thanks,
Adomas

hrg...@gmail.com

unread,
Aug 10, 2022, 9:37:50 PM8/10/22
to Chromium Extensions, Adomas
Broadly speaking, the declarativeNetRequest API suffers from a design problem: Its RuleCondition object is way too restrictive and unnecessarily complicated.
It currently has 15 (FIFTEEN!!) properties. And all it can do is to match various URLs associated to the request/response as well as the request method, request type and tab ID.
For example, it has the initiatorDomains property or the tabIds property, and at the same time it has the excludedInitiatorDomains and excludedTabIds properties.

This over-bloated design is complicated and it lacks extensibility.
A simpler and much more effective RuleCondition object would be like this:

{
    field:
    matchType:
    matcher:
    negate:  
}


So, we could do things like this:

EXAMPLE 1: Matches if the request's contentType begins with "text/"
{
    field: "request.headers.contenType",
    matchType: "regexp",
    matcher: "^text/",
    negate: false,
}


EXAMPLE 2: Matches if the response's URL is neighter example1.com nor example2.com
{
    field: "response.url.hostname",
    matchType: "array",
    matcher: ["example1.com", "example2.com"],
    negate: true,
}


EXAMPLE 3: Matches if the the tab's pinned state is true
{
    field: "tab.pinned",
    matchType: "boolean",
    matcher: true,
}


This way the "field" property would allow a much wider range of possibilities, such as:
request.url
request.url.hostname
request.url.path
request.method
request.headers.origin
request.headers.contentType
request.headers.cookie
request.headers.cacheControl

response.url
response.method
response.headers

tab.id
tab.status
tab.pinned
tab.active

Etc...

This design would immediately allow what you are asking for.
Simpler mechanisms always work better and they are easier to extend. I don't understand why they chose the current design, which is the most complicated way of doing it (a messy implementation full of IF-ELSE statements that's hard to maintain and extend).
It benefits no-one.

Reply all
Reply to author
Forward
0 new messages