Skip to content

Commit

Permalink
fix(http): return valid response for relative url xhr requests
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsChaceD committed Aug 9, 2023
1 parent 0cc927e commit bde6569
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 144 deletions.
91 changes: 49 additions & 42 deletions android/capacitor/src/main/assets/native-bridge.js
Expand Up @@ -496,29 +496,15 @@ var nativeBridge = (function (exports) {
});
},
},
response: {
value: '',
writable: true,
},
responseText: {
value: '',
writable: true,
},
responseURL: {
value: '',
writable: true,
},
status: {
value: 0,
writable: true,
},
});
xhr.readyState = 0;
const prototype = win.CapacitorWebXMLHttpRequest.prototype;
const isRelativeURL = (url) => !url || !(url.startsWith('http:') || url.startsWith('https:'));
const isProgressEventAvailable = () => typeof ProgressEvent !== 'undefined' &&
ProgressEvent.prototype instanceof Event;
// XHR patch abort
prototype.abort = function () {
if (this._url == null ||
!(this._url.startsWith('http:') || this._url.startsWith('https:'))) {
if (isRelativeURL(this._url)) {
return win.CapacitorWebXMLHttpRequest.abort.call(this);
}
this.readyState = 0;
Expand All @@ -531,7 +517,7 @@ var nativeBridge = (function (exports) {
prototype.open = function (method, url) {
this._url = url;
this._method = method;
if (!(url.startsWith('http:') || url.toString().startsWith('https:'))) {
if (isRelativeURL(url)) {
return win.CapacitorWebXMLHttpRequest.open.call(this, method, url);
}
setTimeout(() => {
Expand All @@ -541,22 +527,38 @@ var nativeBridge = (function (exports) {
};
// XHR patch set request header
prototype.setRequestHeader = function (header, value) {
if (this._url == null ||
!(this._url.startsWith('http:') || this._url.startsWith('https:'))) {
if (isRelativeURL(this._url)) {
return win.CapacitorWebXMLHttpRequest.setRequestHeader.call(this, header, value);
}
this._headers[header] = value;
};
// XHR patch send
prototype.send = function (body) {
if (this._url == null ||
!(this._url.startsWith('http:') || this._url.startsWith('https:'))) {
if (isRelativeURL(this._url)) {
return win.CapacitorWebXMLHttpRequest.send.call(this, body);
}
const tag = `CapacitorHttp XMLHttpRequest ${Date.now()} ${this._url}`;
console.time(tag);
try {
this.readyState = 2;
Object.defineProperties(this, {
response: {
value: '',
writable: true,
},
responseText: {
value: '',
writable: true,
},
responseURL: {
value: '',
writable: true,
},
status: {
value: 0,
writable: true,
},
});
convertBody(body).then(({ data, type, headers }) => {
const otherHeaders = this._headers != null && Object.keys(this._headers).length > 0
? this._headers
Expand All @@ -575,11 +577,13 @@ var nativeBridge = (function (exports) {
// intercept & parse response before returning
if (this.readyState == 2) {
//TODO: Add progress event emission on native side
this.dispatchEvent(new ProgressEvent('progress', {
lengthComputable: true,
loaded: nativeResponse.data.length,
total: nativeResponse.data.length,
}));
if (isProgressEventAvailable()) {
this.dispatchEvent(new ProgressEvent('progress', {
lengthComputable: true,
loaded: nativeResponse.data.length,
total: nativeResponse.data.length,
}));
}
this._headers = nativeResponse.headers;
this.status = nativeResponse.status;
if (this.responseType === '' ||
Expand Down Expand Up @@ -611,11 +615,13 @@ var nativeBridge = (function (exports) {
this.responseText = JSON.stringify(error.data);
this.responseURL = error.url;
this.readyState = 4;
this.dispatchEvent(new ProgressEvent('progress', {
lengthComputable: false,
loaded: 0,
total: 0,
}));
if (isProgressEventAvailable()) {
this.dispatchEvent(new ProgressEvent('progress', {
lengthComputable: false,
loaded: 0,
total: 0,
}));
}
setTimeout(() => {
this.dispatchEvent(new Event('error'));
this.dispatchEvent(new Event('loadend'));
Expand All @@ -631,11 +637,13 @@ var nativeBridge = (function (exports) {
this.responseText = error.toString();
this.responseURL = this._url;
this.readyState = 4;
this.dispatchEvent(new ProgressEvent('progress', {
lengthComputable: false,
loaded: 0,
total: 0,
}));
if (isProgressEventAvailable()) {
this.dispatchEvent(new ProgressEvent('progress', {
lengthComputable: false,
loaded: 0,
total: 0,
}));
}
setTimeout(() => {
this.dispatchEvent(new Event('error'));
this.dispatchEvent(new Event('loadend'));
Expand All @@ -645,8 +653,7 @@ var nativeBridge = (function (exports) {
};
// XHR patch getAllResponseHeaders
prototype.getAllResponseHeaders = function () {
if (this._url == null ||
!(this._url.startsWith('http:') || this._url.startsWith('https:'))) {
if (isRelativeURL(this._url)) {
return win.CapacitorWebXMLHttpRequest.getAllResponseHeaders.call(this);
}
let returnString = '';
Expand All @@ -659,8 +666,7 @@ var nativeBridge = (function (exports) {
};
// XHR patch getResponseHeader
prototype.getResponseHeader = function (name) {
if (this._url == null ||
!(this._url.startsWith('http:') || this._url.startsWith('https:'))) {
if (isRelativeURL(this._url)) {
return win.CapacitorWebXMLHttpRequest.getResponseHeader.call(this, name);
}
return this._headers[name];
Expand Down Expand Up @@ -896,6 +902,7 @@ var nativeBridge = (function (exports) {
});
});
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
cap.withPlugin = (_pluginId, _fn) => dummy;
cap.Exception = CapacitorException;
initEvents(win, cap);
Expand Down
119 changes: 59 additions & 60 deletions core/native-bridge.ts
Expand Up @@ -572,33 +572,20 @@ const initBridge = (w: any): void => {
});
},
},
response: {
value: '',
writable: true,
},
responseText: {
value: '',
writable: true,
},
responseURL: {
value: '',
writable: true,
},
status: {
value: 0,
writable: true,
},
});

xhr.readyState = 0;
const prototype = win.CapacitorWebXMLHttpRequest.prototype;

const isRelativeURL = (url: string | undefined) =>
!url || !(url.startsWith('http:') || url.startsWith('https:'));
const isProgressEventAvailable = () =>
typeof ProgressEvent !== 'undefined' &&
ProgressEvent.prototype instanceof Event;

// XHR patch abort
prototype.abort = function () {
if (
this._url == null ||
!(this._url.startsWith('http:') || this._url.startsWith('https:'))
) {
if (isRelativeURL(this._url)) {
return win.CapacitorWebXMLHttpRequest.abort.call(this);
}
this.readyState = 0;
Expand All @@ -613,9 +600,7 @@ const initBridge = (w: any): void => {
this._url = url;
this._method = method;

if (
!(url.startsWith('http:') || url.toString().startsWith('https:'))
) {
if (isRelativeURL(url)) {
return win.CapacitorWebXMLHttpRequest.open.call(
this,
method,
Expand All @@ -634,10 +619,7 @@ const initBridge = (w: any): void => {
header: string,
value: string,
) {
if (
this._url == null ||
!(this._url.startsWith('http:') || this._url.startsWith('https:'))
) {
if (isRelativeURL(this._url)) {
return win.CapacitorWebXMLHttpRequest.setRequestHeader.call(
this,
header,
Expand All @@ -649,10 +631,7 @@ const initBridge = (w: any): void => {

// XHR patch send
prototype.send = function (body?: Document | XMLHttpRequestBodyInit) {
if (
this._url == null ||
!(this._url.startsWith('http:') || this._url.startsWith('https:'))
) {
if (isRelativeURL(this._url)) {
return win.CapacitorWebXMLHttpRequest.send.call(this, body);
}

Expand All @@ -663,6 +642,26 @@ const initBridge = (w: any): void => {

try {
this.readyState = 2;

Object.defineProperties(this, {
response: {
value: '',
writable: true,
},
responseText: {
value: '',
writable: true,
},
responseURL: {
value: '',
writable: true,
},
status: {
value: 0,
writable: true,
},
});

convertBody(body).then(({ data, type, headers }) => {
const otherHeaders =
this._headers != null && Object.keys(this._headers).length > 0
Expand All @@ -685,13 +684,15 @@ const initBridge = (w: any): void => {
// intercept & parse response before returning
if (this.readyState == 2) {
//TODO: Add progress event emission on native side
this.dispatchEvent(
new ProgressEvent('progress', {
lengthComputable: true,
loaded: nativeResponse.data.length,
total: nativeResponse.data.length,
}),
);
if (isProgressEventAvailable()) {
this.dispatchEvent(
new ProgressEvent('progress', {
lengthComputable: true,
loaded: nativeResponse.data.length,
total: nativeResponse.data.length,
}),
);
}
this._headers = nativeResponse.headers;
this.status = nativeResponse.status;
if (
Expand Down Expand Up @@ -726,13 +727,15 @@ const initBridge = (w: any): void => {
this.responseText = JSON.stringify(error.data);
this.responseURL = error.url;
this.readyState = 4;
this.dispatchEvent(
new ProgressEvent('progress', {
lengthComputable: false,
loaded: 0,
total: 0,
}),
);
if (isProgressEventAvailable()) {
this.dispatchEvent(
new ProgressEvent('progress', {
lengthComputable: false,
loaded: 0,
total: 0,
}),
);
}
setTimeout(() => {
this.dispatchEvent(new Event('error'));
this.dispatchEvent(new Event('loadend'));
Expand All @@ -747,13 +750,15 @@ const initBridge = (w: any): void => {
this.responseText = error.toString();
this.responseURL = this._url;
this.readyState = 4;
this.dispatchEvent(
new ProgressEvent('progress', {
lengthComputable: false,
loaded: 0,
total: 0,
}),
);
if (isProgressEventAvailable()) {
this.dispatchEvent(
new ProgressEvent('progress', {
lengthComputable: false,
loaded: 0,
total: 0,
}),
);
}
setTimeout(() => {
this.dispatchEvent(new Event('error'));
this.dispatchEvent(new Event('loadend'));
Expand All @@ -764,10 +769,7 @@ const initBridge = (w: any): void => {

// XHR patch getAllResponseHeaders
prototype.getAllResponseHeaders = function () {
if (
this._url == null ||
!(this._url.startsWith('http:') || this._url.startsWith('https:'))
) {
if (isRelativeURL(this._url)) {
return win.CapacitorWebXMLHttpRequest.getAllResponseHeaders.call(
this,
);
Expand All @@ -784,10 +786,7 @@ const initBridge = (w: any): void => {

// XHR patch getResponseHeader
prototype.getResponseHeader = function (name: string) {
if (
this._url == null ||
!(this._url.startsWith('http:') || this._url.startsWith('https:'))
) {
if (isRelativeURL(this._url)) {
return win.CapacitorWebXMLHttpRequest.getResponseHeader.call(
this,
name,
Expand Down

0 comments on commit bde6569

Please sign in to comment.