2022-06-24 15:31:48 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2022-06-28 15:11:46 +02:00
|
|
|
"embed"
|
2022-06-24 15:31:48 +02:00
|
|
|
_ "embed"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"os/exec"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
"velvettear/go-scan/config"
|
|
|
|
"velvettear/go-scan/log"
|
|
|
|
"velvettear/go-scan/util/date"
|
|
|
|
)
|
|
|
|
|
2022-06-28 15:11:46 +02:00
|
|
|
//go:embed resources
|
|
|
|
var resources embed.FS
|
2022-06-24 15:31:48 +02:00
|
|
|
|
|
|
|
var configuration config.Config
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
configuration = config.New()
|
|
|
|
startServer()
|
|
|
|
}
|
|
|
|
|
|
|
|
func startServer() {
|
|
|
|
serverAddress := configuration.ServerConfig.Address + ":" + configuration.ServerConfig.Port
|
2022-06-28 15:11:46 +02:00
|
|
|
http.HandleFunc("/favicon.ico", serveResources)
|
|
|
|
http.HandleFunc("/resources/", serveResources)
|
2022-06-24 15:31:48 +02:00
|
|
|
http.HandleFunc("/", handleHTTPRequests)
|
|
|
|
log.Info("starting server '" + serverAddress + "'...")
|
|
|
|
error := http.ListenAndServe(serverAddress, nil)
|
|
|
|
if error != nil {
|
|
|
|
log.Error("an error occured starting the server", error.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-28 15:11:46 +02:00
|
|
|
func serveResources(writer http.ResponseWriter, request *http.Request) {
|
|
|
|
var resource string
|
|
|
|
if strings.HasSuffix(request.URL.Path, "favicon.ico") {
|
|
|
|
resource = "resources/gopher.png"
|
|
|
|
} else {
|
|
|
|
resource = strings.TrimPrefix(request.URL.Path, "/")
|
|
|
|
}
|
|
|
|
bytes, error := resources.ReadFile(resource)
|
|
|
|
if error != nil {
|
|
|
|
log.Error("an error occured serving the resource '"+resource+"'", error.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
log.Debug("serving '" + resource + "'...")
|
|
|
|
if strings.HasSuffix(resource, "svg") {
|
|
|
|
writer.Header().Set("Content-Type", "image/svg+xml")
|
|
|
|
}
|
|
|
|
writer.Write(bytes)
|
|
|
|
}
|
|
|
|
|
2022-06-24 15:31:48 +02:00
|
|
|
func handleHTTPRequests(writer http.ResponseWriter, request *http.Request) {
|
|
|
|
if strings.ToLower(request.Method) == "post" {
|
|
|
|
result := handleScan(request)
|
|
|
|
writer.Header().Set("Content-Type", "application/json")
|
|
|
|
json, _ := json.Marshal(result)
|
|
|
|
writer.Write(json)
|
|
|
|
return
|
|
|
|
}
|
2022-06-28 15:11:46 +02:00
|
|
|
resource := "resources/index.html"
|
|
|
|
bytes, error := resources.ReadFile(resource)
|
|
|
|
if error != nil {
|
|
|
|
log.Error("an error occured serving the resource '"+resource+"'", error.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
log.Debug("serving '" + resource + "'...")
|
|
|
|
writer.Write(bytes)
|
2022-06-24 15:31:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func handleScan(request *http.Request) *result {
|
|
|
|
log.Info("starting scan...")
|
|
|
|
timestamp := date.Milliseconds()
|
|
|
|
|
|
|
|
var parameters requestParameters
|
|
|
|
parseErr := json.NewDecoder(request.Body).Decode(¶meters)
|
|
|
|
if parseErr != nil {
|
|
|
|
log.Error("error parsing request parameters", parseErr.Error())
|
|
|
|
}
|
|
|
|
scanName := generateScanName(parameters.Filename)
|
|
|
|
args := []string{}
|
|
|
|
if len(configuration.ScannerConfig.Scanner) > 0 {
|
|
|
|
args = append(args, "-d")
|
|
|
|
args = append(args, configuration.ScannerConfig.Scanner)
|
|
|
|
}
|
|
|
|
args = append(args, "-o")
|
|
|
|
args = append(args, scanName)
|
|
|
|
extraArgs := strings.Split(configuration.ScannerConfig.Arguments, " ")
|
|
|
|
for index := 0; index < len(extraArgs); index++ {
|
|
|
|
args = append(args, extraArgs[index])
|
|
|
|
}
|
|
|
|
log.Debug("executing command 'scanimage'...", args...)
|
|
|
|
scanCmd := exec.Command(
|
|
|
|
"scanimage",
|
|
|
|
args...,
|
|
|
|
)
|
|
|
|
_, err := scanCmd.Output()
|
|
|
|
if err != nil {
|
|
|
|
log.Error("an error occured executing the scan", err.Error())
|
|
|
|
result := &result{
|
|
|
|
State: "error",
|
|
|
|
Message: err.Error(),
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
result := &result{
|
|
|
|
State: "ok",
|
|
|
|
Message: scanName,
|
|
|
|
}
|
|
|
|
log.Info("finished scan after "+strconv.Itoa(date.GetTimeDifference(timestamp))+"ms", scanName)
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateScanName(filename string) string {
|
|
|
|
if len(filename) == 0 {
|
|
|
|
day := fmt.Sprint(time.Now().Day())
|
|
|
|
if len(day) < 2 {
|
|
|
|
day = "0" + day
|
|
|
|
}
|
|
|
|
month := fmt.Sprint(int(time.Now().Month()))
|
|
|
|
if len(month) < 2 {
|
|
|
|
month = "0" + month
|
|
|
|
}
|
|
|
|
hour := fmt.Sprint(time.Now().Hour())
|
|
|
|
if len(hour) < 2 {
|
|
|
|
hour = "0" + hour
|
|
|
|
}
|
|
|
|
minute := fmt.Sprint(time.Now().Minute())
|
|
|
|
if len(minute) < 2 {
|
|
|
|
minute = "0" + minute
|
|
|
|
}
|
|
|
|
second := fmt.Sprint(time.Now().Second())
|
|
|
|
if len(second) < 2 {
|
|
|
|
second = "0" + second
|
|
|
|
}
|
|
|
|
filename = day + month + fmt.Sprint(time.Now().Year()) + "-" + hour + minute + second
|
|
|
|
}
|
|
|
|
if !strings.HasSuffix(filename, ".png") {
|
|
|
|
filename += ".png"
|
|
|
|
}
|
|
|
|
return configuration.ScannerConfig.OutputDirectory + filename
|
|
|
|
}
|
|
|
|
|
|
|
|
// structs
|
|
|
|
type result struct {
|
|
|
|
State string
|
|
|
|
Message string
|
|
|
|
}
|
|
|
|
|
|
|
|
type requestParameters struct {
|
|
|
|
Filename string
|
|
|
|
}
|