Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modifying XHR response without changes causes a breakage at sante.journaldesfemmes.fr #419

Open
piquark6046 opened this issue Apr 3, 2024 · 4 comments
Assignees

Comments

@piquark6046
Copy link
Member

AdguardTeam/AdguardFilters#176244

Please test with the following rule:

sante.journaldesfemmes.fr#%#//scriptlet('trusted-replace-xhr-response', ',"aabMessage":true,', ',"aabMessage":true,', '/ws/mediaplayer-data/init')
@piquark6046 piquark6046 changed the title modifying XHR response without changes causes a breakage at sante.journaldesfemmes.fr Mmodifying XHR response without changes causes a breakage at sante.journaldesfemmes.fr Apr 3, 2024
@adguard-bot adguard-bot changed the title Mmodifying XHR response without changes causes a breakage at sante.journaldesfemmes.fr modifying XHR response without changes causes a breakage at sante.journaldesfemmes.fr Apr 3, 2024
@piquark6046 piquark6046 changed the title modifying XHR response without changes causes a breakage at sante.journaldesfemmes.fr Modifying XHR response without changes causes a breakage at sante.journaldesfemmes.fr Apr 3, 2024
@AdamWr
Copy link
Member

AdamWr commented Apr 3, 2024

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"]);

@piquark6046
Copy link
Member Author

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

@AdamWr
Copy link
Member

AdamWr commented Apr 3, 2024

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 AdguardTeam/AdguardFilters#176244, this rule can be used:

sante.journaldesfemmes.fr#%#//scriptlet('set-constant', 'integrityObserver.corrupted', '0')

@piquark6046
Copy link
Member Author

By the way, if I'm not wrong, as an alternative solution for AdguardTeam/AdguardFilters#176244, this rule can be used:

Thanks. Committed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants