@cappitolian/http-local-server-swifter 0.0.9 → 0.0.11
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.
|
@@ -16,7 +16,7 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
|
|
|
16
16
|
private static var pendingResponses = [String: (String) -> Void]()
|
|
17
17
|
private static let queue = DispatchQueue(label: "com.cappitolian.HttpLocalServerSwifter.pendingResponses", qos: .userInitiated)
|
|
18
18
|
|
|
19
|
-
private let defaultTimeout: TimeInterval =
|
|
19
|
+
private let defaultTimeout: TimeInterval = 30.0 // Aumentado para debugging
|
|
20
20
|
private let defaultPort: UInt16 = 8080
|
|
21
21
|
|
|
22
22
|
// MARK: - Initialization
|
|
@@ -31,41 +31,31 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
|
|
|
31
31
|
|
|
32
32
|
// MARK: - Public Methods
|
|
33
33
|
@objc public func connect(_ call: CAPPluginCall) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
self.
|
|
34
|
+
// Stop existing server if running
|
|
35
|
+
self.disconnect()
|
|
36
|
+
|
|
37
|
+
self.webServer = HttpServer()
|
|
38
|
+
self.setupHandlers()
|
|
39
|
+
|
|
40
|
+
do {
|
|
41
|
+
try self.startServer()
|
|
42
|
+
let ip = Self.getWiFiAddress() ?? "127.0.0.1"
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
self.setupHandlers()
|
|
44
|
+
print("✅ HttpLocalServerSwifter: Server started on \(ip):\(self.defaultPort)")
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} catch {
|
|
54
|
-
call.reject("Failed to start server: \(error.localizedDescription)")
|
|
55
|
-
}
|
|
46
|
+
call.resolve([
|
|
47
|
+
"ip": ip,
|
|
48
|
+
"port": self.defaultPort
|
|
49
|
+
])
|
|
50
|
+
} catch {
|
|
51
|
+
print("❌ HttpLocalServerSwifter: Failed to start server - \(error.localizedDescription)")
|
|
52
|
+
call.reject("Failed to start server: \(error.localizedDescription)")
|
|
56
53
|
}
|
|
57
54
|
}
|
|
58
55
|
|
|
59
56
|
@objc public func disconnect(_ call: CAPPluginCall? = nil) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
call?.reject("Server instance deallocated")
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
self.disconnect()
|
|
67
|
-
call?.resolve()
|
|
68
|
-
}
|
|
57
|
+
disconnect()
|
|
58
|
+
call?.resolve()
|
|
69
59
|
}
|
|
70
60
|
|
|
71
61
|
// MARK: - Static Methods
|
|
@@ -74,6 +64,9 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
|
|
|
74
64
|
if let callback = pendingResponses[requestId] {
|
|
75
65
|
callback(body)
|
|
76
66
|
pendingResponses.removeValue(forKey: requestId)
|
|
67
|
+
print("✅ HttpLocalServerSwifter: Response sent for requestId: \(requestId)")
|
|
68
|
+
} else {
|
|
69
|
+
print("⚠️ HttpLocalServerSwifter: No pending callback for requestId: \(requestId)")
|
|
77
70
|
}
|
|
78
71
|
}
|
|
79
72
|
}
|
|
@@ -87,24 +80,44 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
|
|
|
87
80
|
Self.queue.async {
|
|
88
81
|
Self.pendingResponses.removeAll()
|
|
89
82
|
}
|
|
83
|
+
|
|
84
|
+
print("🛑 HttpLocalServerSwifter: Server stopped")
|
|
90
85
|
}
|
|
91
86
|
|
|
92
87
|
private func setupHandlers() {
|
|
93
88
|
guard let server = webServer else { return }
|
|
89
|
+
|
|
90
|
+
server["/"] = { [weak self] request in
|
|
91
|
+
return self?.handleRequest(request) ?? self?.errorResponse() ?? .internalServerError
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
server["/:path"] = { [weak self] request in
|
|
95
|
+
return self?.handleRequest(request) ?? self?.errorResponse() ?? .internalServerError
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Rutas con dos segmentos: /orders/{id}
|
|
99
|
+
server["/:first/:second"] = { [weak self] request in
|
|
100
|
+
return self?.handleRequest(request) ?? self?.errorResponse() ?? .internalServerError
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Rutas con tres segmentos por si acaso: /orders/{id}/status
|
|
104
|
+
server["/:first/:second/:third"] = { [weak self] request in
|
|
105
|
+
return self?.handleRequest(request) ?? self?.errorResponse() ?? .internalServerError
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
print("✅ HttpLocalServerSwifter: Handlers configured")
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private func handleRequest(_ request: HttpRequest) -> HttpResponse {
|
|
112
|
+
print("📨 HttpLocalServerSwifter: Received \(request.method) request to \(request.path)")
|
|
94
113
|
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Handle OPTIONS (CORS preflight)
|
|
102
|
-
if request.method == "OPTIONS" {
|
|
103
|
-
return self.corsResponse()
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return self.processRequest(request)
|
|
114
|
+
// Handle OPTIONS (CORS preflight)
|
|
115
|
+
if request.method == "OPTIONS" {
|
|
116
|
+
print("🔄 HttpLocalServerSwifter: Handling CORS preflight")
|
|
117
|
+
return corsResponse()
|
|
107
118
|
}
|
|
119
|
+
|
|
120
|
+
return processRequest(request)
|
|
108
121
|
}
|
|
109
122
|
|
|
110
123
|
private func processRequest(_ request: HttpRequest) -> HttpResponse {
|
|
@@ -147,7 +160,12 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
|
|
|
147
160
|
requestData["query"] = query
|
|
148
161
|
}
|
|
149
162
|
|
|
150
|
-
delegate
|
|
163
|
+
print("📤 HttpLocalServerSwifter: Notifying delegate with requestId: \(requestId)")
|
|
164
|
+
|
|
165
|
+
// Notify on main thread to ensure proper event delivery
|
|
166
|
+
DispatchQueue.main.async { [weak self] in
|
|
167
|
+
self?.delegate?.httpLocalServerSwifterDidReceiveRequest(requestData)
|
|
168
|
+
}
|
|
151
169
|
|
|
152
170
|
// Wait for JS response or timeout
|
|
153
171
|
let result = semaphore.wait(timeout: .now() + defaultTimeout)
|
|
@@ -159,16 +177,17 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
|
|
|
159
177
|
|
|
160
178
|
// Handle timeout
|
|
161
179
|
if result == .timedOut {
|
|
180
|
+
print("⏱️ HttpLocalServerSwifter: Request timeout for requestId: \(requestId)")
|
|
162
181
|
let timeoutResponse = "{\"error\":\"Request timeout\",\"requestId\":\"\(requestId)\"}"
|
|
163
182
|
return createJsonResponse(timeoutResponse, statusCode: 408)
|
|
164
183
|
}
|
|
165
184
|
|
|
166
185
|
let reply = responseString ?? "{\"error\":\"No response from handler\"}"
|
|
186
|
+
print("✅ HttpLocalServerSwifter: Sending response for requestId: \(requestId)")
|
|
167
187
|
return createJsonResponse(reply)
|
|
168
188
|
}
|
|
169
189
|
|
|
170
190
|
private func extractBody(from request: HttpRequest) -> String? {
|
|
171
|
-
// request.body ya es [UInt8], no es opcional
|
|
172
191
|
let bodyBytes = request.body
|
|
173
192
|
|
|
174
193
|
guard !bodyBytes.isEmpty else {
|
|
@@ -179,7 +198,6 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
|
|
|
179
198
|
}
|
|
180
199
|
|
|
181
200
|
private func extractHeaders(from request: HttpRequest) -> [String: String] {
|
|
182
|
-
// Swifter headers es [(String, String)], convertir a [String: String]
|
|
183
201
|
var headersDict: [String: String] = [:]
|
|
184
202
|
for (key, value) in request.headers {
|
|
185
203
|
headersDict[key] = value
|
|
@@ -188,7 +206,6 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
|
|
|
188
206
|
}
|
|
189
207
|
|
|
190
208
|
private func extractQuery(from request: HttpRequest) -> [String: String] {
|
|
191
|
-
// request.queryParams también es [(String, String)]
|
|
192
209
|
var queryDict: [String: String] = [:]
|
|
193
210
|
for (key, value) in request.queryParams {
|
|
194
211
|
queryDict[key] = value
|
|
@@ -254,8 +271,14 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
|
|
|
254
271
|
)
|
|
255
272
|
}
|
|
256
273
|
|
|
257
|
-
//
|
|
258
|
-
|
|
274
|
+
// Try to start on the default port
|
|
275
|
+
do {
|
|
276
|
+
try server.start(defaultPort, forceIPv4: true)
|
|
277
|
+
print("✅ HttpLocalServerSwifter: Server listening on port \(defaultPort)")
|
|
278
|
+
} catch {
|
|
279
|
+
print("❌ HttpLocalServerSwifter: Failed to bind to port \(defaultPort): \(error)")
|
|
280
|
+
throw error
|
|
281
|
+
}
|
|
259
282
|
}
|
|
260
283
|
|
|
261
284
|
// MARK: - Network Utilities
|
|
@@ -264,6 +287,7 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
|
|
|
264
287
|
var ifaddr: UnsafeMutablePointer<ifaddrs>?
|
|
265
288
|
|
|
266
289
|
guard getifaddrs(&ifaddr) == 0 else {
|
|
290
|
+
print("❌ HttpLocalServerSwifter: Failed to get network interfaces")
|
|
267
291
|
return nil
|
|
268
292
|
}
|
|
269
293
|
|
|
@@ -304,6 +328,8 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
|
|
|
304
328
|
|
|
305
329
|
address = String(cString: hostname)
|
|
306
330
|
|
|
331
|
+
print("📡 HttpLocalServerSwifter: Found \(name) interface with IP: \(address ?? "unknown")")
|
|
332
|
+
|
|
307
333
|
// Prefer en0 (WiFi) over pdp_ip0 (cellular)
|
|
308
334
|
if name == "en0" {
|
|
309
335
|
break
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import Capacitor
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Capacitor plugin for running a local HTTP server on the device.
|
|
6
|
-
* Allows receiving HTTP requests and sending responses from JavaScript.
|
|
7
|
-
*/
|
|
8
4
|
@objc(HttpLocalServerSwifterPlugin)
|
|
9
5
|
public class HttpLocalServerSwifterPlugin: CAPPlugin, CAPBridgedPlugin, HttpLocalServerSwifterDelegate {
|
|
10
6
|
// MARK: - CAPBridgedPlugin Properties
|
|
@@ -19,59 +15,56 @@ public class HttpLocalServerSwifterPlugin: CAPPlugin, CAPBridgedPlugin, HttpLoca
|
|
|
19
15
|
// MARK: - Properties
|
|
20
16
|
private var localServer: HttpLocalServerSwifter?
|
|
21
17
|
|
|
22
|
-
// MARK: -
|
|
18
|
+
// MARK: - Lifecycle
|
|
19
|
+
public override func load() {
|
|
20
|
+
print("✅ HttpLocalServerSwifterPlugin: Plugin loaded")
|
|
21
|
+
}
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
* Starts the local HTTP server.
|
|
26
|
-
* @return ip: The server's IP address
|
|
27
|
-
* @return port: The port the server is listening on
|
|
28
|
-
*/
|
|
23
|
+
// MARK: - Plugin Methods
|
|
29
24
|
@objc func connect(_ call: CAPPluginCall) {
|
|
25
|
+
print("📞 HttpLocalServerSwifterPlugin: connect() called")
|
|
26
|
+
|
|
30
27
|
if localServer == nil {
|
|
31
28
|
localServer = HttpLocalServerSwifter(delegate: self)
|
|
29
|
+
print("✅ HttpLocalServerSwifterPlugin: Server instance created")
|
|
32
30
|
}
|
|
31
|
+
|
|
33
32
|
localServer?.connect(call)
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
/**
|
|
37
|
-
* Stops the local HTTP server.
|
|
38
|
-
* Cleans up all resources and pending requests.
|
|
39
|
-
*/
|
|
40
35
|
@objc func disconnect(_ call: CAPPluginCall) {
|
|
36
|
+
print("📞 HttpLocalServerSwifterPlugin: disconnect() called")
|
|
37
|
+
|
|
41
38
|
if localServer != nil {
|
|
42
39
|
localServer?.disconnect(call)
|
|
40
|
+
localServer = nil
|
|
43
41
|
} else {
|
|
44
42
|
call.resolve()
|
|
45
43
|
}
|
|
46
44
|
}
|
|
47
45
|
|
|
48
|
-
/**
|
|
49
|
-
* Sends a response back to the client that made the request.
|
|
50
|
-
* @param requestId Unique request ID (received in 'onRequest')
|
|
51
|
-
* @param body Response body (typically stringified JSON)
|
|
52
|
-
*/
|
|
53
46
|
@objc func sendResponse(_ call: CAPPluginCall) {
|
|
54
47
|
guard let requestId = call.getString("requestId") else {
|
|
48
|
+
print("❌ HttpLocalServerSwifterPlugin: Missing requestId")
|
|
55
49
|
call.reject("Missing requestId")
|
|
56
50
|
return
|
|
57
51
|
}
|
|
58
52
|
|
|
59
53
|
guard let body = call.getString("body") else {
|
|
54
|
+
print("❌ HttpLocalServerSwifterPlugin: Missing body")
|
|
60
55
|
call.reject("Missing body")
|
|
61
56
|
return
|
|
62
57
|
}
|
|
63
58
|
|
|
59
|
+
print("📤 HttpLocalServerSwifterPlugin: sendResponse for requestId: \(requestId)")
|
|
64
60
|
HttpLocalServerSwifter.handleJsResponse(requestId: requestId, body: body)
|
|
65
61
|
call.resolve()
|
|
66
62
|
}
|
|
67
63
|
|
|
68
64
|
// MARK: - HttpLocalServerSwifterDelegate
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Delegate method called when the server receives an HTTP request.
|
|
72
|
-
* Notifies JavaScript via the 'onRequest' event.
|
|
73
|
-
*/
|
|
74
65
|
public func httpLocalServerSwifterDidReceiveRequest(_ data: [String: Any]) {
|
|
66
|
+
print("📨 HttpLocalServerSwifterPlugin: Received request, notifying listeners")
|
|
67
|
+
print(" Request data: \(data)")
|
|
75
68
|
notifyListeners("onRequest", data: data)
|
|
76
69
|
}
|
|
77
70
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cappitolian/http-local-server-swifter",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"description": "Runs a local HTTP server on your device, accessible over LAN. Supports connect, disconnect, GET, and POST methods with IP and port discovery.",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|