Selaa lähdekoodia

refactor(parselog): accept io.Reader instead of path

parseStatusLog() now accepts a io.Reader interface instead of a file path
now in order to increase modularity and
testablity of the unit.

Existing references are updated to use the change in the
function signature.
Mustafa Arici 7 vuotta sitten
vanhempi
commit
85478d5e5a
3 muutettua tiedostoa jossa 34 lisäystä ja 20 poistoa
  1. 18 18
      parselog.go
  2. 9 1
      user.go
  3. 7 1
      vpn.go

+ 18 - 18
parselog.go

@@ -2,7 +2,7 @@ package ovpm
 
 import (
 	"bufio"
-	"os"
+	"io"
 	"strconv"
 	"strings"
 	"time"
@@ -29,7 +29,7 @@ type rtEntry struct {
 
 // parseStatusLog parses the received OpenVPN status log file.
 // And then returns the parsed client information.
-func parseStatusLog(fPath string) ([]clEntry, []rtEntry) {
+func parseStatusLog(f io.Reader) ([]clEntry, []rtEntry) {
 	// Parsing stages.
 	const stageCL int = 0
 	const stageRT int = 1
@@ -41,11 +41,6 @@ func parseStatusLog(fPath string) ([]clEntry, []rtEntry) {
 	var cl []clEntry
 	var rt []rtEntry
 
-	f, err := os.Open(fPath)
-	if err != nil {
-		panic(err)
-	}
-
 	// Scan and parse the file by dividing it into chunks.
 	scanner, skipFor := bufio.NewScanner(f), 3
 	for lc := 0; scanner.Scan(); lc++ {
@@ -56,30 +51,30 @@ func parseStatusLog(fPath string) ([]clEntry, []rtEntry) {
 		txt := scanner.Text()
 		switch currStage {
 		case stageCL:
-			if txt == "ROUTING TABLE" {
+			if strings.Contains(txt, "ROUTING TABLE") {
 				currStage = stageRT
 				skipFor = 1
 				continue
 			}
 			dat := strings.Split(txt, ",")
 			cl = append(cl, clEntry{
-				CommonName:     dat[0],
-				RealAddress:    dat[1],
-				BytesReceived:  stoui64(dat[2]),
-				BytesSent:      stoui64(dat[3]),
-				ConnectedSince: stodt(dat[4]),
+				CommonName:     trim(dat[0]),
+				RealAddress:    trim(dat[1]),
+				BytesReceived:  stoui64(trim(dat[2])),
+				BytesSent:      stoui64(trim(dat[3])),
+				ConnectedSince: stodt(trim(dat[4])),
 			})
 		case stageRT:
-			if txt == "GLOBAL STATS" {
+			if strings.Contains(txt, "GLOBAL STATS") {
 				currStage = stageFin
 				break
 			}
 			dat := strings.Split(txt, ",")
 			rt = append(rt, rtEntry{
-				VirtualAddress: dat[0],
-				CommonName:     dat[1],
-				RealAddress:    dat[2],
-				LastRef:        stodt(dat[3]),
+				VirtualAddress: trim(dat[0]),
+				CommonName:     trim(dat[1]),
+				RealAddress:    trim(dat[2]),
+				LastRef:        stodt(trim(dat[3])),
 			})
 		}
 	}
@@ -107,3 +102,8 @@ func stodt(s string) time.Time {
 	}
 	return t
 }
+
+// trim will trim all leading and trailing whitespace from the s.
+func trim(s string) string {
+	return strings.TrimSpace(s)
+}

+ 9 - 1
user.go

@@ -3,6 +3,7 @@ package ovpm
 import (
 	"fmt"
 	"net"
+	"os"
 	"time"
 
 	passlib "gopkg.in/hlandau/passlib.v1"
@@ -433,7 +434,14 @@ func (u *User) getKey() string {
 // ConnectionStatus returns information about user's connection to the VPN server.
 func (u *User) ConnectionStatus() (isConnected bool, connectedSince time.Time, bytesSent uint64, bytesReceived uint64) {
 	var found *clEntry
-	cl, _ := parseStatusLog(_DefaultStatusLogPath)
+
+	// Open the status log file.
+	f, err := os.Open(_DefaultStatusLogPath)
+	if err != nil {
+		panic(err)
+	}
+
+	cl, _ := parseStatusLog(f)
 	for _, c := range cl {
 		if c.CommonName == u.Username {
 			found = &c

+ 7 - 1
vpn.go

@@ -640,8 +640,14 @@ func GetServerInstance() (*Server, error) {
 // to the VPN service.
 func GetConnectedUsers() ([]User, error) {
 	var users []User
-	cl, _ := parseStatusLog(_DefaultStatusLogPath)
 
+	// Open the status log file.
+	f, err := os.Open(_DefaultStatusLogPath)
+	if err != nil {
+		panic(err)
+	}
+
+	cl, _ := parseStatusLog(f)
 	for _, c := range cl {
 		var u dbUserModel
 		q := db.Where(dbUserModel{Username: c.CommonName}).First(&u)