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

Add file backend support for Blob and related #11221

Merged
merged 1 commit into from Jun 1, 2016

Conversation

@izgzhen
Copy link
Contributor

izgzhen commented May 17, 2016

  • ./mach build -d does not report any errors
  • ./mach test-tidy --faster does not report any errors
  • These changes fix #10851, related to #11131
  • These changes do not require tests because the implementation is partial and can't work alone

Major changes

  1. Add new backend to Blob and a BlobImpl struct to abstract multiple backends
  2. Rewrite most interfaces of Blob to accommodate the change
  3. Change the read behaviour of FileReader, considering the case when blob is file-backed and not cached

The design is still immature, welcome comments!

Problems to resolve

  • I used DOMRefCell to cache the bytes in BlobImpl, is it sound?
  • The interfaces (like BlobImpl::get_bytes) handle requests in a default-to-empty way when the inner DataSlice is not cached. It might be possible to handle this condition better.

This change is Reviewable

@highfive
Copy link

highfive commented May 17, 2016

Heads up! This PR modifies the following files:

  • @KiChjang: components/script/dom/testbinding.rs, components/script/dom/file.rs, components/script/dom/xmlhttprequest.rs, components/net_traits/filemanager_thread.rs, components/net_traits/filemanager_thread.rs, components/script/dom/htmlformelement.rs, components/script/dom/filereader.rs, components/script/dom/websocket.rs, components/script/dom/blob.rs, components/script/dom/formdata.rs
@highfive
Copy link

highfive commented May 17, 2016

warning Warning warning

  • These commits modify script code, but no tests are modified. Please consider adding a test!
@izgzhen
Copy link
Contributor Author

izgzhen commented May 17, 2016

@Manishearth I refined the design a bit and I think we can push the progress of this thread in parallel with #11189

@mbrubeck mbrubeck assigned Manishearth and unassigned mbrubeck May 17, 2016
typeString: String,
isClosed_: Cell<bool>,
}

#[derive(Clone, JSTraceable)]
pub struct BlobImpl {
slice: DOMRefCell<Option<DataSlice>>,

This comment has been minimized.

Copy link
@Manishearth

Manishearth May 17, 2016

Member

Perhaps this should be an enum?

This comment has been minimized.

Copy link
@izgzhen

izgzhen May 17, 2016

Author Contributor

I am thinking about the possibility of caching here. If it is file-backed, we can put the cached content inside the other DataSlice field.

This comment has been minimized.

Copy link
@Manishearth

Manishearth May 17, 2016

Member

I'd rather have an enum here and within the FileId variant have an option for caching. As it stands slice = Some can mean cached or an in-memory slice, a clear boundary would be nicer and more Rusty.

}

pub fn get_bytes(&self) -> Vec<u8> {
match *self.slice.borrow() {

This comment has been minimized.

Copy link
@Manishearth

Manishearth May 17, 2016

Member

what if it's a file?

This comment has been minimized.

Copy link
@izgzhen

izgzhen May 18, 2016

Author Contributor

Currently I don't put any read operations in blob.rs, which means that the user needs to check if it is cached and then cache if necessary. Or, if the file is not cached, a empty slice or stuff with similar semantics will be returned.

This comment has been minimized.

Copy link
@Manishearth

Manishearth May 18, 2016

Member

I feel like blob.rs should handle get_bytes either way. Of course it shouldn't be the one doing the reading, but it should talk to the resource task and fetch the reads and handle caching.

This comment has been minimized.

Copy link
@izgzhen

izgzhen May 18, 2016

Author Contributor

It am not sure if it is possible to fetch a reference to the window within Blob itself, which means that I can access script_thread stuff.

This comment has been minimized.

Copy link
@Manishearth

Manishearth May 18, 2016

Member

blob.global() should work

@izgzhen izgzhen force-pushed the izgzhen:blob-file-backend branch from 87adc31 to 3c194a1 May 18, 2016
@highfive
Copy link

highfive commented May 18, 2016

New code was committed to pull request.

@izgzhen
Copy link
Contributor Author

izgzhen commented May 20, 2016

@Manishearth In order to get port to filemanger thread inside blob (by GlobalRef), I need to attach the filemanager_thread to worker (in workerglobalscope.rs). Currently the worker only has access to core_resource_thread (renamed from original resource_thread), rather than the combined ResourceThreads from which I can access the file manager. However I don't know if storage API (storage_thread I think) can be exposed to worker as well.

@jdm
Copy link
Member

jdm commented May 20, 2016

Exposing it won't hurt anything; the storage APIs aren't accessible from workers, so there hasn't been any need to make the storage thread available.

@Manishearth
Copy link
Member

Manishearth commented May 20, 2016

Any particular reason for workers not being able to use storage? If there's a security reason we should not even give workers an unused storage chan (sandboxing).

@Manishearth
Copy link
Member

Manishearth commented May 20, 2016

Seems like it used to be for security reasons but now it's just for "threading issues".

@izgzhen
Copy link
Contributor Author

izgzhen commented May 20, 2016

I didn't see any Exposed or similar in this spec http://www.w3.org/TR/2016/REC-webstorage-20160419/#the-storage-interface

@Manishearth
Copy link
Member

Manishearth commented May 20, 2016

Oh, sure, the spec doesn't let you, the question is: If a sandboxed worker was compromised with an RCE vulnerability and got access to storage data, is that an escalation of access?

Assuming that we have checks in place in the resource/storage thread that ensure that no process gets data from a different origin (we don't, but we should eventually), I don't think this is an issue. Also, I don't see us putting workers in separate processes, so if a worker thread is compromised the script thread would be compromised too anyway.

let file_manager: IpcSender<FileManagerThreadMsg> = unimplemented!();
let (chan, recv) = ipc::channel().unwrap();
let _ = file_manager.send(FileManagerThreadMsg::ReadFile(chan, id));
let result = recv.recv().unwrap();

This comment has been minimized.

Copy link
@Manishearth

Manishearth May 20, 2016

Member

Should we be handling/propagating errors here?

This comment has been minimized.

Copy link
@izgzhen

izgzhen May 20, 2016

Author Contributor

I think read_file can be made Option<DataSlice> and we can throw a script-level exception or something at the dom API where it is used (like Slice)

This comment has been minimized.

Copy link
@Manishearth

Manishearth May 20, 2016

Member

Result<DataSlice,()> and use try! or the ? operator, but yeah

@@ -313,7 +313,8 @@ impl HTMLFormElement {
content_disposition,
content_type));

result.push_str(from_utf8(&f.upcast::<Blob>().get_data().get_bytes()).unwrap());
let slice = f.upcast::<Blob>().get_slice();
result.push_str(from_utf8(&slice.get_bytes()).unwrap());

This comment has been minimized.

Copy link
@Manishearth

Manishearth May 20, 2016

Member

Not necessarily utf8 here? The charset can change.

We should handle errors too.

@Manishearth
Copy link
Member

Manishearth commented May 20, 2016

Almost done!

@izgzhen izgzhen force-pushed the izgzhen:blob-file-backend branch from 3c194a1 to 2579570 May 20, 2016
@highfive
Copy link

highfive commented May 20, 2016

New code was committed to pull request.

@bors-servo
Copy link
Contributor

bors-servo commented May 21, 2016

The latest upstream changes (presumably #10961) made this pull request unmergeable. Please resolve the merge conflicts.

@izgzhen izgzhen force-pushed the izgzhen:blob-file-backend branch from 2579570 to bc888d1 May 21, 2016
@@ -308,12 +308,17 @@ impl HTMLFormElement {
DispositionParam::Filename(Charset::Ext(String::from(charset.clone())),
None,
f.name().clone().into()));
/// XXX: unwrap

This comment has been minimized.

Copy link
@Manishearth

Manishearth May 23, 2016

Member

replace it with an expect

though in this case unwrap_or(text/plain) might be better?

This comment has been minimized.

Copy link
@izgzhen

izgzhen May 23, 2016

Author Contributor

Not sure, can't find related spec, maybe an empty ""?

This comment has been minimized.

Copy link
@Manishearth

Manishearth May 23, 2016

Member

Section 4.4, it defaults to text/plain

https://tools.ietf.org/html/rfc7578#section-4.4

@izgzhen izgzhen force-pushed the izgzhen:blob-file-backend branch from bc888d1 to 4bf9943 May 23, 2016
@bors-servo
Copy link
Contributor

bors-servo commented May 23, 2016

The latest upstream changes (presumably #11225) made this pull request unmergeable. Please resolve the merge conflicts.

@izgzhen izgzhen force-pushed the izgzhen:blob-file-backend branch from 4bf9943 to 13fb790 May 23, 2016
@bors-servo
Copy link
Contributor

bors-servo commented Jun 1, 2016

Testing commit 43ad4ba with merge e83fb45...

bors-servo added a commit that referenced this pull request Jun 1, 2016
Add file backend support for Blob and related

- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy --faster` does not report any errors
- [x] These changes fix #10851, related to #11131
- [x] These changes do not require tests because the implementation is partial and can't work alone

1. Add new backend to `Blob` and a `BlobImpl` struct to abstract multiple backends
2. Rewrite most interfaces of `Blob` to accommodate the change
3. Change the `read` behaviour of `FileReader`, considering the case when blob is file-backed and not cached

The design is still immature, welcome comments!

- [x] I used `DOMRefCell` to cache the bytes in `BlobImpl`, is it sound?
- [x] The interfaces (like `BlobImpl::get_bytes`) handle requests in a default-to-empty way when the inner `DataSlice` is not cached. It might be possible to handle this condition better.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11221)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Jun 1, 2016

💔 Test failed - mac-rel-css

@highfive
Copy link

highfive commented Jun 1, 2016

  ▶ TIMEOUT [expected PASS] /css21_dev/html4/at-charset-074.htm

  ▶ TIMEOUT [expected PASS] /css21_dev/html4/at-charset-072.htm
  │ 
  └ Shutting down the Constellation after generating an output file or exit flag specified

  ▶ TIMEOUT [expected PASS] /css21_dev/html4/attribute-value-selector-001.htm
@Manishearth
Copy link
Member

Manishearth commented Jun 1, 2016

@Manishearth
Copy link
Member

Manishearth commented Jun 1, 2016

@bors-servo
Copy link
Contributor

bors-servo commented Jun 1, 2016

Trying commit 43ad4ba with merge decbabd...

bors-servo added a commit that referenced this pull request Jun 1, 2016
Add file backend support for Blob and related

- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy --faster` does not report any errors
- [x] These changes fix #10851, related to #11131
- [x] These changes do not require tests because the implementation is partial and can't work alone

1. Add new backend to `Blob` and a `BlobImpl` struct to abstract multiple backends
2. Rewrite most interfaces of `Blob` to accommodate the change
3. Change the `read` behaviour of `FileReader`, considering the case when blob is file-backed and not cached

The design is still immature, welcome comments!

- [x] I used `DOMRefCell` to cache the bytes in `BlobImpl`, is it sound?
- [x] The interfaces (like `BlobImpl::get_bytes`) handle requests in a default-to-empty way when the inner `DataSlice` is not cached. It might be possible to handle this condition better.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11221)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Jun 1, 2016

@bors-servo
Copy link
Contributor

bors-servo commented Jun 1, 2016

Testing commit 43ad4ba with merge 7293702...

bors-servo added a commit that referenced this pull request Jun 1, 2016
Add file backend support for Blob and related

- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy --faster` does not report any errors
- [x] These changes fix #10851, related to #11131
- [x] These changes do not require tests because the implementation is partial and can't work alone

1. Add new backend to `Blob` and a `BlobImpl` struct to abstract multiple backends
2. Rewrite most interfaces of `Blob` to accommodate the change
3. Change the `read` behaviour of `FileReader`, considering the case when blob is file-backed and not cached

The design is still immature, welcome comments!

- [x] I used `DOMRefCell` to cache the bytes in `BlobImpl`, is it sound?
- [x] The interfaces (like `BlobImpl::get_bytes`) handle requests in a default-to-empty way when the inner `DataSlice` is not cached. It might be possible to handle this condition better.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11221)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Jun 1, 2016

💔 Test failed - mac-rel-css

@Manishearth
Copy link
Member

Manishearth commented Jun 1, 2016

@bors retry try-

  • interrupt
@Manishearth
Copy link
Member

Manishearth commented Jun 1, 2016

@bors-servo retry try-

bors-servo added a commit that referenced this pull request Jun 1, 2016
Add file backend support for Blob and related

- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy --faster` does not report any errors
- [x] These changes fix #10851, related to #11131
- [x] These changes do not require tests because the implementation is partial and can't work alone

1. Add new backend to `Blob` and a `BlobImpl` struct to abstract multiple backends
2. Rewrite most interfaces of `Blob` to accommodate the change
3. Change the `read` behaviour of `FileReader`, considering the case when blob is file-backed and not cached

The design is still immature, welcome comments!

- [x] I used `DOMRefCell` to cache the bytes in `BlobImpl`, is it sound?
- [x] The interfaces (like `BlobImpl::get_bytes`) handle requests in a default-to-empty way when the inner `DataSlice` is not cached. It might be possible to handle this condition better.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11221)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Jun 1, 2016

Testing commit 43ad4ba with merge 3d7b176...

@bors-servo
Copy link
Contributor

bors-servo commented Jun 1, 2016

@bors-servo bors-servo merged commit 43ad4ba into servo:master Jun 1, 2016
2 of 3 checks passed
2 of 3 checks passed
continuous-integration/appveyor/pr AppVeyor build failed
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

7 participants
You can’t perform that action at this time.