diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index fe6109e9db38c..c305d3ca75e5d 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -1786827,6 +1786827,54 @@ worker / resources / +scope1 +/ +redirect +. +py +" +: +[ +[ +{ +} +] +] +" +service +- +workers +/ +service +- +worker +/ +resources +/ +scope2 +/ +worker_interception_redirect_webworker +. +py +" +: +[ +[ +{ +} +] +] +" +service +- +workers +/ +service +- +worker +/ +resources +/ service - worker @@ -1787635,6 +1787683,62 @@ resources / worker - +interception +- +redirect +- +serviceworker +. +js +" +: +[ +[ +{ +} +] +] +" +service +- +workers +/ +service +- +worker +/ +resources +/ +worker +- +interception +- +redirect +- +webworker +. +js +" +: +[ +[ +{ +} +] +] +" +service +- +workers +/ +service +- +worker +/ +resources +/ +worker +- load - interceptor @@ -1787677,6 +1787781,28 @@ service - workers / +service +- +worker +/ +resources +/ +worker_interception_redirect_webworker +. +py +" +: +[ +[ +{ +} +] +] +" +service +- +workers +/ specgen . json @@ -2359312,6 +2359438,52 @@ worker worker - interception +- +redirect +. +https +. +html +" +: +[ +[ +" +/ +service +- +workers +/ +service +- +worker +/ +worker +- +interception +- +redirect +. +https +. +html +" +{ +} +] +] +" +service +- +workers +/ +service +- +worker +/ +worker +- +interception . https . @@ -4036670,6 +4036842,58 @@ worker / resources / +scope1 +/ +redirect +. +py +" +: +[ +" +7741f204c67ca71087df3b182826bc28c14dbe37 +" +" +support +" +] +" +service +- +workers +/ +service +- +worker +/ +resources +/ +scope2 +/ +worker_interception_redirect_webworker +. +py +" +: +[ +" +c482ed2a7ff5ed2d663bd54ee2ecd2f6609d77cd +" +" +support +" +] +" +service +- +workers +/ +service +- +worker +/ +resources +/ service - worker @@ -4037540,6 +4037764,66 @@ resources / worker - +interception +- +redirect +- +serviceworker +. +js +" +: +[ +" +05a2f3a4ad034b9cece10b5abc7ffff71bfcb4aa +" +" +support +" +] +" +service +- +workers +/ +service +- +worker +/ +resources +/ +worker +- +interception +- +redirect +- +webworker +. +js +" +: +[ +" +615f6dd41ee6f9f141132a48544f976ce0403d27 +" +" +support +" +] +" +service +- +workers +/ +service +- +worker +/ +resources +/ +worker +- load - interceptor @@ -4037590,6 +4037874,30 @@ service - worker / +resources +/ +worker_interception_redirect_webworker +. +py +" +: +[ +" +37a8a7bd94cc529420eba8838e1e20056caf2945 +" +" +support +" +] +" +service +- +workers +/ +service +- +worker +/ respond - with @@ -4038553,6 +4038861,34 @@ worker worker - interception +- +redirect +. +https +. +html +" +: +[ +" +8654d94e9797ac332bedcadeed61837ccf13b944 +" +" +testharness +" +] +" +service +- +workers +/ +service +- +worker +/ +worker +- +interception . https . diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/scope1/redirect.py b/testing/web-platform/tests/service-workers/service-worker/resources/scope1/redirect.py new file mode 100644 index 0000000000000..b1741a3f35809 --- /dev/null +++ b/testing/web-platform/tests/service-workers/service-worker/resources/scope1/redirect.py @@ -0,0 +1,39 @@ +import +os +import +sys +# +Use +the +file +from +the +parent +directory +. +sys +. +path +. +append +( +os +. +path +. +dirname +( +os +. +path +. +dirname +( +__file__ +) +) +) +from +redirect +import +main diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py b/testing/web-platform/tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py new file mode 100644 index 0000000000000..5ee4e81a99db9 --- /dev/null +++ b/testing/web-platform/tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py @@ -0,0 +1,39 @@ +import +os +import +sys +# +Use +the +file +from +the +parent +directory +. +sys +. +path +. +append +( +os +. +path +. +dirname +( +os +. +path +. +dirname +( +__file__ +) +) +) +from +worker_interception_redirect_webworker +import +main diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/worker-interception-redirect-serviceworker.js b/testing/web-platform/tests/service-workers/service-worker/resources/worker-interception-redirect-serviceworker.js new file mode 100644 index 0000000000000..101aaf6e3aa13 --- /dev/null +++ b/testing/web-platform/tests/service-workers/service-worker/resources/worker-interception-redirect-serviceworker.js @@ -0,0 +1,394 @@ +let +name +; +if +( +self +. +registration +. +scope +. +indexOf +( +' +scope1 +' +) +! += +- +1 +) +name += +' +sw1 +' +; +if +( +self +. +registration +. +scope +. +indexOf +( +' +scope2 +' +) +! += +- +1 +) +name += +' +sw2 +' +; +self +. +addEventListener +( +' +fetch +' +evt += +> +{ +/ +/ +There +are +three +types +of +requests +this +service +worker +handles +. +/ +/ +( +1 +) +The +first +request +for +the +worker +which +will +redirect +elsewhere +. +/ +/ +" +redirect +. +py +" +means +to +test +network +redirect +so +let +network +handle +it +. +if +( +evt +. +request +. +url +. +indexOf +( +' +redirect +. +py +' +) +! += +- +1 +) +{ +return +; +} +/ +/ +" +sw +- +redirect +" +means +to +test +service +worker +redirect +so +respond +with +a +/ +/ +redirect +. +if +( +evt +. +request +. +url +. +indexOf +( +' +sw +- +redirect +' +) +! += +- +1 +) +{ +const +url += +new +URL +( +evt +. +request +. +url +) +; +const +redirect_to += +url +. +searchParams +. +get +( +' +Redirect +' +) +; +evt +. +respondWith +( +Response +. +redirect +( +redirect_to +) +) +; +return +; +} +/ +/ +( +2 +) +After +redirect +the +request +is +for +a +" +webworker +. +py +" +URL +. +/ +/ +Add +a +search +parameter +to +indicate +this +service +worker +handled +the +/ +/ +final +request +for +the +worker +. +if +( +evt +. +request +. +url +. +indexOf +( +' +webworker +. +py +' +) +! += +- +1 +) +{ +const +greeting += +encodeURIComponent +( +{ +name +} +saw +the +request +for +the +worker +script +) +; +evt +. +respondWith +( +fetch +( +worker_interception_redirect_webworker +. +py +? +greeting += +{ +greeting +} +) +) +; +return +; +} +/ +/ +( +3 +) +The +worker +does +a +fetch +( +) +to +simple +. +txt +. +Indicate +that +this +service +/ +/ +worker +handled +the +request +. +if +( +evt +. +request +. +url +. +indexOf +( +' +simple +. +txt +' +) +! += +- +1 +) +{ +evt +. +respondWith +( +new +Response +( +{ +name +} +saw +the +fetch +from +the +worker +) +) +; +} +} +) +; diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/worker-interception-redirect-webworker.js b/testing/web-platform/tests/service-workers/service-worker/resources/worker-interception-redirect-webworker.js new file mode 100644 index 0000000000000..361a499cf77d2 --- /dev/null +++ b/testing/web-platform/tests/service-workers/service-worker/resources/worker-interception-redirect-webworker.js @@ -0,0 +1,288 @@ +/ +/ +This +is +the +( +shared +or +dedicated +) +worker +file +for +the +/ +/ +worker +- +interception +- +redirect +test +. +It +should +be +served +by +the +corresponding +/ +/ +. +py +file +instead +of +being +served +directly +. +/ +/ +/ +/ +This +file +is +served +from +both +resources +/ +* +webworker +. +py +and +/ +/ +resources +/ +scope2 +/ +* +webworker +. +py +hence +some +of +the +complexity +/ +/ +below +about +paths +. +const +resources_url += +new +URL +( +" +/ +service +- +workers +/ +service +- +worker +/ +resources +/ +" +self +. +location +) +; +/ +/ +This +greeting +text +is +meant +to +be +injected +by +the +Python +script +that +serves +/ +/ +this +file +to +indicate +how +the +script +was +served +( +from +network +or +from +/ +/ +service +worker +) +. +/ +/ +/ +/ +We +can +' +t +just +use +a +sub +pipe +and +name +this +file +. +sub +. +js +since +we +want +/ +/ +to +serve +the +file +from +multiple +URLs +( +see +above +) +. +let +greeting += +' +% +GREETING_TEXT +% +' +; +if +( +! +greeting +) +greeting += +' +the +shared +worker +script +was +served +from +network +' +; +self +. +onconnect += +async +function +( +e +) +{ +const +port += +e +. +ports +[ +0 +] +; +port +. +start +( +) +; +port +. +postMessage +( +greeting +) +; +const +fetch_url += +new +URL +( +' +simple +. +txt +' +resources_url +) +; +const +response += +await +fetch +( +fetch_url +) +; +const +text += +await +response +. +text +( +) +; +port +. +postMessage +( +' +fetch +( +) +: +' ++ +text +) +; +} +; diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/worker_interception_redirect_webworker.py b/testing/web-platform/tests/service-workers/service-worker/resources/worker_interception_redirect_webworker.py new file mode 100644 index 0000000000000..1fddfea10143e --- /dev/null +++ b/testing/web-platform/tests/service-workers/service-worker/resources/worker_interception_redirect_webworker.py @@ -0,0 +1,163 @@ +# +This +serves +the +worker +JavaScript +file +. +It +takes +a +| +greeting +| +request +# +parameter +to +inject +into +the +JavaScript +to +indicate +how +the +request +# +reached +the +server +. +import +os +import +sys +def +main +( +request +response +) +: + +path += +os +. +path +. +join +( +os +. +path +. +dirname +( +__file__ +) + +" +worker +- +interception +- +redirect +- +webworker +. +js +" +) + +body += +open +( +path +" +rb +" +) +. +read +( +) + +if +" +greeting +" +in +request +. +GET +: + +body += +body +. +replace +( +" +% +GREETING_TEXT +% +" +request +. +GET +[ +" +greeting +" +] +) + +else +: + +body += +body +. +replace +( +" +% +GREETING_TEXT +% +" +" +" +) + +headers += +[ +] + +headers +. +append +( +( +" +Content +- +Type +" +" +text +/ +javascript +" +) +) + +return +headers +body diff --git a/testing/web-platform/tests/service-workers/service-worker/worker-interception-redirect.https.html b/testing/web-platform/tests/service-workers/service-worker/worker-interception-redirect.https.html new file mode 100644 index 0000000000000..d0367abd4e34e --- /dev/null +++ b/testing/web-platform/tests/service-workers/service-worker/worker-interception-redirect.https.html @@ -0,0 +1,1560 @@ +< +! +DOCTYPE +html +> +< +title +> +Service +Worker +: +controlling +a +SharedWorker +< +/ +title +> +< +script +src += +" +/ +resources +/ +testharness +. +js +" +> +< +/ +script +> +< +script +src += +" +/ +resources +/ +testharnessreport +. +js +" +> +< +/ +script +> +< +script +src += +" +resources +/ +test +- +helpers +. +sub +. +js +" +> +< +/ +script +> +< +body +> +< +script +> +/ +/ +This +tests +service +worker +interception +for +worker +clients +when +the +request +/ +/ +for +the +worker +script +goes +through +redirects +. +For +example +a +request +can +go +/ +/ +through +a +chain +of +URLs +like +A +- +> +B +- +> +C +- +> +D +and +each +URL +might +fall +in +the +/ +/ +scope +of +a +different +service +worker +if +any +. +/ +/ +The +two +key +questions +are +: +/ +/ +1 +. +Upon +a +redirect +from +A +- +> +B +should +a +service +worker +for +scope +B +/ +/ +intercept +the +request +? +/ +/ +2 +. +After +the +final +response +which +service +worker +controls +the +resulting +/ +/ +client +? +/ +/ +/ +/ +The +standard +prescribes +the +following +: +/ +/ +1 +. +The +service +worker +for +scope +B +intercepts +the +redirect +. +* +However +* +once +a +/ +/ +request +falls +back +to +network +( +i +. +e +. +a +service +worker +did +not +call +/ +/ +respondWith +( +) +) +and +a +redirect +is +then +received +from +network +no +service +/ +/ +worker +should +intercept +that +redirect +or +any +subsequent +redirects +. +/ +/ +2 +. +The +final +service +worker +that +got +a +fetch +event +( +or +would +have +in +the +/ +/ +case +of +a +non +- +fetch +- +event +worker +) +becomes +the +controller +of +the +client +. +/ +/ +/ +/ +The +standard +may +change +later +see +: +/ +/ +https +: +/ +/ +github +. +com +/ +w3c +/ +ServiceWorker +/ +issues +/ +1289 +/ +/ +/ +/ +The +basic +test +setup +is +: +/ +/ +1 +. +Page +registers +service +workers +for +scope1 +and +scope2 +. +/ +/ +2 +. +Page +requests +a +worker +from +scope1 +. +/ +/ +3 +. +The +request +is +redirected +to +scope2 +or +out +- +of +- +scope +. +/ +/ +4 +. +The +worker +posts +message +to +the +page +describing +where +the +final +response +/ +/ +was +served +from +( +service +worker +or +network +) +. +/ +/ +5 +. +The +worker +does +a +fetch +( +) +and +posts +back +the +response +which +describes +/ +/ +where +the +fetch +response +was +served +from +. +/ +/ +/ +/ +Currently +this +only +tests +shared +worker +but +dedicated +worker +tests +should +be +/ +/ +added +in +a +future +patch +. +/ +/ +Globals +for +easier +cleanup +. +const +scope1 += +' +resources +/ +scope1 +' +; +const +scope2 += +' +resources +/ +scope2 +' +; +let +frame +; +function +get_message_from_worker +( +worker +) +{ +return +new +Promise +( +resolve += +> +{ +worker +. +port +. +onmessage += +evt += +> +{ +resolve +( +evt +. +data +) +; +} +} +) +; +} +async +function +cleanup +( +) +{ +if +( +frame +) +frame +. +remove +( +) +; +const +reg1 += +await +navigator +. +serviceWorker +. +getRegistration +( +scope1 +) +; +if +( +reg1 +) +await +reg1 +. +unregister +( +) +; +const +reg2 += +await +navigator +. +serviceWorker +. +getRegistration +( +scope2 +) +; +if +( +reg2 +) +await +reg2 +. +unregister +( +) +; +} +/ +/ +Builds +the +worker +script +URL +which +encodes +information +about +where +/ +/ +to +redirect +to +. +The +URL +falls +in +sw1 +' +s +scope +. +/ +/ +/ +/ +- +| +redirector +| +is +" +network +" +or +" +serviceworker +" +. +If +" +serviceworker +" +sw1 +will +/ +/ +respondWith +( +) +a +redirect +. +Otherwise +it +falls +back +to +network +and +the +server +/ +/ +responds +with +a +redirect +. +/ +/ +- +| +redirect_location +| +is +" +scope2 +" +or +" +out +- +of +- +scope +" +. +If +" +scope2 +" +the +/ +/ +redirect +ends +up +in +sw2 +' +s +scope2 +. +Otherwise +it +' +s +out +of +scope +. +function +build_worker_url +( +redirector +redirect_location +) +{ +let +redirect_path +; +/ +/ +Set +path +to +redirect +. +py +a +file +on +the +server +that +serves +/ +/ +a +redirect +. +When +sw1 +sees +this +URL +it +falls +back +to +network +. +if +( +redirector += += +' +network +' +) +redirector_path += +' +redirect +. +py +' +; +/ +/ +Set +path +to +' +sw +- +redirect +' +to +tell +the +service +worker +/ +/ +to +respond +with +redirect +. +else +if +( +redirector += += +' +serviceworker +' +) +redirector_path += +' +sw +- +redirect +' +; +let +redirect_to += +base_path +( +) ++ +' +resources +/ +' +; +/ +/ +Append +" +scope2 +/ +" +to +redirect_to +so +the +redirect +falls +in +scope2 +. +/ +/ +Otherwise +no +change +is +needed +as +the +parent +" +resources +/ +" +directory +is +/ +/ +used +and +is +out +- +of +- +scope +. +if +( +redirect_location += += +' +scope2 +' +) +redirect_to ++ += +' +scope2 +/ +' +; +/ +/ +Append +the +name +of +the +file +which +serves +the +worker +script +. +redirect_to ++ += +' +worker_interception_redirect_webworker +. +py +' +; +return +scope1 +/ +{ +redirector_path +} +? +Redirect += +{ +redirect_to +} +} +promise_test +( +async +t += +> +{ +await +cleanup +( +) +; +const +service_worker += +' +resources +/ +worker +- +interception +- +redirect +- +serviceworker +. +js +' +; +const +registration1 += +await +navigator +. +serviceWorker +. +register +( +service_worker +{ +scope +: +scope1 +} +) +; +await +wait_for_state +( +t +registration1 +. +installing +' +activated +' +) +; +const +registration2 += +await +navigator +. +serviceWorker +. +register +( +service_worker +{ +scope +: +scope2 +} +) +; +await +wait_for_state +( +t +registration2 +. +installing +' +activated +' +) +; +promise_test +( +t += +> +{ +return +cleanup +( +) +; +} +' +cleanup +global +state +' +) +; +} +' +initialize +global +state +' +) +; +function +worker_redirect_test +( +worker_url +expected_main_resource_message +expected_subresource_message +description +) +{ +promise_test +( +async +t += +> +{ +/ +/ +Create +a +frame +to +load +the +worker +from +. +This +way +we +can +remove +the +frame +/ +/ +to +destroy +the +worker +client +when +the +test +is +done +. +frame += +await +with_iframe +( +' +resources +/ +blank +. +html +' +) +; +t +. +add_cleanup +( +( +) += +> +{ +frame +. +remove +( +) +; +} +) +; +/ +/ +Start +the +worker +. +const +w += +new +frame +. +contentWindow +. +SharedWorker +( +worker_url +) +; +w +. +port +. +start +( +) +; +/ +/ +Expect +a +message +from +the +worker +indicating +which +service +worker +/ +/ +provided +the +response +for +the +worker +script +request +if +any +. +const +data += +await +get_message_from_worker +( +w +) +; +assert_equals +( +data +expected_main_resource_message +) +; +/ +/ +The +worker +does +a +fetch +( +) +after +it +starts +up +. +Expect +a +message +from +the +/ +/ +worker +indicating +which +service +worker +provided +the +response +for +the +/ +/ +fetch +( +) +if +any +. +/ +/ +/ +/ +Note +: +for +some +reason +Firefox +would +pass +all +these +tests +if +a +/ +/ +postMessage +ping +/ +pong +step +is +added +before +the +fetch +( +) +. +I +. +e +. +if +the +/ +/ +page +does +postMessage +( +) +and +the +worker +does +fetch +( +) +in +response +to +the +/ +/ +ping +the +fetch +( +) +is +properly +intercepted +. +See +/ +/ +https +: +/ +/ +bugzilla +. +mozilla +. +org +/ +show_bug +. +cgi +? +id += +1452528 +. +( +Chrome +can +' +t +pass +/ +/ +the +tests +either +way +. +) +const +message += +get_message_from_worker +( +w +) +; +const +data2 += +await +message +; +assert_equals +( +data2 +expected_subresource_message +) +; +} +description +) +; +} +worker_redirect_test +( +build_worker_url +( +' +network +' +' +scope2 +' +) +' +the +shared +worker +script +was +served +from +network +' +' +fetch +( +) +: +sw1 +saw +the +fetch +from +the +worker +' +' +request +to +sw1 +scope +gets +network +redirect +to +sw2 +scope +' +) +; +worker_redirect_test +( +build_worker_url +( +' +network +' +' +out +- +scope +' +) +' +the +shared +worker +script +was +served +from +network +' +' +fetch +( +) +: +sw1 +saw +the +fetch +from +the +worker +' +' +request +to +sw1 +scope +gets +network +redirect +to +out +- +of +- +scope +' +) +; +worker_redirect_test +( +build_worker_url +( +' +serviceworker +' +' +scope2 +' +) +' +sw2 +saw +the +request +for +the +worker +script +' +' +fetch +( +) +: +sw2 +saw +the +fetch +from +the +worker +' +' +request +to +sw1 +scope +gets +service +- +worker +redirect +to +sw2 +scope +' +) +; +worker_redirect_test +( +build_worker_url +( +' +serviceworker +' +' +out +- +scope +' +) +' +the +shared +worker +script +was +served +from +network +' +' +fetch +( +) +: +sw1 +saw +the +fetch +from +the +worker +' +' +request +to +sw1 +scope +gets +service +- +worker +redirect +to +out +- +of +- +scope +' +) +; +< +/ +script +> +< +/ +body +>