W3C

- DRAFT -

Web Platform WG - Service Workers

20 Sep 2016

See also: IRC log

Attendees

Present
jakeA, jungkees, hober, weinig, chaals, Salvador, Kris_Borchers, Nathan_Schloss, yoav, Brad_Hill, annevk, Kenji, ilya, bz, Alex_Russell, yves, xiaoqian, toddreifsteck, Jatinder_Mann, Mike_West, Joshua, esprehn, Ali_Alabbas, Ben_Kelly, Domemic
Regrets
Chair
jakeA
Scribe
chaals, xiaoqian

Contents


<jungkees> https://github.com/w3c/ServiceWorker/issues/974

<chaals> scribe: chaals

agenda-bashing

<bz> What's the link to the stuff we're looking at right now?

CMN: Please make sure you are signed up to the group if you're contributing substantive content.

V1 update

Jungkee: we've got 24 issues, half solved and need to be edited in, so the agenda issue has the rest.

<jungkees> https://github.com/w3c/ServiceWorker/issues/816

Jungkee: there are a couple of issues, already decided-ish: 816
... same object cannot be used for union type in IDL

<jungkees> https://github.com/heycam/webidl/issues/71

Jungkee: filed in WebIDL as an issue. Want to check the status.

BZ: This is an IDL bug that should be fixed - just assume it will happen.

JS: OK

<jungkees> https://github.com/w3c/ServiceWorker/issues/873

873

JS: related to fetch. we have API that can probably use fetch event cache attribute.

AvK: This is for normal reload stuff? not shift?

JA: We don't get shift through the service worker.

AvK: Why do we want this

JA: Alex made the case...

BZ: navigating to yourself is semantically different to reloading yourself - at least sometimes.

SW: cache strategies are different.

JA: If you trigger reload you *might* move from offline-first to online-first …
... cache mode of the request would reflect that

AvK: Hmmm.

<jungkees> This is exactly this issue: https://github.com/w3c/ServiceWorker/issues/875

JA: Won't go to cache on reload, will re-validate.

AvK: Do we want to expose that?
... would need a hidden flag.

JA: Why hide it?

AvK: Then script can bypass the action...

JA: service workers *do* that.

JS: In normal reload serviec worker can do what it wants. For full reload it should bypass the service worker.

JA: We already have that.
... with client API we know the page that triggered the request is the same as the URL you are asking for.
... does cache mode reflect this?

AvK: May be implementation-specific what reload does.

??:If you hit the button we may have different things we do. It's up to the UA to decide what to do, but we want to match the service worker process.

JA: We should reflect what the user wants to do. If you follow a live feed, and you hit reload, you might want to get the new stuff off the network, not the cache.
... We have cache mode where you can skip the HTTP cache…
... think the cache mode should reflect what the browser thinks it is doing.

AvK: So UX reload, navigation to self, and location.reload can be different?

KB: We currently have two kinds of behaviour, but we want to have just one

SW: I'd have to write a test to see exactly what we do.
... think we revalidate main resource if you hit return in the address bar, and reload button validates sub resources on cache.

Salvador: There should be a way to say "this reload is meant to bypass the cache."

JA: If browsers do different things - it isn't specced - we can expect different behaviours. Do we want to expose a user intent to refresh?
... Is this a feature that is useful?

AvK: We can define location.reload in one way or another. If we reflect that in cache mode that would be easy, then suggest the UI gestures should behave in the same way.

N8: Yep.

JS: Can we drop the reloaded thing then?

JA: If browser decides what a reload button does, do you want the website to follow howthe browser intends its UI to work, or do you want to know what the user asked?

N8: We want to know what the browser is going to do in regards to how it will treat the HTTP cache.

JA: So that would be enough to replae the isReload property?

AvK: We don't need to define shift-reload, but if normal reload affects resources then we need an inheritane model to store cache mode

JA: Browser does this already, so it's just a hook in the spec to keep that data.

AvK: if location.reload only reloads the main resource, then you only need to handle that request not a fetch-group policy

JA: Should it be in spec?

AvK: There's no API for it, so no...

AR: isReload can't be killed...

JA: But this does it instead.
... look at request.cache ...

AR: This is the ugliest way to do it.
... this is reload plus top-level navigation.

JA: You see browser intent here. It's consistent for document reloads.

AR: OK.
... It's still ugly.

AvK: Not sure if this is a comon pattern - if it is we could add a shortcut

AR: Use case: Google Docs team
... needs to know.

SW: There are at least 4 different kinds of reload…

BZ: 5

SW: Each browser has different behaviour for all of these.

AR: We said that if you were going to bypass the cache you should bypass the service worker.

AvK: Doesn't happen for location.reload
... there you go through the worker but not cache.

SW: We should try to understand how browsers handle reload, in the future

<annevk> bz: https://github.com/whatwg/html/issues/1742

<jungkees> https://github.com/w3c/ServiceWorker/issues/875

Issue 875

JS: This is covered by what we discussed.

Issue 870

-> https://github.com/w3c/ServiceWorker/issues/875 Issue 875

JS: There is no concept like reserved client ID. We designed a reserved client ID to reference target client environment of a request.
... expose this as source / target of a fetch.
... was having a hard time speccing this, because the HTML navigation doesn't have a concept like this.
... When a navigation is triggered we have to create some state that holds the ID, URL and origin of the request to pass into fetch.
... propose fetch have a client, passed through end of fetch, that developers can use. Fetch returns to HTML and HTML creates the status object. Plan is to override the ID at the end, we're discussing the design now.
... AvK thinks the design is a bit odd. I need the client ID…

AvK: New info is that you need a reserved ID.
... we should just add the ID and pass it on the request.
... then you make a collection of IDs and settings objects.
... An environment settings object without a global object or realm, is pretty weird…
... So change the API to also operate on reserved IDs instead.

JA: So under the hood there is onformation coming from different places…

AvK: Right - either reservedID or an environment settings object.

JA/JS: OK

JS: So we need to refer to targetn client ID. It's browsing context, because we need to refer to UI properties, for use in the service worker

AvK: What info?

JS: Visibility state, focus state.

AvK: That's in browsing context or document?

JS: I capture that info during method call.

AvK: What about target window object not browsing context. You can check if it is active, or abort.

JS: Target client should be a regular client.

AvK: There will be differnce where there is another navigation, and they race.

JA: When you click a link and there is a target as iframe or window.

AvK: Represent target by current active document, whatever that is at the time you check.

JA: WOud be weird for the ID of a client to change ...

AvK: not in browsing context.
... why not pass the info before you enter, and not going back and forward.

JS: We capture the info in the client's context, create object in service worker. So it doesn't cross.

AvK: Yes, you do when fetch goes async.
... better to pass that to fetch from the start.

JA: This proposal is to do that.

AvK: No. This is reserved.

JA: We suggest both. 3 IDs on the fetch.

JS: We hvae to go to client context to get visibility state. So we capture that from client context, service worker is waiing on the state, intialises it with what we captured.

JA: There is a task to get the properties, but the IDs just live on the fetch event. At one point we have client objects on it, but that was really heavy.

JS: Problem that client we get later could be different

JA: Already can.

JS: We can capture ID during creation.

JA: The client might be gone when you look for it, but you have the IDs

JS: Need both the browsing context and the ID …
... So, how to design this - an we do superclassing for those two?

AvK: ID is a new field on environment settings object. You could have a base class with ID, and env.settings is a subclass with more fields.
... sounds OK, if it's OK with Domenic.

JS: OK, I'll discuss that outside.

I am a fish

Longdesc

Issue 887

JA: It's important to have the fist client by creation time.
... seems to make sense to focus the most recent one

SW: I think we will be fine

N8: think that is OK.

JA: Doing it by focused order will be a bigger task

SW: Yeah, but not that big.

JM: What's the value?

JA: If you've got a window that's been sitting three days, and another that you were using 5 minutes ago, pick that one…

AvK: Most recently focused same-origin?

SW: Yep. We could find most-recently focused of all origins, ...

JA: Seems easy.
... we track focus ordering for everything.

SW: We recently added a lot more timestamped tracking.

JM: Yes, this is OK.

SW: We're OK with this.

Issue: 893

JA: We agreed on this. Lots of long max-age for JS resources. We cap it for 24 hours already, but it's a real gotcha.

<slightlyoff> https://github.com/w3c/ServiceWorker/issues/893

JA: we're planning to make it always revalidate with a way to opt back into cache, and that's the bit we are missing.

AR: Still capping on 24 hours?

JA: Yes.

JS: Change this for v1?

JA: Yes.

JS: Suggest install API not register option?

AvK: Seems good.

JA: Yeah...
... [thinks]
... lots of options are on registration - it's a choice of the two

AvK: prefer install, so you don't need to remove and add.

JA: If it's on registration you could set it in install. Benefit of install is you can have a default that takes over if a new service worker doesn't have an opinion.

N8: Can you read it later if it is on install?

JA: Probably not. On registration it's set and forget…

N8: Can't think why we would want to use the value later, but think people are going to want that...

AvK: Why couldn't you still expose this on register?
... do you need to unregister?

JA: Scope is primary key, you can change values without unregistering.

AR: You do get a new registration.

JA: If you change URL you get an update. Otherwise tehre is a noop. So feels like it should sit on registration

[yeah whatevs]

AvK: We don't have a good strategy for choosing between register and install.

JA: Would like to remove foreignFetch from install...

AR: There are those two and activate as places to put stuff.
... Thought if caches should be tied to the worker. Desgined it against that. There isn't a lot of state hanging around on register or service worker. relationship is dynamic.

JA: If it lives as long as registration it needs to go on the registration object.
... don't think we should put too much on actiavte because that casuses blocking.

[blue! Green! …]

AvK: We can start with true as a keyword, and add an enum if we ever need to.

path to CR

JS: We're planning to publish the FPWD for v2 now to get the latest features, and publish a draft for v1 heading to Rec.
... my question is if we can skip an exclusion.
... until the next version. We did it with CR of the next spec.
... purpose is to see the gap between the CR and the latest draft of v2
... this can produce quite a lot of burden maintaining two versions.

<inserted> scribe: xiaoqian

chaals: once you publish the CR, you don't want to change it any more
... when you make a FPWD, you have to start a CFE
... people have 60 days from the day of CR for exclusion
... you must have those two CfE
... CR is your nightly

Yves: You might like to put a link to latest version
... which should fit in the model for SW
... the min time to move a spec to REC (?) is 6 months

slightlyoff: you can maintain two branches
... one is the latest
... one is the stable

JakeA: we have nightly for v1, which is the one missing foreign fetch

Yves: you can focus on updating the latest, once you have something stable, put it to ...

jungkees: let's go with adrianba's proposal

JM: we have a v1...

jungkees: /TR/ServiceWorkers always refers to the latest

<chaals> scribe: chaals

879

JA: We'll do this after v1

<Yves> naming nit, I would prever "level 1" over "v1", but that's up to the grop

703

JA: This is security and work.
... HTML doesn't talk about range requests but browsers do it. We can't do it in service worker we need this in HTML and they need to defend against ranges from multiple origins.

SW: We ran into this with service workers.
... range requests plus CSP plus media engines == bad time.
... so, agree. Needs to be dealt with in HTML

JA: Not blocking for v1

JS: We're done now for this?

JA: Yep. Service worker can't do this, so we need it in HTML.

AvK: Seeing range requests for images now.

JA: Chrome can be persuaded to do it for CSS…

HEIST

JA: Heist was revealed - series of attacks where we provide info about size of a x-origin resource when we shouldn't.
... e.g. a search will be a different size if there is a match or not, detectable through timing or cache-based attacks.
... Ryan Sleevi said we should stop trying to fiddle the edges, and block at the source. Would be opt-in, e.g. using mike west's proposal for same site cookies.

BH: No great soluton, like Ryan's intuition. Almost impossible to beat these side channels because it is hard to disguise elephants as mice.
... shouldn't expose privacy-differentiated data gives up on a lot of what we expect from teh same origin policy, involves pretty serious changes in how we use the web.
... would like to find other ways to provide systematic answers that make it harder to get high-precision views from side channels.
... randomisation is a strategy. Defeatable by statistical samples.
... bucketising things?
... this would have a big impact.

AvK: This has been broken for a long time, right?

BH: Yep. We have access control for timing to set resolution of views available.

AvK: we're trying to minimise storage attacks - we've made estimating sizes easier.

AR: We have that already.

SW: What's the use case for x-origin storage in search cache

AR: Website includes 3rd party JS. We don't want the responses for that to be exposed.

JA: We culd say put CORS on your CDNs. Might work…
... if your CSS is on CDN there is no way to request a background image with CORS

AvK: We made a big effort to cache things…

AR: If you're not doing anything in service worker, it's a noop.

JA: upgrading CSS to CORS is a wrapping issue.

SW: Should we have been explicit about resources you can cache being cached x-origin?

[What the web would like like if we made it tomorrow…]

JA: Mike you are disagreeing with opt-in solutions?

MW: Would be nice if we could do something else - but we haven't figured out what that could be yet.
... you have timing attacks, and those are hard to fight.
... bucketise or reduce data granularity.
... and there are explicit things like quota giving data.
... have we considered applying quotas based on origins?

AR: Value of cache API is that you know what is in it. That's the property we want to preserve. We want to be able to have 3rd party things in it.

AvK: Then you get persisitent storage, and if the quota doesn't count against yourself, who does it count against?

AR: If you evict today you evict the entire cache not one entity

MW: We give a handle to a resource, that might be in someone else's cache. You lose the reference, but the other guys do.
... or we do some GC-like approach.

AR: You need to know when you are going to have a write failure. I write into a cache as a 3rd party, I'm near the limit and want to write something too big. Do i have a write error?

MW: Yes. But you wont know the size of the 3rd party cache.

[yes, if you filled it up to start with...]

MW: I see it as a better problem to solve, and if we assign blame for putting things into a cache we can deal with the issue.

SW: We do something like this already…

MW: Think this would be the inverse, allowing one origin to put things into another one.

SW: Sure, but technique is the same

JA: Think the storage issue can be dealt with by padding, but timing attacks are harder...

BH: They an be solved to a certain resolution.

Brad is sad. 3 ways.

scribe: would hate to take away a whole class of functionality.
... Can we let people opt in, and then give people choices to do work to get more perf or security.

JA: If we have same-site cookies and let requests opt out via CORS preflight, does that solve it?

BH: Nope. Don't want random 3rd party sites make requests to things and learn about them
... want to show differentiated content without leaking data about which user is there.

[frames, framebusting. There are use cases for wanting to be, or not be, framed]

MW: If you have no-opener, you get problems knowing if you're framed, and where.

ES: Giving you no-opener but having ancestor origin gets around a bunch of that.

AR: To what extent is this a service worker problem?

JA: It's an img problem.

[break - 15 minutes]

storage…

Uploading

issue - fetch-with-streams 66

DomenicD: problem - what if you upload to endpoint and get a redirect?
... or asked for credentials. These are realistic scenarios…

<kbx> https://github.com/yutakahirano/fetch-with-streams/issues/66

DomenicD: could say "redirect-mode error", otherwise you get the problem…
... Teeing is bad, because you can't delete bits of the stream.

JA: This is where we are now?

DD: Yep. We're trying to allow streaming uploads not hold the whole thing in memory

JA: Do we want stream representing progress?

DD: Separate question.
... idea is to have a new status code "won't send 301/4xx" so you can drop the rest of the Tee

YL: in HTTP 1.1 people were sending an expect 101 to ask if they could send a payload. Looks like this

AvK: Looked at it. If you get a 101 there is no guarantee on not getting redirect later. And the expect thing didn't work

YL: broken because of caches.

AvK: That status code is not needed for v1

JA: Not all codes require resending?
... reposting is the exception.

AvK: 301 for PUT doesn't go to GET
... if you see 303 you can stop teeing.

JA: But you've sent the thing

DD: No, the response can come any time during the transfer.

AvK: New code is when you need the whole body, but you know you won't redirect.

JA: If function returned a promise for a stream does that expose the redirect?

AvK: Yep.
... you can detect the number of endpoints.
... people didn't want to deviate from existing model.

DD: v0 just dies on 301/4xx, v1 opt into allowing with maybe needing to buffer everything, v2 with new status code lets you optimise and throw away the rest of the body

AvK: Requestere doesn't know about redirects and wants to follow.
... server knows if they will redirect. Send early 199, wait with the final status. So client can discard tee early on.

DD: Client runs into redirect, so allows it, but asks servers to provide 199 to help the client.
... pushing to the future is fine, this is niche.

JA: Michael fails on redirects, nobody cared.

DD: Was looking to see if people cared.

JA: Dev could turn a stream into a blob.
... if you have to do full buffering, why not? I suppose you can start earlier, but it's not much.

AvK: you get network error with redirect, 401, 407
... we could allow 303.
... you post to a generic endpoint, and get redirected to the comment page you came from

DD: Do we opt you in automatically?

JA: Yep.
... you provided a stream already.

AvK: Want to allow 303

JA: If you get redirect manual, you don't know what you're getting

DD: Problem is error is not programatically treatable.

AvK: Should we expose different classes of errors… oh look, worms.
... if you get a redirect other than 303 for an upload of a stream or 401 or 407, you get a network error

JA: This seems fine

SW: I agree with Alex.

upload progress

DD: originally we figured you could track how much of your stream is uploaded. What if you have a blob?
... API is uncomfortable. People do New request(blob.body)

AvK: XHR makes progress easy, getting UI from fetch is pretty low-level.

DD: Think the concern is ergonomic.

AR: Is making a blob into a stream OK?

DD: People are hacking this so we should do it. e.g. blob.toStream or vice versa

JA: You'll need to observe your stream to get progress

DD: Yeah, and it takes a bunch of low-level work to follow the stream's progress.

[which side of the shed does the door go on]

JA: If I have formdata with a bunch of things, it's blergh

DD: Dislike factories…

JA: We would need to know the size, and add tostream to formdata.

DD: You need size to know upload progress.

AvK; You can still say how much transferred.

SW: This was done for progress events

AvK: But not for streams.

DD: Right. So you'll need to find the size somehow.

JA: .toStream all the Thingz!
... plus a .size

SW: forces serialisation eagerly on a lazy object

JA: Doesn't need to be.

AvK: We can make it sync because blob is sync

ES: We may send the serialising somewhere else.

SW: You know the boundary size.

ES: Once you escape all the values. If the code exists.

JA: If .toStream() returns a bounded stream with .size it can be a promise

DD: awkward… you figure out size when it goes to the network code.
... we could add a magic uploadProgress API
... strawman on init...

ES: You want a progress handle, right?

JA: Yep, a callback with amount-sent and total

ES: Or wrap the blob and it's a drain you can watch. It's simpler with an uploadObserverFactoryThingy

DD: Trying to make streams single observer only. This is probably fine.

JA: a bounded stream would be good for download progress, too.

DD: Interesting

AvK: can't expose total easily. Fetch will have a notion for blob and stuff.

JA: Don't need to give total until the first call of the callback.

AvK: This means you require streams at each end.
... which is extra work in a simple case.

AR: Would like to see what pattern comes out here

DD: This looks like it will set a precedent

SW: Looks like observables.

RESOLUTION: lunch is good

[no scribing, follow the agenda issue to get to the issues being discussed]

upload requests

-> https://github.com/w3c/ServiceWorker/issues/920#issuecomment-245621515 upload requests

note: We need to make sure this header doesn't get copied over on redirect.

note: Some users are detecting the Service-Worker header and thinking it's a SW script request, so we should use a different header: Navigation-Preload: true by default, but can be set to any value

note: It'd be nice to have self. that refers to this service worker instance in a service worker global (self.own)

note: The header needs to be settable at any point.

note: The setting should live with the lifecycle of the service worker.

note: Need a way to clear it.

// this can be called at any point
registration.active.setNavigationPreload({
  value: 'true' // header value
}).then(() => console.log(`It's set!`));

registration.active.getNavigationPreload()
  .then(settings => console.log(settings.value));

self.addEventListener('fetch', event => {
  event.respondWith(event.navigationPreload || fetch(event.request));
});

[break]

[resume in 15 minutes]

<TabAtkins> This "no scribing" thing sucks pretty bad. It means people who have difficulty following live discussions are excluded, and it kills discussion context for the decisions that get recorded.

background cache

<note> background cache

RESOLUTION: Put Background Cache in the WICG

Multiple instances

<note> Multiple instances

note: Could Chrome add an option to devtools to close/clear the service worker after each event - this would be super slow because it's handling things in series, but it's a good validation tool.

Sam: the main worry is heavy processing in the SW.

note: Edge/Safari need to prove that multiple instances is beneficial, but we're open to doing what we can to support this if it turns out to be beneficial.

note: Reminder for @jakearchibald: Facebook double-request so the browser will show the real error page - we should fix this in Chrome.

Next F2F

note: March, in Asia maybe.

Summary of Action Items

Summary of Resolutions

  1. lunch is good
  2. Put Background Cache in the WICG
[End of minutes]

Minutes formatted by David Booth's scribe.perl version 1.144 (CVS log)
$Date: 2016/09/20 15:47:22 $

Scribe.perl diagnostic output

[Delete this section before finalizing the minutes.]
This is scribe.perl Revision: 1.144  of Date: 2015/11/17 08:39:34  
Check for newer version at http://dev.w3.org/cvsweb/~checkout~/2002/scribe/

Guessing input format: RRSAgent_Text_Format (score 1.00)

Succeeded: s/cient/client/
Succeeded: s/.. AvK/… AvK/
Succeeded: s/873/887/
Succeeded: s/join #webdriver//
Succeeded: s/angenda-bashing/agenda-bashing/
Succeeded: i/once you publish the CR, you don't want to change it any more/scribe: xiaoqian
Succeeded: s/webapps/platform/
Found Scribe: chaals
Inferring ScribeNick: chaals
Found Scribe: xiaoqian
Inferring ScribeNick: xiaoqian
Found Scribe: chaals
Inferring ScribeNick: chaals
Scribes: chaals, xiaoqian
ScribeNicks: chaals, xiaoqian
Present: jakeA jungkees hober weinig chaals Salvador Kris_Borchers Nathan_Schloss yoav Brad_Hill annevk Kenji ilya bz Alex_Russell yves xiaoqian toddreifsteck Jatinder_Mann Mike_West Joshua esprehn Ali_Alabbas wanderview
Got date from IRC log name: 20 Sep 2016
Guessing minutes URL: http://www.w3.org/2016/09/20-webapps-minutes.html
People with action items: 

[End of scribe.perl diagnostic output]