CSC/ECE 517 Fall 2015 M1504 Implement support for missing XMLHttpRequest APIs: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
(Refactored to move up Project Description)
(→‎Test Cases: updated the passing tests)
 
(40 intermediate revisions by 4 users not shown)
Line 12: Line 12:


Rust is a modern, fast, memory safe and multithreaded programming language that focuses on speed and safety for developing reliable and efficient systems. It eliminates all data races by having numerous compile-time safety checks that adds no runtime overhead.<ref> http://doc.rust-lang.org/nightly/book/README.html</ref>
Rust is a modern, fast, memory safe and multithreaded programming language that focuses on speed and safety for developing reliable and efficient systems. It eliminates all data races by having numerous compile-time safety checks that adds no runtime overhead.<ref> http://doc.rust-lang.org/nightly/book/README.html</ref>
==Servo task Architecture==
[[Image:task.jpg]]
<ref group="image">https://github.com/servo/servo/wiki/Design</ref>
===Description===
* Each box corresponds to a Rust task.
* The primary tasks in the browser pipeline are represented by Blue boxes.
* Dashed lines indicate supervisor relationships.
* Gray boxes indicate tasks auxiliary to the browser pipeline.
* Communication channels are represented as solid lines.
* White boxes are represented as worker tasks. Each such box represents several tasks which varies with the workload.<ref>https://github.com/servo/servo/wiki/Design</ref>


==Background==
==Background==
Line 28: Line 43:
  var client = new XMLHttpRequest();
  var client = new XMLHttpRequest();
  client.onreadystatechange = function() {
  client.onreadystatechange = function() {
           if (client.readyState !== 4) return;
           ... //read the response as XML object
try{
            var str = client.responseXML.documentElement.tagName+client.responseXML.documentElement.firstChild.tagName+client.responseXML.documentElement.firstChild.textContent;
}catch(e){
assert_unreached('Exception when reading responseXML');
}
          assert_equals( client.responseXML.documentElement.tagName,  'test' );
          assert_equals( client.responseXML.documentElement.firstChild.tagName,  'message' );
          assert_equals( client.responseXML.documentElement.firstChild.textContent,  'Hello World!' );
          test.done();
         };
         };
         client.open("GET", "resources/status.py?type="+encodeURIComponent('text/plain;charset=Shift-JIS')+'&content='+encodeURIComponent('<test><message>Hello World!</message></test>'));
         client.open("GET", "resources/status.py?type="
                    +encodeURIComponent('text/plain;charset=Shift-JIS')
                    +'&content='+ encodeURIComponent('<test><message>Hello World!</message></test>'));
         client.overrideMimeType('application/xml;charset=UTF-8');
         client.overrideMimeType('application/xml;charset=UTF-8');
         client.send();
         client.send();
Line 73: Line 81:
==Project Description==
==Project Description==


Servo has implemented many API specifications that relies upon JavaScript that executes on all the browsers. [https://xhr.spec.whatwg.org/ XMLHttpRequest] is one such specification which is used for making HTTP requests dynamically. Our project aim is to implement few of the missing XMLHttpRequest APIs. The [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2015/oss_M1504_JJD OSS project] involved implementing initial steps of the [https://github.com/servo/servo/wiki/Implement-support-for-missing-XMLHttpRequest-APIs specifications]. It basically involved implementing overrideMimeType method and adjusting related test expectations.  
Our project aim is to implement few of the missing XMLHttpRequest APIs.<ref>https://github.com/servo/servo/wiki/Implement-support-for-missing-XMLHttpRequest-APIs</ref> The [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2015/oss_M1504_JJD OSS project] included implementing initial steps of the [https://github.com/servo/servo/wiki/Implement-support-for-missing-XMLHttpRequest-APIs specifications]. It basically incorporated implementing overrideMimeType method and adjusting related test expectations.  
 
The current scope of the project involves:<ref>https://github.com/servo/servo/wiki/Implement-support-for-missing-XMLHttpRequest-APIs</ref>
* Implementing the specified behavior of the final MIME type and final charset based on the implemented override_mime_type() method in the initial steps
* Implementing responseXML API and document response type according to the XHR specifications
* Implementing withCredentials API
 
==Servo task Architecture==


[[File:task.jpg]]
The implementation of the final project is described in a [[#Implementation_Details|section below]].
 
===Description===
 
* Each box corresponds to a Rust task.
* The primary tasks in the browser pipeline are represented by Blue boxes.
* Dashed lines indicate supervisor relationships.
* Gray boxes indicate tasks auxiliary to the browser pipeline.
* Communication channels are represented as solid lines.
* White boxes are represented as worker tasks. Each such box represents several tasks which varies with the workload.<ref>https://github.com/servo/servo/wiki/Design</ref>


==Requirement Analysis==
==Requirement Analysis==


Below is an overview of the various steps identified as a part of the requirement analysis:
Below is an overview of the various steps identified as a part of the requirement analysis and corresponding places in code in which these steps would be implemented:


''' XMLHttpRequest Interface '''
''' XMLHttpRequest Interface '''
Line 103: Line 95:
'''XMLHttpRequest DOM '''
'''XMLHttpRequest DOM '''


# Create helper methods for final_mime_type and final_charset
# Create helper methods final_mime_type and final_charset
#* Implement the two methods as per the behavior mentioned in the [https://xhr.spec.whatwg.org/#final-mime-type specification]
#* Implement the two methods as per the behavior mentioned in the [https://xhr.spec.whatwg.org/#final-mime-type specification]
# Implement correct behavior for the text_response method
# Implement correct behavior for the text_response method
Line 113: Line 105:


''' net_traits '''
''' net_traits '''
* Add a new member to the LoadData Structure which will be used by the http_loader to conditionally exclude cookies from the XHR request based on the value of the member.
* Add a new member to the LoadData Structure in [https://github.com/servo/servo/blob/master/components/net_traits/lib.rs#L130 lib.rs file] which will be used by the http_loader to conditionally exclude cookies from the XHR request based on the value of the member.


''' XHR Tests '''
''' XHR Tests '''
Line 119: Line 111:


==Component Flow Diagram==
==Component Flow Diagram==
{{wide image|Component Flow Diagram.png|1000px|alt=component flow diagram)}


==Proposed Test Cases==
[[File:component_flow_f15_m1504.png]]
The tests have already been written for the XMLHttpRequest APIs related to our project. So the test cases that could validate our changes to the code are as follows:
 
The XMLHttpRequest API receives request from the web server, the implementation then checks the response type, if it is a text response then we use the charset from final_charset else we use the default charset that was received with the request. The same applies to document response.
 
<span style="color:red">
Note :- UML diagram is not included because we do not have much class interaction in this project.
</span>
 
==Design Patterns ==
We have used "State Pattern" for our final project implementation. Our implementation stores the new CHARSET and MIME type based on what user has requested. So once user has requested for override in this value, the design pattern ensures the system behaves as per this new value.
 
[[File: design_pattern_f15_m1504.png]]
 
==Implementation Details==
The implementation for the final project involved following tasks:
* '''Implement the specified behavior for the override MIME type/final MIME type and override charset/final charset :''' We created two helper methods in xmlhttprequest.rs file: final_mime_type() and final_charset()
** final_mime_type() method returns the final MIME type<ref>https://xhr.spec.whatwg.org/#final-mime-type</ref> depending on override MIME type and response MIME type
** final_charset() method returns the final charset<ref>https://xhr.spec.whatwg.org/#final-charset</ref> depending on override charset and response charset
** We have also determined encoding of text_response by calling the final_charset() helper method. But if final charset is not set (i.e. it is None) then UTF-8 is set as the default encoding. The step 4 mentioned in the [https://xhr.spec.whatwg.org/#text-response text response] documentation in order to add support for XML encoding guess stuff using XML spec was not to be implemented and hence FIXME was added in the code.
 
* '''Support the withCredentials API :''' We have implemented basic network level support to conditionally exclude cookies from the HTTP request by adding a boolean member: credentials_flag to LoadData structure in lib.rs file.
** The default value of credentials_flag is set to true. credentials_flag is assigned value for cross-origin requests in Send() method of xmlhttprequest.rs file using the withCredentials attribute of XMLHttpRequest.
** If the credentials_flag is false then cookies will not be set from the cookie jar for the HTTP request for which the code is added in http_loader.rs file. Also if the credentials_flag is false, then the cookies are not set in the cookie jar from HTTP response. As suggested by the Servo focal for this project, we have not implemented the [https://github.com/servo/servo/wiki/Implement-support-for-missing-XMLHttpRequest-APIs first sub-task] for withCredentials API.
 
* '''Support for document response in responseXML API :''' Added Document to the list of response type checks. New methods were created which contain handling for different mime types. A document object is created and its JS value is returned. The document object is stored in response_xml member of XHR, on subsequent calls to the method this object is returned if it has already been set previously.<ref>https://xhr.spec.whatwg.org/#response-document-object</ref>.For mime type text/html if any of the charset is NONE the requirement was to scan the first 1024 bytes of the header to identify the charset, this part has not been implemented in this project. The following new methods were added to file XMLHttprequest.rs as part of this task -
**document_response - This method creates a document as per mime type returned by the final_mime_type() method created as part of OSS project. It internally calls other methods listed below. 
**document_text_html - This method creates a document flagged as an HTML document. This method is called by document_response in case the mime type is text/html. It calls the new_doc helper method.
**handle_xml - This method creates a document flagged as a non HTML document. This method is called by document_response in case the mime type subtype is XML. It calls the new_doc helper method. 
**new_doc - This method creates a new document which is the final response based on the input received from document_text_response and handle_xml methods.
 
==Test Cases==
The tests have already been written for the XMLHttpRequest(XHR) APIs related to our project. So the test cases that pass after our changes to the code are as follows:


* overrideMimeType() in unsent state enforces Shift-JIS encoding
* If XHR is in unsent state, then overrideMimeType() is able to enforce Shift-JIS charset encoding (overridemimetype-unsent-state-force-shiftjis.htm)
* overrideMimeType() in open state enforces UTF-8 encoding
* If XHR is in open state, then overrideMimeType() is able to enforce UTF-8 charset encoding (overridemimetype-open-state-force-utf-8.htm)
* overrideMimeType() in open state and XML MIME type with UTF-8 charset is correctly enforced
* If XHR with XML MIME type is in open state, then overrideMimeType() is able to enforce UTF-8 charset encoding (overridemimetype-open-state-force-xml.htm)
* overrideMimeType() in HEADERS RECEIVED state enforces Shift-JIS encoding
* If XHR is in HEADERS RECEIVED state, then overrideMimeType() is able to enforce Shift-JIS charset encoding (overridemimetype-headers-received-state-force-shiftjis.htm)
* responseXML attribute throws InvalidStateError if response type is not null or document
* The various responseXML document properties like title, contentType, doctype, cookie, etc. are correctly initialized (responsexml-document-properties.htm)
* The various responseXML document properties are correctly initialized
* In XHR, parsing of different responseXML MIME type is successful (responsexml-media-type.htm)
* The type of the responseXML stylesheets and implementation must be object
* In XHR, parsing of document received from responseXML is successful (send-redirect-no-location.htm, status-async.htm, status-basic.htm)
* If the state of XMLHttpRequest is not done then responseXML is null
* In XHR, throw InvalidStateError if response type is not null or document (responsexml-non-document-types.htm)
* Check withCredentials defaults to false and set value is true
* Setting withCredentials when not in UNSENT, OPENED state throws InvalidStateError exception
* Setting withCredentials when synchornous flag is set throws InvalidAccessError exception


==Appendix==
==Appendix==
Line 142: Line 160:
==References==
==References==
<references/>
<references/>
===Images===
<references group="image"/>

Latest revision as of 21:03, 8 December 2015

Introduction

Servo

Servo <ref> https://github.com/servo/servo </ref> is a web browser layout engine written in Rust<ref>https://github.com/rust-lang/rust</ref> and is currently being developed by Mozilla Research. The aim of the project is not to create a full browser but is rather to create a highly parallel environment that allows for many components be handled by fine-grained, isolated tasks.<ref>https://en.wikipedia.org/wiki/Servo_(layout_engine)</ref>

Servo is built on top of Rust to provide a secure and reliable foundation and is focused on creating a reliable and fast browser engine.

Rust

Rust is a multi-paradigm, compiled programming language that is a good language for creating highly safe systems. Rust and Servo have a symbiotic relationship as the development of servo has influenced the design of the language.

Rust is a modern, fast, memory safe and multithreaded programming language that focuses on speed and safety for developing reliable and efficient systems. It eliminates all data races by having numerous compile-time safety checks that adds no runtime overhead.<ref> http://doc.rust-lang.org/nightly/book/README.html</ref>

Servo task Architecture

<ref group="image">https://github.com/servo/servo/wiki/Design</ref>

Description

  • Each box corresponds to a Rust task.
  • The primary tasks in the browser pipeline are represented by Blue boxes.
  • Dashed lines indicate supervisor relationships.
  • Gray boxes indicate tasks auxiliary to the browser pipeline.
  • Communication channels are represented as solid lines.
  • White boxes are represented as worker tasks. Each such box represents several tasks which varies with the workload.<ref>https://github.com/servo/servo/wiki/Design</ref>

Background

XMLHttpRequest

"XMLHttpRequest is a specification which defines APIs that provides scripted client functionality for transferring data between a client and a server."<ref>https://xhr.spec.whatwg.org/</ref> XMLHttpRequest provides a way for data to be retrieved from a URL without having to retrieve the entire page. It supports protocols other than HTTP and can be used to retrieve any type of data.<ref>https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest</ref>

Some of the APIs and properties present in XMLHttpRequest specification are overrideMimeType() , responseXML and withCredentials. The following javascript code snippets briefly explain about each of these APIs.

overrideMimeType<ref>https://github.com/servo/servo/blob/master/tests/wpt/web-platform-tests/XMLHttpRequest/overridemimetype-open-state-force-xml.htm</ref>
 
//override the Mime type to retrieve the response as an XML Object


 var client = new XMLHttpRequest();
 client.onreadystatechange = function() {
          ... //read the response as XML object
        };
        client.open("GET", "resources/status.py?type="
                    +encodeURIComponent('text/plain;charset=Shift-JIS')
                    +'&content='+ encodeURIComponent('<test><message>Hello World!</message></test>'));
        client.overrideMimeType('application/xml;charset=UTF-8');
        client.send();

responseXML property<ref>https://msdn.microsoft.com/en-us/library/ms534370(v=vs.85).aspx</ref>
//read the response from the server as an XML Object

var oReq = new XMLHttpRequest();
oReq.open("GET", "http://localhost/books.xml", false);
oReq.send();
console.log(oReq.responseXML.xml);
withCredentials property<ref>http://arunranga.com/examples/access-control/credentialedRequest.html</ref>

//create cross site requests using cookies as credentials
 
var invocation = new XMLHttpRequest();
var url = 'http://crossoriginurl.com/resources/access-control-with-credentials/';
invocation.open('GET', url, true);
invocation.withCredentials = "true";
invocation.onreadystatechange = handler;
invocation.send(); 

The above mentioned APIs and properties for XMLHttpRequest are currently unimplemented in servo.

Project Description

Our project aim is to implement few of the missing XMLHttpRequest APIs.<ref>https://github.com/servo/servo/wiki/Implement-support-for-missing-XMLHttpRequest-APIs</ref> The OSS project included implementing initial steps of the specifications. It basically incorporated implementing overrideMimeType method and adjusting related test expectations.

The implementation of the final project is described in a section below.

Requirement Analysis

Below is an overview of the various steps identified as a part of the requirement analysis and corresponding places in code in which these steps would be implemented:

XMLHttpRequest Interface

  • We have to uncomment the responseXML API
  • A webpage can make use of this API to read the document response

XMLHttpRequest DOM

  1. Create helper methods final_mime_type and final_charset
    • Implement the two methods as per the behavior mentioned in the specification
  2. Implement correct behavior for the text_response method
    • Make use of the final_charset and final_mime_type helper methods to determine the correct encoding for the response and decode the response using this encoding
  3. Create and implement a new method "document_response" according to the xhr specification
  4. Implement the correct behavior for the responseXML API to handle exceptions and return the document response using the method implemented above <ref>https://xhr.spec.whatwg.org/#dom-xmlhttprequest-responsexml</ref>
  5. Implement the withCredentials APIs (setter and getter) as per the specification
  6. Add support to the send() and open() API to test the value of the withCredentials attribute where necessary

net_traits

  • Add a new member to the LoadData Structure in lib.rs file which will be used by the http_loader to conditionally exclude cookies from the XHR request based on the value of the member.

XHR Tests

Component Flow Diagram

The XMLHttpRequest API receives request from the web server, the implementation then checks the response type, if it is a text response then we use the charset from final_charset else we use the default charset that was received with the request. The same applies to document response.

Note :- UML diagram is not included because we do not have much class interaction in this project.

Design Patterns

We have used "State Pattern" for our final project implementation. Our implementation stores the new CHARSET and MIME type based on what user has requested. So once user has requested for override in this value, the design pattern ensures the system behaves as per this new value.

Implementation Details

The implementation for the final project involved following tasks:

  • Implement the specified behavior for the override MIME type/final MIME type and override charset/final charset : We created two helper methods in xmlhttprequest.rs file: final_mime_type() and final_charset()
    • final_mime_type() method returns the final MIME type<ref>https://xhr.spec.whatwg.org/#final-mime-type</ref> depending on override MIME type and response MIME type
    • final_charset() method returns the final charset<ref>https://xhr.spec.whatwg.org/#final-charset</ref> depending on override charset and response charset
    • We have also determined encoding of text_response by calling the final_charset() helper method. But if final charset is not set (i.e. it is None) then UTF-8 is set as the default encoding. The step 4 mentioned in the text response documentation in order to add support for XML encoding guess stuff using XML spec was not to be implemented and hence FIXME was added in the code.
  • Support the withCredentials API : We have implemented basic network level support to conditionally exclude cookies from the HTTP request by adding a boolean member: credentials_flag to LoadData structure in lib.rs file.
    • The default value of credentials_flag is set to true. credentials_flag is assigned value for cross-origin requests in Send() method of xmlhttprequest.rs file using the withCredentials attribute of XMLHttpRequest.
    • If the credentials_flag is false then cookies will not be set from the cookie jar for the HTTP request for which the code is added in http_loader.rs file. Also if the credentials_flag is false, then the cookies are not set in the cookie jar from HTTP response. As suggested by the Servo focal for this project, we have not implemented the first sub-task for withCredentials API.
  • Support for document response in responseXML API : Added Document to the list of response type checks. New methods were created which contain handling for different mime types. A document object is created and its JS value is returned. The document object is stored in response_xml member of XHR, on subsequent calls to the method this object is returned if it has already been set previously.<ref>https://xhr.spec.whatwg.org/#response-document-object</ref>.For mime type text/html if any of the charset is NONE the requirement was to scan the first 1024 bytes of the header to identify the charset, this part has not been implemented in this project. The following new methods were added to file XMLHttprequest.rs as part of this task -
    • document_response - This method creates a document as per mime type returned by the final_mime_type() method created as part of OSS project. It internally calls other methods listed below.
    • document_text_html - This method creates a document flagged as an HTML document. This method is called by document_response in case the mime type is text/html. It calls the new_doc helper method.
    • handle_xml - This method creates a document flagged as a non HTML document. This method is called by document_response in case the mime type subtype is XML. It calls the new_doc helper method.
    • new_doc - This method creates a new document which is the final response based on the input received from document_text_response and handle_xml methods.

Test Cases

The tests have already been written for the XMLHttpRequest(XHR) APIs related to our project. So the test cases that pass after our changes to the code are as follows:

  • If XHR is in unsent state, then overrideMimeType() is able to enforce Shift-JIS charset encoding (overridemimetype-unsent-state-force-shiftjis.htm)
  • If XHR is in open state, then overrideMimeType() is able to enforce UTF-8 charset encoding (overridemimetype-open-state-force-utf-8.htm)
  • If XHR with XML MIME type is in open state, then overrideMimeType() is able to enforce UTF-8 charset encoding (overridemimetype-open-state-force-xml.htm)
  • If XHR is in HEADERS RECEIVED state, then overrideMimeType() is able to enforce Shift-JIS charset encoding (overridemimetype-headers-received-state-force-shiftjis.htm)
  • The various responseXML document properties like title, contentType, doctype, cookie, etc. are correctly initialized (responsexml-document-properties.htm)
  • In XHR, parsing of different responseXML MIME type is successful (responsexml-media-type.htm)
  • In XHR, parsing of document received from responseXML is successful (send-redirect-no-location.htm, status-async.htm, status-basic.htm)
  • In XHR, throw InvalidStateError if response type is not null or document (responsexml-non-document-types.htm)

Appendix

References

<references/>

Images

<references group="image"/>