Scriptlets
Scriptlets copied to clipboard
Modifying XHR response without changes causes a breakage at sante.journaldesfemmes.fr
https://github.com/AdguardTeam/AdguardFilters/issues/176244
Please test with the following rule:
sante.journaldesfemmes.fr#%#//scriptlet('trusted-replace-xhr-response', ',"aabMessage":true,', ',"aabMessage":true,', '/ws/mediaplayer-data/init')
It seems that I was wrong and the information below is only partially true.
The problem is that website checks headers.get("content-type")
and if it's not application/json
then reject request.
So, it even doesn't have to be a blob
.
Do I understand correctly that video player doesn't work with mentioned rule? If it's not the problem, then please provide more details.
Regarding issue with video player, as far as I understand, the problem is that in this case responseType
is a blob
, and website expect blob
as a response, but trusted-replace-xhr-response
returns string
.
Converting modifiedContent
to a blob
(in case if responseType
is a blob
) should fixes it.
blobContent = new Blob([modifiedContent], {
type: "application/json"
});
There is a scriptlet converted to JavaScript rule with mentioned changes:
sante.journaldesfemmes.fr#%#!function(e,t){function n(e){if(!0===e.verbose){try{var t=console.log.bind(console),n=console.trace.bind(console),r=e.ruleText||"";if(e.domainName){var a;e.ruleText.includes("#%#//")?a=e.ruleText.indexOf("#%#//"):e.ruleText.includes("##+js")&&(a=e.ruleText.indexOf("##+js"));var o=e.ruleText.slice(a);r="".concat(e.domainName).concat(o)}t("".concat(r," trace start")),n&&n(),t("".concat(r," trace end"))}catch(e){}"function"==typeof window.__debug&&window.__debug(e)}}function r(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],a=e.name,o=e.verbose;if(n||o){var c=console.log;r?c("".concat(a,": ").concat(t)):c("".concat(a,":"),t)}}function a(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";if(""===e)return new RegExp(".?");var t,n,r=e.lastIndexOf("/"),a=e.substring(r+1),o=e.substring(0,r+1),c=(n=a,(t=o).startsWith("/")&&t.endsWith("/")&&!t.endsWith("\\/")&&function(e){if(!e)return!1;try{return new RegExp("",e),!0}catch(e){return!1}}(n)?n:"");if(e.startsWith("/")&&e.endsWith("/")||c)return new RegExp((c?o:e).slice(1,-1),c);var s=e.replace(/\\'/g,"'").replace(/\\"/g,'"').replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(s)}function o(e){return e&&"object"==typeof e?function(e){return 0===Object.keys(e).length&&!e.prototype}(e)?"{}":Object.entries(e).map((function(e){var t=e[0],n=e[1],r=n;return n instanceof Object&&(r="{ ".concat(o(n)," }")),"".concat(t,':"').concat(r,'"')})).join(" "):String(e)}function c(e,t,n,r,a){return{method:e,url:t,async:n,user:r,password:a}}var s=t?[].concat(e).concat(t):[e];try{(function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";if("undefined"!=typeof Proxy)if(""!==t||""===s){var l,u=""===t&&""===s,p=window.XMLHttpRequest.prototype.open,d=window.XMLHttpRequest.prototype.send,f={apply:function(t,s,p){if(l=c.apply(null,p),u){var d="xhr( ".concat(o(l)," )");return r(e,d,!0),n(e),Reflect.apply(t,s,p)}if(function(e,t,n){if(""===t||"*"===t)return!0;var o,c,s,i,l=(" ",":",c=function(e){return["url","method","headers","body","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive","signal","mode"].includes(e)},s={},t.split(" ").forEach((function(e){var t=e.indexOf(":"),n=e.slice(0,t);if(c(n)){var r=e.slice(t+1);s[n]=r}else s.url=e})),s);if(i=l,Object.values(i).every((function(e){return function(e){var t,n=function(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}(e);"/"===e[0]&&"/"===e[e.length-1]&&(n=e.slice(1,-1));try{t=new RegExp(n),t=!0}catch(e){t=!1}return t}(e)}))){var u=function(e){var t={};return Object.keys(e).forEach((function(n){t[n]=a(e[n])})),t}(l);o=Object.keys(u).every((function(e){var t=u[e],r=n[e];return Object.prototype.hasOwnProperty.call(n,e)&&"string"==typeof r&&(null==t?void 0:t.test(r))}))}else r(e,"Invalid parameter: ".concat(t)),o=!1;return o}(e,i,l)&&(s.shouldBePrevented=!0,s.headersReceived=!!s.headersReceived),s.shouldBePrevented&&!s.headersReceived){s.headersReceived=!0,s.collectedHeaders=[];var f={apply:function(e,t,n){return t.collectedHeaders.push(n),Reflect.apply(e,t,n)}};s.setRequestHeader=new Proxy(s.setRequestHeader,f)}return Reflect.apply(t,s,p)}},v={apply:function(r,o,c){if(!o.shouldBePrevented)return Reflect.apply(r,o,c);var i=new XMLHttpRequest;i.addEventListener("readystatechange",(function(){if(4===i.readyState){var r=i.readyState,c=i.response,l=i.responseText,u=i.responseURL,p=i.responseXML,d=i.status,f=i.statusText,v=l||c;if("string"==typeof v){var y="*"===t?/(\n|.)*/:a(t),h=v.replace(y,s);"blob"===o.responseType&&(h=new Blob([h],{type:"application/json"})),Object.defineProperties(o,{readyState:{value:r,writable:!1},responseURL:{value:u,writable:!1},responseXML:{value:p,writable:!1},status:{value:d,writable:!1},statusText:{value:f,writable:!1},response:{value:h,writable:!1},responseText:{value:h,writable:!1}}),setTimeout((function(){var e=new Event("readystatechange");o.dispatchEvent(e);var t=new Event("load");o.dispatchEvent(t);var n=new Event("loadend");o.dispatchEvent(n)}),1),n(e)}}})),p.apply(i,[l.method,l.url]),o.collectedHeaders.forEach((function(e){var t=e[0],n=e[1];i.setRequestHeader(t,n)})),o.collectedHeaders=[];try{d.call(i,c)}catch(e){return Reflect.apply(r,o,c)}}};XMLHttpRequest.prototype.open=new Proxy(XMLHttpRequest.prototype.open,f),XMLHttpRequest.prototype.send=new Proxy(XMLHttpRequest.prototype.send,v)}else r(e,"Pattern argument should not be empty string.")}).apply(this,s)}catch(e){console.log(e)}}({name:"trusted-replace-xhr-response",engine:"corelibs",version:"1.14.46",verbose:!1},['"aabMessage":true','"aabMessage":false',"/ws/mediaplayer-data/init"]);
Do I understand correctly that video player doesn't work with mentioned rule? If it's not the problem, then please provide more details.
Yes. That's correct. Thanks.
Regarding issue with video player, as far as I understand, the problem is that in this case responseType is a blob, and website expect blob as a response, but trusted-replace-xhr-response returns string.
Then, Can we resolve the issue with extra parameter selecting a return type?
Also, I think that we should improve json-prune-xhr-response
scriptlet too if necessary.
CC: @gorhill
Then, Can we resolve the issue with extra parameter selecting a return type?
I think that we can check responseType
and do it automatically without additional parameters.
Also, I think that we should improve
json-prune-xhr-response
scriptlet too if necessary.
As I recall, in json-prune-xhr-response
it's done this way, but type
is not set (sante.journaldesfemmes.fr
is checking it, so in this case it's needed to set it), so it might be necessary to fix it.
By the way, if I'm not wrong, as an alternative solution for https://github.com/AdguardTeam/AdguardFilters/issues/176244, this rule can be used:
sante.journaldesfemmes.fr#%#//scriptlet('set-constant', 'integrityObserver.corrupted', '0')
By the way, if I'm not wrong, as an alternative solution for https://github.com/AdguardTeam/AdguardFilters/issues/176244, this rule can be used:
Thanks. Committed.