@capacitor/ios 5.7.0 → 5.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -90,6 +90,8 @@ internal class CapacitorBridge: NSObject, CAPBridgeProtocol {
90
90
  static let tmpVCAppeared = Notification(name: Notification.Name(rawValue: "tmpViewControllerAppeared"))
91
91
  public static let capacitorSite = "https://capacitorjs.com/"
92
92
  public static let fileStartIdentifier = "/_capacitor_file_"
93
+ public static let httpInterceptorStartIdentifier = "/_capacitor_http_interceptor_"
94
+ public static let httpsInterceptorStartIdentifier = "/_capacitor_https_interceptor_"
93
95
  public static let defaultScheme = "capacitor"
94
96
 
95
97
  var webViewAssetHandler: WebViewAssetHandler
@@ -20,10 +20,25 @@ internal class WebViewAssetHandler: NSObject, WKURLSchemeHandler {
20
20
  self.serverUrl = serverUrl
21
21
  }
22
22
 
23
+ private func isUsingLiveReload(_ localUrl: URL) -> Bool {
24
+ return self.serverUrl != nil && self.serverUrl?.scheme != localUrl.scheme
25
+ }
26
+
23
27
  func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
24
28
  let startPath: String
25
29
  let url = urlSchemeTask.request.url!
26
30
  let stringToLoad = url.path
31
+ let localUrl = URL.init(string: url.absoluteString)!
32
+
33
+ if url.path.starts(with: CapacitorBridge.httpInterceptorStartIdentifier) {
34
+ handleCapacitorHttpRequest(urlSchemeTask, localUrl, false)
35
+ return
36
+ }
37
+
38
+ if url.path.starts(with: CapacitorBridge.httpsInterceptorStartIdentifier) {
39
+ handleCapacitorHttpRequest(urlSchemeTask, localUrl, true)
40
+ return
41
+ }
27
42
 
28
43
  if stringToLoad.starts(with: CapacitorBridge.fileStartIdentifier) {
29
44
  startPath = stringToLoad.replacingOccurrences(of: CapacitorBridge.fileStartIdentifier, with: "")
@@ -31,7 +46,6 @@ internal class WebViewAssetHandler: NSObject, WKURLSchemeHandler {
31
46
  startPath = router.route(for: stringToLoad)
32
47
  }
33
48
 
34
- let localUrl = URL.init(string: url.absoluteString)!
35
49
  let fileUrl = URL.init(fileURLWithPath: startPath)
36
50
 
37
51
  do {
@@ -43,9 +57,9 @@ internal class WebViewAssetHandler: NSObject, WKURLSchemeHandler {
43
57
  ]
44
58
 
45
59
  // if using live reload, then set CORS headers
46
- if self.serverUrl != nil && self.serverUrl?.scheme != localUrl.scheme {
60
+ if isUsingLiveReload(localUrl) {
47
61
  headers["Access-Control-Allow-Origin"] = self.serverUrl?.absoluteString
48
- headers["Access-Control-Allow-Methods"] = "GET, OPTIONS"
62
+ headers["Access-Control-Allow-Methods"] = "GET, HEAD, OPTIONS, TRACE"
49
63
  }
50
64
 
51
65
  if let rangeString = urlSchemeTask.request.value(forHTTPHeaderField: "Range"),
@@ -121,6 +135,68 @@ internal class WebViewAssetHandler: NSObject, WKURLSchemeHandler {
121
135
  return false
122
136
  }
123
137
 
138
+ func handleCapacitorHttpRequest(_ urlSchemeTask: WKURLSchemeTask, _ localUrl: URL, _ isHttpsRequest: Bool) {
139
+ var urlRequest = urlSchemeTask.request
140
+ guard let url = urlRequest.url else { return }
141
+ var targetUrl = url.absoluteString
142
+ .replacingOccurrences(of: CapacitorBridge.httpInterceptorStartIdentifier, with: "")
143
+ .replacingOccurrences(of: CapacitorBridge.httpsInterceptorStartIdentifier, with: "")
144
+ // Only replace first occurrence of the scheme
145
+ if let range = targetUrl.range(of: localUrl.scheme ?? InstanceDescriptorDefaults.scheme) {
146
+ targetUrl = targetUrl.replacingCharacters(in: range, with: isHttpsRequest ? "https" : "http")
147
+ }
148
+
149
+ // Only replace first occurrence of the hostname
150
+ if let range = targetUrl.range(of: (localUrl.host ?? InstanceDescriptorDefaults.hostname) + "/") {
151
+ targetUrl = targetUrl.replacingCharacters(in: range, with: "")
152
+ }
153
+
154
+ urlRequest.url = URL(string: targetUrl.removingPercentEncoding ?? targetUrl)
155
+
156
+ let urlSession = URLSession.shared
157
+ let task = urlSession.dataTask(with: urlRequest) { (data, response, error) in
158
+ if let error = error {
159
+ urlSchemeTask.didFailWithError(error)
160
+ return
161
+ }
162
+
163
+ if let response = response as? HTTPURLResponse {
164
+ let existingHeaders = response.allHeaderFields
165
+ var newHeaders: [AnyHashable: Any] = [:]
166
+
167
+ // if using live reload, then set CORS headers
168
+ if self.isUsingLiveReload(url) {
169
+ newHeaders = [
170
+ "Access-Control-Allow-Origin": self.serverUrl?.absoluteString ?? "",
171
+ "Access-Control-Allow-Methods": "GET, HEAD, OPTIONS, TRACE"
172
+ ]
173
+ }
174
+
175
+ if let mergedHeaders = existingHeaders.merging(newHeaders, uniquingKeysWith: { (current, _) in current }) as? [String: String] {
176
+
177
+ if let responseUrl = response.url {
178
+ if let modifiedResponse = HTTPURLResponse(
179
+ url: responseUrl,
180
+ statusCode: response.statusCode,
181
+ httpVersion: nil,
182
+ headerFields: mergedHeaders
183
+ ) {
184
+ urlSchemeTask.didReceive(modifiedResponse)
185
+ }
186
+ }
187
+
188
+ if let data = data {
189
+ urlSchemeTask.didReceive(data)
190
+ }
191
+ }
192
+ }
193
+ urlSchemeTask.didFinish()
194
+ return
195
+ }
196
+
197
+ task.resume()
198
+ }
199
+
124
200
  let mimeTypes = [
125
201
  "aaf": "application/octet-stream",
126
202
  "aca": "application/octet-stream",
@@ -130,6 +130,26 @@ var nativeBridge = (function (exports) {
130
130
  }
131
131
  return { data: body, type: 'json' };
132
132
  };
133
+ const CAPACITOR_HTTP_INTERCEPTOR = '/_capacitor_http_interceptor_';
134
+ const CAPACITOR_HTTPS_INTERCEPTOR = '/_capacitor_https_interceptor_';
135
+ // TODO: export as Cap function
136
+ const isRelativeOrProxyUrl = (url) => !url ||
137
+ !(url.startsWith('http:') || url.startsWith('https:')) ||
138
+ url.indexOf(CAPACITOR_HTTP_INTERCEPTOR) > -1 ||
139
+ url.indexOf(CAPACITOR_HTTPS_INTERCEPTOR) > -1;
140
+ // TODO: export as Cap function
141
+ const createProxyUrl = (url, win) => {
142
+ var _a, _b;
143
+ if (isRelativeOrProxyUrl(url))
144
+ return url;
145
+ let proxyUrl = new URL(url);
146
+ const isHttps = proxyUrl.protocol === 'https:';
147
+ const originalHost = encodeURIComponent(proxyUrl.host);
148
+ const originalPathname = proxyUrl.pathname;
149
+ proxyUrl = new URL((_b = (_a = win.Capacitor) === null || _a === void 0 ? void 0 : _a.getServerUrl()) !== null && _b !== void 0 ? _b : '');
150
+ proxyUrl.pathname = `${isHttps ? CAPACITOR_HTTPS_INTERCEPTOR : CAPACITOR_HTTP_INTERCEPTOR}/${originalHost}${originalPathname}`;
151
+ return proxyUrl.toString();
152
+ };
133
153
  const initBridge = (w) => {
134
154
  const getPlatformId = (win) => {
135
155
  var _a, _b;
@@ -476,6 +496,15 @@ var nativeBridge = (function (exports) {
476
496
  if (request.url.startsWith(`${cap.getServerUrl()}/`)) {
477
497
  return win.CapacitorWebFetch(resource, options);
478
498
  }
499
+ if (!(options === null || options === void 0 ? void 0 : options.method) ||
500
+ options.method.toLocaleUpperCase() === 'GET' ||
501
+ options.method.toLocaleUpperCase() === 'HEAD' ||
502
+ options.method.toLocaleUpperCase() === 'OPTIONS' ||
503
+ options.method.toLocaleUpperCase() === 'TRACE') {
504
+ const modifiedResource = createProxyUrl(resource.toString(), win);
505
+ const response = await win.CapacitorWebFetch(modifiedResource, options);
506
+ return response;
507
+ }
479
508
  const tag = `CapacitorHttp fetch ${Date.now()} ${resource}`;
480
509
  console.time(tag);
481
510
  try {
@@ -546,12 +575,11 @@ var nativeBridge = (function (exports) {
546
575
  });
547
576
  xhr.readyState = 0;
548
577
  const prototype = win.CapacitorWebXMLHttpRequest.prototype;
549
- const isRelativeURL = (url) => !url || !(url.startsWith('http:') || url.startsWith('https:'));
550
578
  const isProgressEventAvailable = () => typeof ProgressEvent !== 'undefined' &&
551
579
  ProgressEvent.prototype instanceof Event;
552
580
  // XHR patch abort
553
581
  prototype.abort = function () {
554
- if (isRelativeURL(this._url)) {
582
+ if (isRelativeOrProxyUrl(this._url)) {
555
583
  return win.CapacitorWebXMLHttpRequest.abort.call(this);
556
584
  }
557
585
  this.readyState = 0;
@@ -562,10 +590,18 @@ var nativeBridge = (function (exports) {
562
590
  };
563
591
  // XHR patch open
564
592
  prototype.open = function (method, url) {
593
+ this._method = method.toLocaleUpperCase();
565
594
  this._url = url;
566
- this._method = method;
567
- if (isRelativeURL(url)) {
568
- return win.CapacitorWebXMLHttpRequest.open.call(this, method, url);
595
+ if (!this._method ||
596
+ this._method === 'GET' ||
597
+ this._method === 'HEAD' ||
598
+ this._method === 'OPTIONS' ||
599
+ this._method === 'TRACE') {
600
+ if (isRelativeOrProxyUrl(url)) {
601
+ return win.CapacitorWebXMLHttpRequest.open.call(this, method, url);
602
+ }
603
+ this._url = createProxyUrl(this._url, win);
604
+ return win.CapacitorWebXMLHttpRequest.open.call(this, method, this._url);
569
605
  }
570
606
  setTimeout(() => {
571
607
  this.dispatchEvent(new Event('loadstart'));
@@ -574,14 +610,14 @@ var nativeBridge = (function (exports) {
574
610
  };
575
611
  // XHR patch set request header
576
612
  prototype.setRequestHeader = function (header, value) {
577
- if (isRelativeURL(this._url)) {
613
+ if (isRelativeOrProxyUrl(this._url)) {
578
614
  return win.CapacitorWebXMLHttpRequest.setRequestHeader.call(this, header, value);
579
615
  }
580
616
  this._headers[header] = value;
581
617
  };
582
618
  // XHR patch send
583
619
  prototype.send = function (body) {
584
- if (isRelativeURL(this._url)) {
620
+ if (isRelativeOrProxyUrl(this._url)) {
585
621
  return win.CapacitorWebXMLHttpRequest.send.call(this, body);
586
622
  }
587
623
  const tag = `CapacitorHttp XMLHttpRequest ${Date.now()} ${this._url}`;
@@ -710,7 +746,7 @@ var nativeBridge = (function (exports) {
710
746
  };
711
747
  // XHR patch getAllResponseHeaders
712
748
  prototype.getAllResponseHeaders = function () {
713
- if (isRelativeURL(this._url)) {
749
+ if (isRelativeOrProxyUrl(this._url)) {
714
750
  return win.CapacitorWebXMLHttpRequest.getAllResponseHeaders.call(this);
715
751
  }
716
752
  let returnString = '';
@@ -723,7 +759,7 @@ var nativeBridge = (function (exports) {
723
759
  };
724
760
  // XHR patch getResponseHeader
725
761
  prototype.getResponseHeader = function (name) {
726
- if (isRelativeURL(this._url)) {
762
+ if (isRelativeOrProxyUrl(this._url)) {
727
763
  return win.CapacitorWebXMLHttpRequest.getResponseHeader.call(this, name);
728
764
  }
729
765
  for (const key in this._headers) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/ios",
3
- "version": "5.7.0",
3
+ "version": "5.7.2",
4
4
  "description": "Capacitor: Cross-platform apps with JavaScript and the web",
5
5
  "homepage": "https://capacitorjs.com",
6
6
  "author": "Ionic Team <hi@ionic.io> (https://ionic.io)",