Merge lp:~rpadovani/oxide/http-status-code into lp:~oxide-developers/oxide/oxide.trunk

Proposed by Riccardo Padovani
Status: Merged
Merged at revision: 1078
Proposed branch: lp:~rpadovani/oxide/http-status-code
Merge into: lp:~oxide-developers/oxide/oxide.trunk
Diff against target: 1034 lines (+612/-65)
10 files modified
qt/core/api/oxideqloadevent.cc (+17/-3)
qt/core/api/oxideqloadevent.h (+16/-3)
qt/core/browser/oxide_qt_web_view.cc (+17/-9)
qt/core/browser/oxide_qt_web_view.h (+8/-4)
qt/qmlplugin/oxide_qml_plugin.cc (+2/-0)
qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.py (+21/-0)
qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.qml (+462/-0)
qt/tests/qmltests/api/tst_WebView_loading.qml (+33/-27)
shared/browser/oxide_web_view.cc (+25/-13)
shared/browser/oxide_web_view.h (+11/-6)
To merge this branch: bzr merge lp:~rpadovani/oxide/http-status-code
Reviewer Review Type Date Requested Status
Olivier Tilloy (community) Approve
Chris Coulson Approve
Review via email: mp+256606@code.launchpad.net

Commit message

Implement HttpStatusCode in OxideQLoadEvent

Description of the change

My first patch for Oxide :-)

So, atm it doesn't work (and test fails) because it returns always Code 200. I submitted the code just to have some feedbacks.

I inserted in the Enum HttpStatusCode all codes listed here: https://tools.ietf.org/html/rfc2616#section-6.1.1

To post a comment you must log in.
Revision history for this message
Olivier Tilloy (osomon) wrote :

You’re setting the HTTP status code on load events emitted from a LoadCommitted event. That’s not enough, the HTTP status code is also relevant for load events emitted from LoadRedirected, LoadFailed and LoadSucceeded events.

Also, I’m not sure it’s super useful to define an enum for the codes. I’m thinking an int property would be enough. But if we go for an enum, you might be able to get rid of HttpStatusCodeFromInt by doing a static cast from the int value to the enum.

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

> You’re setting the HTTP status code on load events emitted from a
> LoadCommitted event. That’s not enough, the HTTP status code is also relevant
> for load events emitted from LoadRedirected, LoadFailed and LoadSucceeded
> events.
>
> Also, I’m not sure it’s super useful to define an enum for the codes. I’m
> thinking an int property would be enough. But if we go for an enum, you might
> be able to get rid of HttpStatusCodeFromInt by doing a static cast from the
> int value to the enum.

Yeah, I'd be tempted to just use an int for this too (and setting it to -1 for events which don't have a status code). Other API's seem to just use an int (eg, https://developer.gnome.org/libsoup/stable/SoupMessage.html#SoupMessage--status-code, although they use an unsigned int here).

Note that LoadFailed can be generated before a commit - this means the connection failed for the main resource and there will be no valid status code. (If it's generated after a commit, then it means that the main resource loaded but a subresource failed. In this case, the status code will be the one for the successful main resource load).

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

To expose the status code for load succeeded events, you can use the same mechanism as used for committed events (NavigationEntry::GetHttpStatusCode). For redirect events, it's slightly different as the status code on NavigationEntry is only set when a load commits - in this case, you can use content::ResourceRedirectDetails::http_response_code (see |details| in WebView::DidGetRedirectForResourceRequest).

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Ok, I've added a few minor comments inline as well.

In addition to additional tests with a few different response codes, it would be worthwhile adding this property to the tests in tst_WebView_loading.qml where we test the sequence of LoadEvents (I guess it should always be "200" in these tests for events where the status code is valid).

And thanks for working on this :)

review: Needs Fixing
Revision history for this message
Riccardo Padovani (rpadovani) wrote :

Thanks for your feedbacks :-)

So, I dropped Enum and I implemented http_status_code also for Redirect and Success.

The code should be ok, but I didn't understand what I should add to oxide_qml_plugin.cc. I read the documentation, but I don't understand how qmlRegisterUncreatableType uri works, sorry.

I'm also a bit confused by tests: I thougth (let me know if I'm wrong) to write a test for every 'collection' of status code (2xx, 3xx, 4xx, 5xx) instead a test for each status code, so they verify also if on an url change the code status is updated.

But this approach has something wrong, because every LoadEvent.TypeSucceeded returns -1, and it's not a code fail, because I updated also tst_WebView_loading.qml and there LoadEvent.TypeSucceeded returns the right status code.

In exports.onBeforeSendHeaders = function(event){} (file qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.js) I wasn't able to use functions to manipulate strings, like substring, because they stop execution of the function. There is a way to don't have all these if, but simply extract the argument and pass it to the python script?

Or maybe there is a better way at all to create these tests?

Last thing: when the page returns 407 http_status_code becomes 406.
This maybe due the response, because 407 should also indicates the proxy that the requestor should use, so since the python script doesn't indicate anything, it fails on 406?

Thanks for your time!

Revision history for this message
Olivier Tilloy (osomon) wrote :

You will need to add the following line at the end of OxideQmlPlugin::registerTypes(…):

    qmlRegisterUncreatableType<OxideQLoadEvent, 2>(uri, 1, 8, "LoadEvent",
        "LoadEvent is delivered by WebView.loadEvent");

This means that revision 2 of OxideQLoadEvent is registered under oxide 1.8, and as a consequence the new property won’t be accessible when importing previous versions.
As a consequence you will need to update tst_LoadEvent_httpStatusCode.qml and tst_WebView_loading.qml to import oxide 1.8.

Revision history for this message
Olivier Tilloy (osomon) wrote :

As for the unit tests, no need for a javascript file that inserts a custom header for the server to parse. In the python handler function, request.path contains e.g. "/tst_LoadEvent_httpStatusCode.py?404", so you can just parse this to get the expected status code.

Revision history for this message
Riccardo Padovani (rpadovani) wrote :

Hi Olivier,
thanks for your feedback.

Sorry for the delay, it has been a busy week!

I followed your suggestions, so I think now it's ok, but it still has problems with test, because every LoadEvent.TypeSucceeded returns -1 in tst_LoadEvent_httpStatusCode.qml, and it's not a code fail, because I updated also tst_WebView_loading.qml and there LoadEvent.TypeSucceeded returns the right status code.

Revision history for this message
Olivier Tilloy (osomon) wrote :

Try the following patch, this should fix the issue you’re seeing with httpStatusCode not properly set:

=== modified file 'qt/core/browser/oxide_qt_web_view.cc'
--- qt/core/browser/oxide_qt_web_view.cc 2015-04-30 21:25:36 +0000
+++ qt/core/browser/oxide_qt_web_view.cc 2015-04-30 21:56:58 +0000
@@ -621,6 +621,7 @@
   OxideQLoadEvent event(
       QUrl(QString::fromStdString(validated_url.spec())),
       OxideQLoadEvent::TypeSucceeded,
+ false,
       http_status_code);
   client_->LoadEvent(&event);
 }

review: Needs Fixing
Revision history for this message
Riccardo Padovani (rpadovani) wrote :

You rock, thanks :-)

Could you please help me understandig what was wrong?

So, as far as I can say, I called the wrong constructor - instead of

OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,
                                 Type type,
                                 bool is_error,
                                 int http_status_code)

I called

OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,
                                 const QUrl& original_url,
                                 int http_status_code)

so, why the compiler didn't warning me about the conversion from Type type to const QUrl& original_url?

Revision history for this message
Olivier Tilloy (osomon) wrote :

In fact the right constructor was being called, but the status code was being converted to a boolean (is_error), and http_status_code was initialized with its default value, -1.

Revision history for this message
Olivier Tilloy (osomon) wrote :

There is now a minor conflict in qt/qmlplugin/oxide_qml_plugin.cc when merging this branch into trunk, would you mind addressing it? Both conflicting lines need to stay.

lp:~rpadovani/oxide/http-status-code updated
1040. By Riccardo Padovani

Merge from trunk and resolve conflict

Revision history for this message
Riccardo Padovani (rpadovani) wrote :

Fixed

Revision history for this message
Olivier Tilloy (osomon) wrote :

Thanks Riccardo for working on this! The logic looks good and seems to work well. I have a few comments, mostly on the unit tests:

 - In tst_LoadEvent_httpStatusCode.py, the body of the response (html) should be written regardless of the status code (it’s currently written only if http_status_code < 400. Actually, reading the spec more closely, for status codes 204 and 304 there musn’t be a message body, so those need to be special-cased. All others should be fine with a body.

 - In shared/browser/oxide_web_view.cc, the new line after OnLoadRedirected( needs to be indented by 4 whitespaces, for consistency with the rest of the codebase.

 - It should be possible to rewrite the tests in tst_LoadEvent_httpStatusCode.qml to be data-driven (see http://doc.qt.io/qt-5/qml-qttest-testcase.html#data-driven-tests): each row of data would contain a status code, together with a list of expected load events and their respective status codes.

 - Would it be possible to add tests for 3xx and 5xx status codes?

 - What exactly are the issues with the tests for status codes 205 and 407?

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Thanks for working on this - I've added one comment inline.

Also, I don't really understand the difference between -1 and 0. There is a comment saying that -1 is unknown, and that 0 is a list of cases where the status code isn't available - but aren't these just the same?

lp:~rpadovani/oxide/http-status-code updated
1041. By Riccardo Padovani

Improve tests for http status code

- Always write body of the response in tst_LoadEvent_httpStatusCode.py
- Tests now are data-driven
- Add tests for 3xx and 5xx status code

1042. By Riccardo Padovani

Add is_provisional_load to DispatchLoadFailed to be sure we have an http status code

Revision history for this message
Riccardo Padovani (rpadovani) wrote :

I think I addressed all your comments.

@Chris: it returns -1 as default - comment was wrong, now it's only the default value. At first implementation I added Enum for status codes, so when a status code wasn't in the enum it used -1.

I think it's importat the difference between 0 and -1: 0 is returned by Chromium for cases listed in the comment, -1 is returned by Oxide. If you don't want this difference, I change -1 with 0 as default.

@Olivier, now fails only test for 407.
This is the output:

1: 127.0.0.1 - - [15/May/2015 12:30:32] code 407, message Proxy Authentication Required
1: 127.0.0.1 - - [15/May/2015 12:30:32] "GET /tst_LoadEvent_httpStatusCode.py?407 HTTP/1.1" 407 -
1: FAIL! : qml-api-test::LoadEvent_httpStatusCode::test_HttpStatusCode4xx(407) Unexpected value of httpStatusCode
1: Actual (): 406
1: Expected (): 407
1: Loc: [/home/rpadovani/Ubuntu/touch/oxide/branches/firstTime/qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.qml(22)]

Maybe is because 407 is Proxy Authentication Required and for specs:
   The proxy MUST
   return a Proxy-Authenticate header field (section 14.33) containing a
   challenge applicable to the proxy for the requested resource.

but our http server doesn't return anything?

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

> I think I addressed all your comments.
>
> @Chris: it returns -1 as default - comment was wrong, now it's only the
> default value. At first implementation I added Enum for status codes, so when
> a status code wasn't in the enum it used -1.
>
> I think it's importat the difference between 0 and -1: 0 is returned by
> Chromium for cases listed in the comment, -1 is returned by Oxide. If you
> don't want this difference, I change -1 with 0 as default.
>

I'm not convinced it's important to convey this distinction in the API - either there's a valid status code with this event, or there isn't. I think I'd prefer just sticking with -1 or 0 (I don't mind which).

> @Olivier, now fails only test for 407.
> This is the output:
>
> 1: 127.0.0.1 - - [15/May/2015 12:30:32] code 407, message Proxy Authentication
> Required
> 1: 127.0.0.1 - - [15/May/2015 12:30:32] "GET
> /tst_LoadEvent_httpStatusCode.py?407 HTTP/1.1" 407 -
> 1: FAIL! : qml-api-
> test::LoadEvent_httpStatusCode::test_HttpStatusCode4xx(407) Unexpected value
> of httpStatusCode
> 1: Actual (): 406
> 1: Expected (): 407
> 1: Loc: [/home/rpadovani/Ubuntu/touch/oxide/branches/firstTime/qt/tests/qml
> tests/api/tst_LoadEvent_httpStatusCode.qml(22)]
>
> Maybe is because 407 is Proxy Authentication Required and for specs:
> The proxy MUST
> return a Proxy-Authenticate header field (section 14.33) containing a
> challenge applicable to the proxy for the requested resource.
>
> but our http server doesn't return anything?

You can modify tst_LoadEvent_httpStatusCode.py to return whatever headers you like, but in this case, I don't think this would fix the test (it's missing some other bits in Oxide, notably bug 1422339 I believe). I'd just remove the test for this status code for now.

lp:~rpadovani/oxide/http-status-code updated
1043. By Riccardo Padovani

Return 0 as default for http status code

1044. By Riccardo Padovani

Remove test for http status code 407

Revision history for this message
Riccardo Padovani (rpadovani) wrote :

I removed test 407 and set 0 as default http status code, thanks for your feedback :-)

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Thanks! I think this is good to merge (although I'll wait to see if Olivier has any other comments)

review: Approve
Revision history for this message
Olivier Tilloy (osomon) wrote :

That looks good to me too. I think all the test_HttpStatusCode*xx functions could be factored out into only one test function (and the special-casing on whether to test for load committed, succeeded or stopped should be part of the data driving the test), but at this stage that’s just picking nits (and we can still refactor that later on).

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'qt/core/api/oxideqloadevent.cc'
--- qt/core/api/oxideqloadevent.cc 2014-12-08 14:09:25 +0000
+++ qt/core/api/oxideqloadevent.cc 2015-05-15 12:21:58 +0000
@@ -26,6 +26,7 @@
26 : type(OxideQLoadEvent::TypeStarted),26 : type(OxideQLoadEvent::TypeStarted),
27 error_domain(OxideQLoadEvent::ErrorDomainNone),27 error_domain(OxideQLoadEvent::ErrorDomainNone),
28 error_code(0),28 error_code(0),
29 http_status_code(0),
29 is_error(false) {}30 is_error(false) {}
3031
31 QUrl url;32 QUrl url;
@@ -33,13 +34,15 @@
33 OxideQLoadEvent::ErrorDomain error_domain;34 OxideQLoadEvent::ErrorDomain error_domain;
34 QString error_string;35 QString error_string;
35 int error_code;36 int error_code;
37 int http_status_code;
36 QUrl original_url;38 QUrl original_url;
37 bool is_error;39 bool is_error;
38};40};
3941
40OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,42OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,
41 Type type,43 Type type,
42 bool is_error)44 bool is_error,
45 int http_status_code)
43 : d_ptr(new OxideQLoadEventPrivate()) {46 : d_ptr(new OxideQLoadEventPrivate()) {
44 Q_D(OxideQLoadEvent);47 Q_D(OxideQLoadEvent);
4548
@@ -50,12 +53,14 @@
50 d->url = url;53 d->url = url;
51 d->type = type;54 d->type = type;
52 d->is_error = is_error;55 d->is_error = is_error;
56 d->http_status_code = http_status_code;
53}57}
5458
55OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,59OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,
56 ErrorDomain error_domain,60 ErrorDomain error_domain,
57 const QString& error_string,61 const QString& error_string,
58 int error_code)62 int error_code,
63 int http_status_code)
59 : d_ptr(new OxideQLoadEventPrivate()) {64 : d_ptr(new OxideQLoadEventPrivate()) {
60 Q_D(OxideQLoadEvent);65 Q_D(OxideQLoadEvent);
6166
@@ -64,16 +69,19 @@
64 d->error_domain = error_domain;69 d->error_domain = error_domain;
65 d->error_string = error_string;70 d->error_string = error_string;
66 d->error_code = error_code;71 d->error_code = error_code;
72 d->http_status_code = http_status_code;
67}73}
6874
69OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,75OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,
70 const QUrl& original_url)76 const QUrl& original_url,
77 int http_status_code)
71 : d_ptr(new OxideQLoadEventPrivate()) {78 : d_ptr(new OxideQLoadEventPrivate()) {
72 Q_D(OxideQLoadEvent);79 Q_D(OxideQLoadEvent);
7380
74 d->url = url;81 d->url = url;
75 d->type = OxideQLoadEvent::TypeRedirected;82 d->type = OxideQLoadEvent::TypeRedirected;
76 d->original_url = original_url;83 d->original_url = original_url;
84 d->http_status_code = http_status_code;
77}85}
7886
79OxideQLoadEvent::~OxideQLoadEvent() {}87OxideQLoadEvent::~OxideQLoadEvent() {}
@@ -108,6 +116,12 @@
108 return d->error_code;116 return d->error_code;
109}117}
110118
119int OxideQLoadEvent::httpStatusCode() const {
120 Q_D(const OxideQLoadEvent);
121
122 return d->http_status_code;
123}
124
111QUrl OxideQLoadEvent::originalUrl() const {125QUrl OxideQLoadEvent::originalUrl() const {
112 Q_D(const OxideQLoadEvent);126 Q_D(const OxideQLoadEvent);
113127
114128
=== modified file 'qt/core/api/oxideqloadevent.h'
--- qt/core/api/oxideqloadevent.h 2014-12-09 17:18:01 +0000
+++ qt/core/api/oxideqloadevent.h 2015-05-15 12:21:58 +0000
@@ -34,6 +34,15 @@
34 Q_PROPERTY(ErrorDomain errorDomain READ errorDomain CONSTANT)34 Q_PROPERTY(ErrorDomain errorDomain READ errorDomain CONSTANT)
35 Q_PROPERTY(QString errorString READ errorString CONSTANT)35 Q_PROPERTY(QString errorString READ errorString CONSTANT)
36 Q_PROPERTY(int errorCode READ errorCode CONSTANT)36 Q_PROPERTY(int errorCode READ errorCode CONSTANT)
37 // The status code of the last known successful navigation. If
38 // returns 0 that means that either:
39 //
40 // - this navigation hasn't completed yet;
41 // - a response wasn't received;
42 // - or this navigation was restored and for some reason the
43 // status code wasn't available.
44 //
45 Q_PROPERTY(int httpStatusCode READ httpStatusCode CONSTANT REVISION 2)
3746
38 Q_PROPERTY(QUrl originalUrl READ originalUrl CONSTANT)47 Q_PROPERTY(QUrl originalUrl READ originalUrl CONSTANT)
3948
@@ -69,13 +78,16 @@
6978
70 Q_DECL_HIDDEN OxideQLoadEvent(const QUrl& url,79 Q_DECL_HIDDEN OxideQLoadEvent(const QUrl& url,
71 Type type,80 Type type,
72 bool is_error = false);81 bool is_error = false,
82 int http_status_code = -1);
73 Q_DECL_HIDDEN OxideQLoadEvent(const QUrl& url,83 Q_DECL_HIDDEN OxideQLoadEvent(const QUrl& url,
74 ErrorDomain error_domain,84 ErrorDomain error_domain,
75 const QString& error_string,85 const QString& error_string,
76 int error_code);86 int error_code,
87 int http_status_code);
77 Q_DECL_HIDDEN OxideQLoadEvent(const QUrl& url,88 Q_DECL_HIDDEN OxideQLoadEvent(const QUrl& url,
78 const QUrl& original_url);89 const QUrl& original_url,
90 int http_status_code);
79 virtual ~OxideQLoadEvent();91 virtual ~OxideQLoadEvent();
8092
81 QUrl url() const;93 QUrl url() const;
@@ -83,6 +95,7 @@
83 ErrorDomain errorDomain() const;95 ErrorDomain errorDomain() const;
84 QString errorString() const;96 QString errorString() const;
85 int errorCode() const;97 int errorCode() const;
98 int httpStatusCode() const;
86 QUrl originalUrl() const;99 QUrl originalUrl() const;
87 bool isError() const;100 bool isError() const;
88101
89102
=== modified file 'qt/core/browser/oxide_qt_web_view.cc'
--- qt/core/browser/oxide_qt_web_view.cc 2015-05-11 15:32:11 +0000
+++ qt/core/browser/oxide_qt_web_view.cc 2015-05-15 12:21:58 +0000
@@ -581,19 +581,23 @@
581}581}
582582
583void WebView::OnLoadRedirected(const GURL& url,583void WebView::OnLoadRedirected(const GURL& url,
584 const GURL& original_url) {584 const GURL& original_url,
585 int http_status_code) {
585 OxideQLoadEvent event(586 OxideQLoadEvent event(
586 QUrl(QString::fromStdString(url.spec())),587 QUrl(QString::fromStdString(url.spec())),
587 QUrl(QString::fromStdString(original_url.spec())));588 QUrl(QString::fromStdString(original_url.spec())),
589 http_status_code);
588 client_->LoadEvent(&event);590 client_->LoadEvent(&event);
589}591}
590592
591void WebView::OnLoadCommitted(const GURL& url,593void WebView::OnLoadCommitted(const GURL& url,
592 bool is_error_page) {594 bool is_error_page,
595 int http_status_code) {
593 OxideQLoadEvent event(596 OxideQLoadEvent event(
594 QUrl(QString::fromStdString(url.spec())),597 QUrl(QString::fromStdString(url.spec())),
595 OxideQLoadEvent::TypeCommitted,598 OxideQLoadEvent::TypeCommitted,
596 is_error_page);599 is_error_page,
600 http_status_code);
597 client_->LoadEvent(&event);601 client_->LoadEvent(&event);
598}602}
599603
@@ -606,19 +610,23 @@
606610
607void WebView::OnLoadFailed(const GURL& validated_url,611void WebView::OnLoadFailed(const GURL& validated_url,
608 int error_code,612 int error_code,
609 const std::string& error_description) {613 const std::string& error_description,
614 int http_status_code) {
610 OxideQLoadEvent event(615 OxideQLoadEvent event(
611 QUrl(QString::fromStdString(validated_url.spec())),616 QUrl(QString::fromStdString(validated_url.spec())),
612 ErrorDomainFromErrorCode(error_code),617 ErrorDomainFromErrorCode(error_code),
613 QString::fromStdString(error_description),618 QString::fromStdString(error_description),
614 error_code);619 error_code,
620 http_status_code);
615 client_->LoadEvent(&event);621 client_->LoadEvent(&event);
616}622}
617623
618void WebView::OnLoadSucceeded(const GURL& validated_url) {624void WebView::OnLoadSucceeded(const GURL& validated_url, int http_status_code) {
619 OxideQLoadEvent event(625 OxideQLoadEvent event(
620 QUrl(QString::fromStdString(validated_url.spec())),626 QUrl(QString::fromStdString(validated_url.spec())),
621 OxideQLoadEvent::TypeSucceeded);627 OxideQLoadEvent::TypeSucceeded,
628 false,
629 http_status_code);
622 client_->LoadEvent(&event);630 client_->LoadEvent(&event);
623}631}
624632
@@ -1061,7 +1069,7 @@
1061}1069}
10621070
1063bool WebView::incognito() const {1071bool WebView::incognito() const {
1064 return IsIncognito(); 1072 return IsIncognito();
1065}1073}
10661074
1067bool WebView::loading() const {1075bool WebView::loading() const {
10681076
=== modified file 'qt/core/browser/oxide_qt_web_view.h'
--- qt/core/browser/oxide_qt_web_view.h 2015-05-11 15:32:11 +0000
+++ qt/core/browser/oxide_qt_web_view.h 2015-05-15 12:21:58 +0000
@@ -113,14 +113,18 @@
113113
114 void OnLoadStarted(const GURL& validated_url) override;114 void OnLoadStarted(const GURL& validated_url) override;
115 void OnLoadRedirected(const GURL& url,115 void OnLoadRedirected(const GURL& url,
116 const GURL& original_url) override;116 const GURL& original_url,
117 int http_status_code) override;
117 void OnLoadCommitted(const GURL& url,118 void OnLoadCommitted(const GURL& url,
118 bool is_error_page) override;119 bool is_error_page,
120 int http_status_code) override;
119 void OnLoadStopped(const GURL& validated_url) override;121 void OnLoadStopped(const GURL& validated_url) override;
120 void OnLoadFailed(const GURL& validated_url,122 void OnLoadFailed(const GURL& validated_url,
121 int error_code,123 int error_code,
122 const std::string& error_description) override;124 const std::string& error_description,
123 void OnLoadSucceeded(const GURL& validated_url) override;125 int http_status_code) override;
126 void OnLoadSucceeded(const GURL& validated_url,
127 int http_status_code) override;
124128
125 void OnNavigationEntryCommitted() override;129 void OnNavigationEntryCommitted() override;
126 void OnNavigationListPruned(bool from_front, int count) override;130 void OnNavigationListPruned(bool from_front, int count) override;
127131
=== modified file 'qt/qmlplugin/oxide_qml_plugin.cc'
--- qt/qmlplugin/oxide_qml_plugin.cc 2015-05-11 15:32:11 +0000
+++ qt/qmlplugin/oxide_qml_plugin.cc 2015-05-15 12:21:58 +0000
@@ -128,6 +128,8 @@
128 qmlRegisterUncreatableType<OxideQQuickLocationBarController, 1>(uri, 1, 7, "LocationBarController",128 qmlRegisterUncreatableType<OxideQQuickLocationBarController, 1>(uri, 1, 7, "LocationBarController",
129 "LocationBarController is accessed via WebView.locationBarController");129 "LocationBarController is accessed via WebView.locationBarController");
130130
131 qmlRegisterUncreatableType<OxideQLoadEvent, 2>(uri, 1, 8, "LoadEvent",
132 "LoadEvent is delivered by WebView.loadEvent");
131 qmlRegisterType<OxideQQuickWebView, 4>(uri, 1, 8, "WebView");133 qmlRegisterType<OxideQQuickWebView, 4>(uri, 1, 8, "WebView");
132 }134 }
133};135};
134136
=== added file 'qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.py'
--- qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.py 1970-01-01 00:00:00 +0000
+++ qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.py 2015-05-15 12:21:58 +0000
@@ -0,0 +1,21 @@
1from cStringIO import StringIO
2
3def handler(request):
4 html = StringIO()
5
6 http_status_code = int(request.path[-3:])
7
8 html.write("Request for http status code: " + str(http_status_code))
9
10 if http_status_code >= 400:
11 request.send_error(http_status_code)
12 else:
13 request.send_response(http_status_code)
14
15 if http_status_code != 204 and http_status_code != 304:
16 request.send_header("Content-type", "application/json")
17 request.send_header("Content-Length", html.tell())
18 request.send_header("Cache-Control", "no-cache")
19 request.end_headers()
20
21 request.wfile.write(html.getvalue())
022
=== added file 'qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.qml'
--- qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.qml 1970-01-01 00:00:00 +0000
+++ qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.qml 2015-05-15 12:21:58 +0000
@@ -0,0 +1,462 @@
1import QtQuick 2.0
2import QtTest 1.0
3import com.canonical.Oxide 1.8
4import com.canonical.Oxide.Testing 1.0
5
6TestWebView {
7 id: webView
8 width: 200
9 height: 200
10
11 property var expectedLoadEvents: []
12 property int expectedHttpStatusCode
13
14 onLoadEvent: {
15 test.verify(expectedLoadEvents.length > 0);
16 var expected = expectedLoadEvents[0];
17 expectedLoadEvents.shift();
18
19 test.compare(event.type, expected, "Unexpected type")
20
21 test.compare(event.httpStatusCode,
22 event.type != LoadEvent.TypeStarted && event.type != LoadEvent.TypeStopped ? expectedHttpStatusCode : -1,
23 "Unexpected value of httpStatusCode");
24 }
25
26 TestCase {
27 id: test
28 name: "LoadEvent_httpStatusCode"
29 when: windowShown
30
31 function init() {
32 webView.clearLoadEventCounters();
33 expectedLoadEvents = [];
34 }
35
36 function test_HttpStatusCode2xx_data() {
37 return [
38 {
39 tag: "200",
40 httpStatusCode: 200,
41 events: [
42 LoadEvent.TypeStarted,
43 LoadEvent.TypeCommitted,
44 LoadEvent.TypeSucceeded
45 ]
46 },
47 {
48 tag: "201",
49 httpStatusCode: 201,
50 events: [
51 LoadEvent.TypeStarted,
52 LoadEvent.TypeCommitted,
53 LoadEvent.TypeSucceeded
54 ]
55 },
56 {
57 tag: "202",
58 httpStatusCode: 202,
59 events: [
60 LoadEvent.TypeStarted,
61 LoadEvent.TypeCommitted,
62 LoadEvent.TypeSucceeded
63 ]
64 },
65 {
66 tag: "203",
67 httpStatusCode: 203,
68 events: [
69 LoadEvent.TypeStarted,
70 LoadEvent.TypeCommitted,
71 LoadEvent.TypeSucceeded
72 ]
73 },
74 {
75 tag: "204",
76 httpStatusCode: 204,
77 events: [
78 LoadEvent.TypeStarted,
79 LoadEvent.TypeStopped
80 ]
81 },
82 {
83 tag: "205",
84 httpStatusCode: 205,
85 events: [
86 LoadEvent.TypeStarted,
87 LoadEvent.TypeStopped
88 ]
89 },
90 {
91 tag: "206",
92 httpStatusCode: 206,
93 events: [
94 LoadEvent.TypeStarted,
95 LoadEvent.TypeCommitted,
96 LoadEvent.TypeSucceeded
97 ]
98 },
99 ]
100 }
101
102 function test_HttpStatusCode2xx(data) {
103 expectedHttpStatusCode = data.httpStatusCode;
104 expectedLoadEvents = data.events;
105
106 webView.url = "http://testsuite/tst_LoadEvent_httpStatusCode.py?" +
107 data.httpStatusCode;
108
109 if (data.httpStatusCode === 204 || data.httpStatusCode === 205) {
110 verify(webView.waitForLoadStopped());
111 } else {
112 verify(webView.waitForLoadSucceeded());
113 }
114 }
115
116 function test_HttpStatusCode3xx_data() {
117 return [
118 {
119 tag: "300",
120 httpStatusCode: 300,
121 events: [
122 LoadEvent.TypeStarted,
123 LoadEvent.TypeCommitted,
124 LoadEvent.TypeSucceeded
125 ]
126 },
127 {
128 tag: "301",
129 httpStatusCode: 301,
130 events: [
131 LoadEvent.TypeStarted,
132 LoadEvent.TypeCommitted,
133 LoadEvent.TypeSucceeded
134 ]
135 },
136 {
137 tag: "302",
138 httpStatusCode: 302,
139 events: [
140 LoadEvent.TypeStarted,
141 LoadEvent.TypeCommitted,
142 LoadEvent.TypeSucceeded
143 ]
144 },
145 {
146 tag: "303",
147 httpStatusCode: 303,
148 events: [
149 LoadEvent.TypeStarted,
150 LoadEvent.TypeCommitted,
151 LoadEvent.TypeSucceeded
152 ]
153 },
154 {
155 tag: "304",
156 httpStatusCode: 304,
157 events: [
158 LoadEvent.TypeStarted,
159 LoadEvent.TypeStopped
160 ]
161 },
162 {
163 tag: "305",
164 httpStatusCode: 305,
165 events: [
166 LoadEvent.TypeStarted,
167 LoadEvent.TypeCommitted,
168 LoadEvent.TypeSucceeded
169 ]
170 },
171 {
172 tag: "306",
173 httpStatusCode: 306,
174 events: [
175 LoadEvent.TypeStarted,
176 LoadEvent.TypeCommitted,
177 LoadEvent.TypeSucceeded
178 ]
179 },
180 {
181 tag: "307",
182 httpStatusCode: 307,
183 events: [
184 LoadEvent.TypeStarted,
185 LoadEvent.TypeCommitted,
186 LoadEvent.TypeSucceeded
187 ]
188 },
189 {
190 tag: "308",
191 httpStatusCode: 308,
192 events: [
193 LoadEvent.TypeStarted,
194 LoadEvent.TypeCommitted,
195 LoadEvent.TypeSucceeded
196 ]
197 }
198 ]
199 }
200
201 function test_HttpStatusCode3xx(data) {
202 expectedHttpStatusCode = data.httpStatusCode;
203 expectedLoadEvents = data.events;
204
205 webView.url = "http://testsuite/tst_LoadEvent_httpStatusCode.py?" +
206 data.httpStatusCode;
207
208 if (data.httpStatusCode === 304) {
209 verify(webView.waitForLoadStopped());
210 } else {
211 verify(webView.waitForLoadSucceeded());
212 }
213 }
214
215 function test_HttpStatusCode4xx_data() {
216 return [
217 {
218 tag: "400",
219 httpStatusCode: 400,
220 events: [
221 LoadEvent.TypeStarted,
222 LoadEvent.TypeCommitted,
223 LoadEvent.TypeSucceeded
224 ]
225 },
226 {
227 tag: "401",
228 httpStatusCode: 401,
229 events: [
230 LoadEvent.TypeStarted,
231 LoadEvent.TypeCommitted,
232 LoadEvent.TypeSucceeded
233 ]
234 },
235 {
236 tag: "403",
237 httpStatusCode: 403,
238 events: [
239 LoadEvent.TypeStarted,
240 LoadEvent.TypeCommitted,
241 LoadEvent.TypeSucceeded
242 ]
243 },
244 {
245 tag: "404",
246 httpStatusCode: 404,
247 events: [
248 LoadEvent.TypeStarted,
249 LoadEvent.TypeCommitted,
250 LoadEvent.TypeSucceeded
251 ]
252 },
253 {
254 tag: "405",
255 httpStatusCode: 405,
256 events: [
257 LoadEvent.TypeStarted,
258 LoadEvent.TypeCommitted,
259 LoadEvent.TypeSucceeded
260 ]
261 },
262 {
263 tag: "406",
264 httpStatusCode: 406,
265 events: [
266 LoadEvent.TypeStarted,
267 LoadEvent.TypeCommitted,
268 LoadEvent.TypeSucceeded
269 ]
270 },
271 // XXX: investigate on failure of this test.
272 // See https://code.launchpad.net/~rpadovani/oxide/http-status-code/+merge/256606/comments/647631
273 // {
274 // tag: "407",
275 // httpStatusCode: 407,
276 // events: [
277 // LoadEvent.TypeStarted,
278 // LoadEvent.TypeFailed,
279 // LoadEvent.TypeCommitted
280 // ]
281 // },
282 {
283 tag: "408",
284 httpStatusCode: 408,
285 events: [
286 LoadEvent.TypeStarted,
287 LoadEvent.TypeCommitted,
288 LoadEvent.TypeSucceeded
289 ]
290 },
291 {
292 tag: "409",
293 httpStatusCode: 409,
294 events: [
295 LoadEvent.TypeStarted,
296 LoadEvent.TypeCommitted,
297 LoadEvent.TypeSucceeded
298 ]
299 },
300 {
301 tag: "410",
302 httpStatusCode: 410,
303 events: [
304 LoadEvent.TypeStarted,
305 LoadEvent.TypeCommitted,
306 LoadEvent.TypeSucceeded
307 ]
308 },
309 {
310 tag: "411",
311 httpStatusCode: 411,
312 events: [
313 LoadEvent.TypeStarted,
314 LoadEvent.TypeCommitted,
315 LoadEvent.TypeSucceeded
316 ]
317 },
318 {
319 tag: "412",
320 httpStatusCode: 412,
321 events: [
322 LoadEvent.TypeStarted,
323 LoadEvent.TypeCommitted,
324 LoadEvent.TypeSucceeded
325 ]
326 },
327 {
328 tag: "413",
329 httpStatusCode: 413,
330 events: [
331 LoadEvent.TypeStarted,
332 LoadEvent.TypeCommitted,
333 LoadEvent.TypeSucceeded
334 ]
335 },
336 {
337 tag: "414",
338 httpStatusCode: 414,
339 events: [
340 LoadEvent.TypeStarted,
341 LoadEvent.TypeCommitted,
342 LoadEvent.TypeSucceeded
343 ]
344 },
345 {
346 tag: "415",
347 httpStatusCode: 415,
348 events: [
349 LoadEvent.TypeStarted,
350 LoadEvent.TypeCommitted,
351 LoadEvent.TypeSucceeded
352 ]
353 },
354 {
355 tag: "416",
356 httpStatusCode: 416,
357 events: [
358 LoadEvent.TypeStarted,
359 LoadEvent.TypeCommitted,
360 LoadEvent.TypeSucceeded
361 ]
362 },
363 {
364 tag: "417",
365 httpStatusCode: 417,
366 events: [
367 LoadEvent.TypeStarted,
368 LoadEvent.TypeCommitted,
369 LoadEvent.TypeSucceeded
370 ]
371 }
372 ]
373 }
374
375 function test_HttpStatusCode4xx(data) {
376 expectedHttpStatusCode = data.httpStatusCode;
377 expectedLoadEvents = data.events;
378
379 webView.url = "http://testsuite/tst_LoadEvent_httpStatusCode.py?" +
380 data.httpStatusCode;
381
382 if (data.httpStatusCode === 407) {
383 verify(webView.waitForLoadCommitted());
384 } else {
385 verify(webView.waitForLoadSucceeded());
386 }
387 }
388
389 function test_HttpStatusCode5xx_data() {
390 return [
391 {
392 tag: "500",
393 httpStatusCode: 500,
394 events: [
395 LoadEvent.TypeStarted,
396 LoadEvent.TypeCommitted,
397 LoadEvent.TypeSucceeded
398 ]
399 },
400 {
401 tag: "501",
402 httpStatusCode: 501,
403 events: [
404 LoadEvent.TypeStarted,
405 LoadEvent.TypeCommitted,
406 LoadEvent.TypeSucceeded
407 ]
408 },
409 {
410 tag: "502",
411 httpStatusCode: 502,
412 events: [
413 LoadEvent.TypeStarted,
414 LoadEvent.TypeCommitted,
415 LoadEvent.TypeSucceeded
416 ]
417 },
418 {
419 tag: "503",
420 httpStatusCode: 503,
421 events: [
422 LoadEvent.TypeStarted,
423 LoadEvent.TypeCommitted,
424 LoadEvent.TypeSucceeded
425 ]
426 },
427 {
428 tag: "504",
429 httpStatusCode: 504,
430 events: [
431 LoadEvent.TypeStarted,
432 LoadEvent.TypeCommitted,
433 LoadEvent.TypeSucceeded
434 ]
435 },
436 {
437 tag: "505",
438 httpStatusCode: 505,
439 events: [
440 LoadEvent.TypeStarted,
441 LoadEvent.TypeCommitted,
442 LoadEvent.TypeSucceeded
443 ]
444 }
445 ]
446 }
447
448 function test_HttpStatusCode5xx(data) {
449 expectedHttpStatusCode = data.httpStatusCode;
450 expectedLoadEvents = data.events;
451
452 webView.url = "http://testsuite/tst_LoadEvent_httpStatusCode.py?" +
453 data.httpStatusCode;
454
455 // if (data.httpStatusCode === 304) {
456 // verify(webView.waitForLoadStopped());
457 // } else {
458 verify(webView.waitForLoadSucceeded());
459 //}
460 }
461 }
462}
0463
=== modified file 'qt/tests/qmltests/api/tst_WebView_loading.qml'
--- qt/tests/qmltests/api/tst_WebView_loading.qml 2015-04-15 14:49:03 +0000
+++ qt/tests/qmltests/api/tst_WebView_loading.qml 2015-05-15 12:21:58 +0000
@@ -1,6 +1,6 @@
1import QtQuick 2.01import QtQuick 2.0
2import QtTest 1.02import QtTest 1.0
3import com.canonical.Oxide 1.03import com.canonical.Oxide 1.8
4import com.canonical.Oxide.Testing 1.04import com.canonical.Oxide.Testing 1.0
55
6TestWebView {6TestWebView {
@@ -35,6 +35,10 @@
35 test.compare(event.originalUrl,35 test.compare(event.originalUrl,
36 event.type == LoadEvent.TypeRedirected ? expected.originalUrl : "",36 event.type == LoadEvent.TypeRedirected ? expected.originalUrl : "",
37 "Unexpected originalUrl");37 "Unexpected originalUrl");
38 test.compare(event.httpStatusCode,
39 event.type != LoadEvent.TypeStarted && event.type != LoadEvent.TypeStopped ?
40 expected.httpStatusCode : -1,
41 "Unexpected value of httpStatusCode");
38 test.compare(loading, expected.loading,42 test.compare(loading, expected.loading,
39 "Unexpected state of WebView.loading");43 "Unexpected state of WebView.loading");
40 }44 }
@@ -63,8 +67,8 @@
63 var url = "http://testsuite/empty.html";67 var url = "http://testsuite/empty.html";
64 expectedLoadEvents = [68 expectedLoadEvents = [
65 { type: LoadEvent.TypeStarted, url: url, loading: true },69 { type: LoadEvent.TypeStarted, url: url, loading: true },
66 { type: LoadEvent.TypeCommitted, url: url, error: false, loading: true },70 { type: LoadEvent.TypeCommitted, url: url, error: false, httpStatusCode: 200, loading: true },
67 { type: LoadEvent.TypeSucceeded, url: url, loading: false }71 { type: LoadEvent.TypeSucceeded, url: url, httpStatusCode: 200, loading: false }
68 ];72 ];
6973
70 webView.url = url;74 webView.url = url;
@@ -88,11 +92,11 @@
88 var new_url = "http://foo.testsuite/empty.html";92 var new_url = "http://foo.testsuite/empty.html";
89 expectedLoadEvents = [93 expectedLoadEvents = [
90 { type: LoadEvent.TypeStarted, url: initial_url, loading: true },94 { type: LoadEvent.TypeStarted, url: initial_url, loading: true },
91 { type: LoadEvent.TypeCommitted, url: initial_url, error: false, loading: true },95 { type: LoadEvent.TypeCommitted, url: initial_url, httpStatusCode: 200, error: false, loading: true },
92 { type: LoadEvent.TypeSucceeded, url: initial_url, loading: false },96 { type: LoadEvent.TypeSucceeded, url: initial_url, httpStatusCode: 200, loading: false },
93 { type: LoadEvent.TypeStarted, url: new_url, loading: true }, 97 { type: LoadEvent.TypeStarted, url: new_url, loading: true },
94 { type: LoadEvent.TypeCommitted, url: new_url, error: false, loading: true },98 { type: LoadEvent.TypeCommitted, url: new_url, error: false, httpStatusCode: 200, loading: true },
95 { type: LoadEvent.TypeSucceeded, url: new_url, loading: false }99 { type: LoadEvent.TypeSucceeded, url: new_url, httpStatusCode: 200, loading: false }
96 ];100 ];
97101
98 webView.url = initial_url;102 webView.url = initial_url;
@@ -100,7 +104,7 @@
100104
101 verify(!webView.loading);105 verify(!webView.loading);
102 spy.clear();106 spy.clear();
103 107
104 webView.getTestApi().evaluateCode("window.location = \"" + new_url + "\";", false);108 webView.getTestApi().evaluateCode("window.location = \"" + new_url + "\";", false);
105 webView.waitFor(function() { return spy.count == 2; });109 webView.waitFor(function() { return spy.count == 2; });
106110
@@ -146,8 +150,8 @@
146 var url = "http://invalid/";150 var url = "http://invalid/";
147 expectedLoadEvents = [151 expectedLoadEvents = [
148 { type: LoadEvent.TypeStarted, url: url, loading: true },152 { type: LoadEvent.TypeStarted, url: url, loading: true },
149 { type: LoadEvent.TypeFailed, url: url, loading: true },153 { type: LoadEvent.TypeFailed, url: url, httpStatusCode: 0, loading: true },
150 { type: LoadEvent.TypeCommitted, url: url, error: true, loading: true }154 { type: LoadEvent.TypeCommitted, url: url, error: true, httpStatusCode: 0, loading: true }
151 ];155 ];
152156
153 webView.url = url;157 webView.url = url;
@@ -168,8 +172,8 @@
168 spy.clear();172 spy.clear();
169 expectedLoadEvents = [173 expectedLoadEvents = [
170 { type: LoadEvent.TypeStarted, url: url, loading: true },174 { type: LoadEvent.TypeStarted, url: url, loading: true },
171 { type: LoadEvent.TypeFailed, url: url, loading: true },175 { type: LoadEvent.TypeFailed, url: url, httpStatusCode: 0, loading: true },
172 { type: LoadEvent.TypeCommitted, url: url, error: true, loading: true }176 { type: LoadEvent.TypeCommitted, url: url, error: true, httpStatusCode: 0, loading: true }
173 ];177 ];
174 webView.reload();178 webView.reload();
175179
@@ -191,9 +195,11 @@
191 var url = "http://testsuite/tst_WebView_loading_redirect.py";195 var url = "http://testsuite/tst_WebView_loading_redirect.py";
192 expectedLoadEvents = [196 expectedLoadEvents = [
193 { type: LoadEvent.TypeStarted, url: url, loading: true },197 { type: LoadEvent.TypeStarted, url: url, loading: true },
194 { type: LoadEvent.TypeRedirected, url: "http://testsuite/empty.html", originalUrl: url, loading: true },198 { type: LoadEvent.TypeRedirected, url: "http://testsuite/empty.html",
195 { type: LoadEvent.TypeCommitted, url: "http://testsuite/empty.html", error: false, loading: true },199 originalUrl: url, httpStatusCode: 302, loading: true },
196 { type: LoadEvent.TypeSucceeded, url: "http://testsuite/empty.html", loading: false }200 { type: LoadEvent.TypeCommitted, url: "http://testsuite/empty.html",
201 error: false, httpStatusCode: 200, loading: true },
202 { type: LoadEvent.TypeSucceeded, url: "http://testsuite/empty.html", httpStatusCode: 200, loading: false }
197 ];203 ];
198204
199 webView.url = url;205 webView.url = url;
@@ -216,10 +222,10 @@
216 var initial_url = "http://testsuite/empty.html";222 var initial_url = "http://testsuite/empty.html";
217 var new_url = "http://testsuite/empty.html#foo";223 var new_url = "http://testsuite/empty.html#foo";
218 expectedLoadEvents = [224 expectedLoadEvents = [
219 { type: LoadEvent.TypeStarted, url: initial_url, loading: true },225 { type: LoadEvent.TypeStarted, url: initial_url, httpStatusCode: 200, loading: true },
220 { type: LoadEvent.TypeCommitted, url: initial_url, error: false, loading: true },226 { type: LoadEvent.TypeCommitted, url: initial_url, error: false, httpStatusCode: 200, loading: true },
221 { type: LoadEvent.TypeSucceeded, url: initial_url, loading: false },227 { type: LoadEvent.TypeSucceeded, url: initial_url, httpStatusCode: 200, loading: false },
222 { type: LoadEvent.TypeCommitted, url: new_url, error: false, loading: true }228 { type: LoadEvent.TypeCommitted, url: new_url, error: false, httpStatusCode: 200, loading: true }
223 ];229 ];
224230
225 webView.url = initial_url;231 webView.url = initial_url;
@@ -227,7 +233,7 @@
227233
228 verify(!webView.loading);234 verify(!webView.loading);
229 spy.clear();235 spy.clear();
230 236
231 webView.getTestApi().evaluateCode("window.location = \"" + new_url + "\";", false);237 webView.getTestApi().evaluateCode("window.location = \"" + new_url + "\";", false);
232 webView.waitFor(function() { return spy.count == 2; });238 webView.waitFor(function() { return spy.count == 2; });
233239
@@ -241,10 +247,10 @@
241 var initial_url = "http://testsuite/empty.html";247 var initial_url = "http://testsuite/empty.html";
242 var new_url = "http://testsuite/empty.html#foo";248 var new_url = "http://testsuite/empty.html#foo";
243 expectedLoadEvents = [249 expectedLoadEvents = [
244 { type: LoadEvent.TypeStarted, url: initial_url, loading: true },250 { type: LoadEvent.TypeStarted, url: initial_url, httpStatusCode: 200, loading: true },
245 { type: LoadEvent.TypeCommitted, url: initial_url, error: false, loading: true },251 { type: LoadEvent.TypeCommitted, url: initial_url, error: false, httpStatusCode: 200, loading: true },
246 { type: LoadEvent.TypeSucceeded, url: initial_url, loading: false },252 { type: LoadEvent.TypeSucceeded, url: initial_url, httpStatusCode: 200, loading: false },
247 { type: LoadEvent.TypeCommitted, url: new_url, error: false, loading: true }253 { type: LoadEvent.TypeCommitted, url: new_url, error: false, httpStatusCode: 200, loading: true }
248 ];254 ];
249255
250 webView.url = initial_url;256 webView.url = initial_url;
@@ -288,8 +294,8 @@
288 var url = "http://testsuite/tst_WebView_loading_subframe.html";294 var url = "http://testsuite/tst_WebView_loading_subframe.html";
289 expectedLoadEvents = [295 expectedLoadEvents = [
290 { type: LoadEvent.TypeStarted, url: url, loading: true },296 { type: LoadEvent.TypeStarted, url: url, loading: true },
291 { type: LoadEvent.TypeCommitted, url: url, error: false, loading: true },297 { type: LoadEvent.TypeCommitted, url: url, error: false, httpStatusCode: 200, loading: true },
292 { type: LoadEvent.TypeSucceeded, url: url, loading: false }298 { type: LoadEvent.TypeSucceeded, url: url, httpStatusCode: 200, loading: false }
293 ];299 ];
294300
295 webView.url = url;301 webView.url = url;
296302
=== modified file 'shared/browser/oxide_web_view.cc'
--- shared/browser/oxide_web_view.cc 2015-05-14 15:37:57 +0000
+++ shared/browser/oxide_web_view.cc 2015-05-15 12:21:58 +0000
@@ -253,12 +253,16 @@
253253
254void WebView::DispatchLoadFailed(const GURL& validated_url,254void WebView::DispatchLoadFailed(const GURL& validated_url,
255 int error_code,255 int error_code,
256 const base::string16& error_description) {256 const base::string16& error_description,
257 bool is_provisional_load) {
257 if (error_code == net::ERR_ABORTED) {258 if (error_code == net::ERR_ABORTED) {
258 OnLoadStopped(validated_url);259 OnLoadStopped(validated_url);
259 } else {260 } else {
261 content::NavigationEntry* entry =
262 web_contents_->GetController().GetLastCommittedEntry();
260 OnLoadFailed(validated_url, error_code,263 OnLoadFailed(validated_url, error_code,
261 base::UTF16ToUTF8(error_description));264 base::UTF16ToUTF8(error_description),
265 is_provisional_load ? 0 : entry->GetHttpStatusCode());
262 }266 }
263}267}
264268
@@ -943,7 +947,8 @@
943947
944 content::NavigationEntry* entry =948 content::NavigationEntry* entry =
945 web_contents_->GetController().GetLastCommittedEntry();949 web_contents_->GetController().GetLastCommittedEntry();
946 OnLoadCommitted(url, entry->GetPageType() == content::PAGE_TYPE_ERROR);950 OnLoadCommitted(url, entry->GetPageType() == content::PAGE_TYPE_ERROR,
951 entry->GetHttpStatusCode());
947}952}
948953
949void WebView::DidFailProvisionalLoad(954void WebView::DidFailProvisionalLoad(
@@ -958,7 +963,7 @@
958963
959 if (!frame->parent() &&964 if (!frame->parent() &&
960 validated_url.spec() != content::kUnreachableWebDataURL) {965 validated_url.spec() != content::kUnreachableWebDataURL) {
961 DispatchLoadFailed(validated_url, error_code, error_description);966 DispatchLoadFailed(validated_url, error_code, error_description, true);
962 }967 }
963968
964 if (error_code != net::ERR_ABORTED) {969 if (error_code != net::ERR_ABORTED) {
@@ -1011,7 +1016,9 @@
1011 return;1016 return;
1012 }1017 }
10131018
1014 OnLoadSucceeded(validated_url);1019 content::NavigationEntry* entry =
1020 web_contents_->GetController().GetLastCommittedEntry();
1021 OnLoadSucceeded(validated_url, entry->GetHttpStatusCode());
1015}1022}
10161023
1017void WebView::DidFailLoad(content::RenderFrameHost* render_frame_host,1024void WebView::DidFailLoad(content::RenderFrameHost* render_frame_host,
@@ -1032,7 +1039,8 @@
1032 return;1039 return;
1033 }1040 }
10341041
1035 OnLoadRedirected(details.new_url, details.original_url);1042 OnLoadRedirected(details.new_url, details.original_url,
1043 details.http_response_code);
1036}1044}
10371045
1038void WebView::NavigationEntryCommitted(1046void WebView::NavigationEntryCommitted(
@@ -1126,14 +1134,18 @@
11261134
1127void WebView::OnLoadStarted(const GURL& validated_url) {}1135void WebView::OnLoadStarted(const GURL& validated_url) {}
1128void WebView::OnLoadRedirected(const GURL& url,1136void WebView::OnLoadRedirected(const GURL& url,
1129 const GURL& original_url) {}1137 const GURL& original_url,
1138 int http_status_code) {}
1130void WebView::OnLoadCommitted(const GURL& url,1139void WebView::OnLoadCommitted(const GURL& url,
1131 bool is_error_page) {}1140 bool is_error_page,
1141 int http_status_code) {}
1132void WebView::OnLoadStopped(const GURL& validated_url) {}1142void WebView::OnLoadStopped(const GURL& validated_url) {}
1133void WebView::OnLoadFailed(const GURL& validated_url,1143void WebView::OnLoadFailed(const GURL& validated_url,
1134 int error_code,1144 int error_code,
1135 const std::string& error_description) {}1145 const std::string& error_description,
1136void WebView::OnLoadSucceeded(const GURL& validated_url) {}1146 int http_status_code) {}
1147void WebView::OnLoadSucceeded(const GURL& validated_url,
1148 int http_status_code) {}
11371149
1138void WebView::OnNavigationEntryCommitted() {}1150void WebView::OnNavigationEntryCommitted() {}
1139void WebView::OnNavigationListPruned(bool from_front, int count) {}1151void WebView::OnNavigationListPruned(bool from_front, int count) {}
@@ -1470,7 +1482,7 @@
1470 params.base_url_for_data_url = baseUrl;1482 params.base_url_for_data_url = baseUrl;
1471 params.virtual_url_for_data_url = baseUrl.is_empty() ? GURL(url::kAboutBlankURL) : baseUrl;1483 params.virtual_url_for_data_url = baseUrl.is_empty() ? GURL(url::kAboutBlankURL) : baseUrl;
1472 params.can_load_local_resources = true;1484 params.can_load_local_resources = true;
1473 1485
1474 if (web_contents_) {1486 if (web_contents_) {
1475 web_contents_->GetController().LoadURLWithParams(params);1487 web_contents_->GetController().LoadURLWithParams(params);
1476 } else {1488 } else {
@@ -2082,7 +2094,7 @@
2082 return;2094 return;
2083 }2095 }
20842096
2085 SendFakeCompositionKeyEvent(host, blink::WebInputEvent::RawKeyDown); 2097 SendFakeCompositionKeyEvent(host, blink::WebInputEvent::RawKeyDown);
2086 host->ImeConfirmComposition(text, replacement_range, false);2098 host->ImeConfirmComposition(text, replacement_range, false);
2087 SendFakeCompositionKeyEvent(host, blink::WebInputEvent::KeyUp);2099 SendFakeCompositionKeyEvent(host, blink::WebInputEvent::KeyUp);
2088}2100}
@@ -2096,7 +2108,7 @@
2096 return;2108 return;
2097 }2109 }
20982110
2099 SendFakeCompositionKeyEvent(host, blink::WebInputEvent::RawKeyDown); 2111 SendFakeCompositionKeyEvent(host, blink::WebInputEvent::RawKeyDown);
2100 host->ImeSetComposition(text, underlines,2112 host->ImeSetComposition(text, underlines,
2101 selection_range.start(),2113 selection_range.start(),
2102 selection_range.end());2114 selection_range.end());
21032115
=== modified file 'shared/browser/oxide_web_view.h'
--- shared/browser/oxide_web_view.h 2015-05-14 15:37:57 +0000
+++ shared/browser/oxide_web_view.h 2015-05-15 12:21:58 +0000
@@ -282,7 +282,7 @@
282 bool strict_enforcement,282 bool strict_enforcement,
283 const base::Callback<void(bool)>& callback,283 const base::Callback<void(bool)>& callback,
284 content::CertificateRequestResultType* result);284 content::CertificateRequestResultType* result);
285 285
286 void HandleKeyEvent(const content::NativeWebKeyboardEvent& event);286 void HandleKeyEvent(const content::NativeWebKeyboardEvent& event);
287 void HandleMouseEvent(const blink::WebMouseEvent& event);287 void HandleMouseEvent(const blink::WebMouseEvent& event);
288 void HandleTouchEvent(const ui::TouchEvent& event);288 void HandleTouchEvent(const ui::TouchEvent& event);
@@ -341,7 +341,8 @@
341341
342 void DispatchLoadFailed(const GURL& validated_url,342 void DispatchLoadFailed(const GURL& validated_url,
343 int error_code,343 int error_code,
344 const base::string16& error_description);344 const base::string16& error_description,
345 bool is_provisional_load = false);
345346
346 void OnDidBlockDisplayingInsecureContent();347 void OnDidBlockDisplayingInsecureContent();
347 void OnDidBlockRunningInsecureContent();348 void OnDidBlockRunningInsecureContent();
@@ -501,14 +502,18 @@
501502
502 virtual void OnLoadStarted(const GURL& validated_url);503 virtual void OnLoadStarted(const GURL& validated_url);
503 virtual void OnLoadRedirected(const GURL& url,504 virtual void OnLoadRedirected(const GURL& url,
504 const GURL& original_url);505 const GURL& original_url,
506 int http_status_code);
505 virtual void OnLoadCommitted(const GURL& url,507 virtual void OnLoadCommitted(const GURL& url,
506 bool is_error_page);508 bool is_error_page,
509 int http_status_code);
507 virtual void OnLoadStopped(const GURL& validated_url);510 virtual void OnLoadStopped(const GURL& validated_url);
508 virtual void OnLoadFailed(const GURL& validated_url,511 virtual void OnLoadFailed(const GURL& validated_url,
509 int error_code,512 int error_code,
510 const std::string& error_description);513 const std::string& error_description,
511 virtual void OnLoadSucceeded(const GURL& validated_url);514 int http_status_code);
515 virtual void OnLoadSucceeded(const GURL& validated_url,
516 int http_status_code);
512517
513 virtual void OnNavigationEntryCommitted();518 virtual void OnNavigationEntryCommitted();
514 virtual void OnNavigationListPruned(bool from_front, int count);519 virtual void OnNavigationListPruned(bool from_front, int count);

Subscribers

People subscribed via source and target branches