Skip to content

Commit 723e478

Browse files
authored
Merge branch 'dev' into main
2 parents 00751f3 + 1030390 commit 723e478

File tree

7 files changed

+93
-42
lines changed

7 files changed

+93
-42
lines changed

.github/templates/README.template.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# WoL Client
1+
<h1 align="center">WoL Client</h1>
22

33
<p align="center">
44
🖥️ Wake-on-LAN API · WebSocket & HTTP Interface · Docker Ready
@@ -81,7 +81,7 @@ curl -X POST "http://wol-client:5555/start" \
8181
> [!NOTE]
8282
> The `startupTime` field may be omitted. In that case, the [`PING_INTERVAL`](#ping_interval) and [`PING_RETRIES`](#ping_retries) settings will be used to periodically ping the host.
8383
84-
**WoL Client** will respond with a `client_id`, which can be used to establish a **WebSocket connection** at `ws://wol-client/ws`.
84+
**WoL Client** will respond with a `client_id`, which can be used to establish a **WebSocket connection** at `ws://wol-client:5555/ws`.
8585
This WebSocket will send updates for each step of the process. The response contains:
8686

8787
- `success`: `true` if the process finished successfully.

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# WoL Client
1+
<h1 align="center">WoL Client</h1>
22

33
<p align="center">
44
🖥️ Wake-on-LAN API · WebSocket & HTTP Interface · Docker Ready
@@ -94,7 +94,7 @@ curl -X POST "http://wol-client:5555/start" \
9494
> [!NOTE]
9595
> The `startupTime` field may be omitted. In that case, the [`PING_INTERVAL`](#ping_interval) and [`PING_RETRIES`](#ping_retries) settings will be used to periodically ping the host.
9696

97-
**WoL Client** will respond with a `client_id`, which can be used to establish a **WebSocket connection** at `ws://wol-client/ws`.
97+
**WoL Client** will respond with a `client_id`, which can be used to establish a **WebSocket connection** at `ws://wol-client:5555/ws`.
9898
This WebSocket will send updates for each step of the process. The response contains:
9999

100100
- `success`: `true` if the process finished successfully.

internals/config/config.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010

1111
var ENV = &structure.ENV{
1212
LOG_LEVEL: "info",
13-
PORT: "5555",
1413
PING_INTERVAL: 5,
1514
PING_RETRIES: 7,
1615
}

internals/server/http.go

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package server
33
import (
44
"encoding/json"
55
"net/http"
6+
"strconv"
67
"time"
78

89
"github.com/codeshelldev/gotl/pkg/logger"
@@ -40,99 +41,133 @@ func httpHandler(w http.ResponseWriter, req *http.Request) {
4041
"client_id": clientID,
4142
}
4243

44+
respBytes, err := json.Marshal(resp)
45+
46+
if err != nil {
47+
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
48+
}
49+
50+
logger.Debug("Sending client_id to client")
51+
4352
w.Header().Set("Content-Type", "application/json")
44-
json.NewEncoder(w).Encode(resp)
53+
w.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
54+
w.Write(respBytes)
55+
56+
f, ok := w.(http.Flusher)
57+
if ok {
58+
f.Flush()
59+
}
60+
61+
logger.Debug("Waiting for client to establish websocket connection")
4562

46-
client, err := waitForClient(clientID, time.Duration(15 * time.Second))
63+
client, err := waitForClient(clientID, time.Duration(20 * time.Second))
4764

4865
if err != nil {
4966
logger.Error("Could not get client: ", err.Error())
5067
return
5168
}
5269

70+
logger.Debug("Pinging host")
71+
5372
reachable, err := tryPing(client, body.IP,
5473
func() (bool, error) {
5574
sendToClient(client, map[string]any{
5675
"success": true,
57-
"message": "Host is reachable",
76+
"message": "Host is reachable.",
5877
})
5978
return true, nil
6079
},
6180
func() (bool, error) {
6281
sendToClient(client, map[string]any{
6382
"success": false,
64-
"message": "Host is unreachable",
83+
"message": "Host is unreachable.",
6584
})
6685
return false, nil
6786
},
6887
)
6988

89+
logger.Debug("Host is unreachable")
90+
7091
if reachable || err != nil {
7192
closeClient(client)
7293
return
7394
}
7495

7596
sendToClient(client, map[string]any{
7697
"success": false,
77-
"message": "Sending wakeup packets",
98+
"message": "Sending wakeup packets...",
7899
})
79100

80-
addr := body.IP
101+
addr := body.IP + ":9"
81102

82103
if body.Addr != "" {
83104
addr = body.Addr
84105
}
85106

107+
logger.Debug("Waking up host")
108+
86109
err = wol.Wake(addr, body.Mac)
87110

88111
if err != nil {
112+
logger.Error("Error waking up host: ", err.Error())
113+
89114
sendToClient(client, map[string]any{
90115
"success": false,
91116
"error": true,
92-
"message": "Could not wake up host",
117+
"message": "Could not wake up host.",
93118
})
94119

95120
closeClient(client)
96121
return
97122
}
98123

124+
logger.Debug("Pinging host again")
125+
99126
if body.StartupTime != nil {
100127
time.Sleep(time.Duration(*body.StartupTime) * time.Second)
101128

102-
reachable, err = tryPing(client, body.Addr,
129+
reachable, err = tryPing(client, body.IP,
103130
func() (bool, error) {
104131
sendToClient(client, map[string]any{
105132
"success": true,
106-
"message": "Host is now reachable",
133+
"message": "Host is now reachable.",
107134
})
108135
return true, nil
109136
},
110137
func() (bool, error) {
111138
sendToClient(client, map[string]any{
112139
"success": false,
113140
"error": true,
114-
"message": "Host is still unreachable",
141+
"message": "Host is still unreachable.",
115142
})
116143
return false, nil
117144
},
118145
)
119146

147+
if reachable {
148+
logger.Debug("Host is now reachable.")
149+
} else {
150+
logger.Debug("Host is still unreachable.")
151+
}
152+
120153
closeClient(client)
121154
return
122155
}
123156

124-
success, err := tryPingInterval(client, config.ENV.PING_INTERVAL, config.ENV.PING_RETRIES, body.Addr)
157+
success, err := tryPingInterval(client, config.ENV.PING_INTERVAL, config.ENV.PING_RETRIES, body.IP)
125158

126159
if success {
160+
logger.Debug("Host is now reachable.")
127161
sendToClient(client, map[string]any{
128162
"success": true,
129-
"message": "Host is now reachable",
163+
"message": "Host is now reachable.",
130164
})
131165
} else if !success && err == nil {
166+
logger.Debug("Host is still unreachable.")
132167
sendToClient(client, map[string]any{
133168
"success": false,
134169
"error": true,
135-
"message": "Host is still unreachable",
170+
"message": "Host is still unreachable.",
136171
})
137172
}
138173

internals/server/server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ func Handle() http.Handler {
1414
mux.HandleFunc("/ws", websocketHandler)
1515

1616
final := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
17-
mux.ServeHTTP(w, r)
18-
1917
logger.Info(r.Method, " ", r.URL.Path, " ", r.URL.RawQuery)
18+
19+
mux.ServeHTTP(w, r)
2020
})
2121

2222
return final

internals/server/websocket.go

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ var upgrader = websocket.Upgrader{
1414
CheckOrigin: func(r *http.Request) bool { return true },
1515
}
1616

17-
var waiters = make(map[string]chan *websocket.Conn)
17+
var waiters = map[string]chan *websocket.Conn{}
1818
var waitersMutex = &sync.Mutex{}
1919

20-
var clients = make(map[string]*websocket.Conn)
20+
var clients = map[string]*websocket.Conn{}
2121
var clientsMutex = &sync.Mutex{}
2222

2323
func websocketHandler(w http.ResponseWriter, req *http.Request) {
@@ -59,10 +59,14 @@ func register(req *http.Request, socket *websocket.Conn) string {
5959
clientsMutex.Lock()
6060
clients[clientID] = socket
6161
clientsMutex.Unlock()
62-
waitersMutex.Lock()
63-
if ch, ok := waiters[clientID]; ok {
64-
ch <- socket
6562

63+
waitersMutex.Lock()
64+
ch, ok := waiters[clientID]
65+
if ok {
66+
select {
67+
case ch <- socket:
68+
default:
69+
}
6670
close(ch)
6771
delete(waiters, clientID)
6872
}
@@ -72,24 +76,31 @@ func register(req *http.Request, socket *websocket.Conn) string {
7276
}
7377

7478
func waitForClient(clientID string, timeout time.Duration) (*websocket.Conn, error) {
75-
waitCh := make(chan *websocket.Conn, 1)
76-
77-
waitersMutex.Lock()
78-
waiters[clientID] = waitCh
79-
waitersMutex.Unlock()
80-
81-
select {
82-
case conn := <-waitCh:
83-
return conn, nil
84-
case <-time.After(timeout):
85-
waitersMutex.Lock()
86-
delete(waiters, clientID)
87-
waitersMutex.Unlock()
88-
return nil, errors.New("Timed out waiting for client")
89-
}
79+
clientsMutex.Lock()
80+
conn, ok := clients[clientID]
81+
if ok {
82+
clientsMutex.Unlock()
83+
return conn, nil
84+
}
85+
clientsMutex.Unlock()
86+
87+
waitCh := make(chan *websocket.Conn, 1)
88+
89+
waitersMutex.Lock()
90+
waiters[clientID] = waitCh
91+
waitersMutex.Unlock()
92+
93+
select {
94+
case conn := <-waitCh:
95+
return conn, nil
96+
case <-time.After(timeout):
97+
waitersMutex.Lock()
98+
delete(waiters, clientID)
99+
waitersMutex.Unlock()
100+
return nil, errors.New("Timed out waiting for client")
101+
}
90102
}
91103

92-
93104
func sendToClient(client *websocket.Conn, data map[string]any) error {
94105
return client.WriteJSON(data)
95106
}

internals/wol/wol.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package wol
22

33
import (
4+
"errors"
45
"net"
56

67
"github.com/codeshelldev/gotl/pkg/logger"
@@ -19,7 +20,12 @@ func Init() {
1920
}
2021

2122
func Wake(addr, mac string) error {
22-
return client.Wake(addr, net.HardwareAddr(mac))
23+
hwAddr, err := net.ParseMAC(mac)
24+
if err != nil {
25+
return errors.New("Could not parse mac: " + mac)
26+
}
27+
return client.Wake(addr, hwAddr)
28+
2329
}
2430

2531
func Close() {

0 commit comments

Comments
 (0)