forked from empijei/wapty
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.go
110 lines (98 loc) · 3.34 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package mocksy
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
)
// histDir is the directory to load XML from
var histDir string = "."
// LoadResponseHistory loads all XML files found in `histDir` into the matcher's history.
// It does NOT clear the current history (use `ClearHistory()` for that).
// It does NOT recurse on the directory.
// In case of errors, it tries to load as much files as possible and reports the error afterwards.
func LoadResponseHistory(dir string) error {
files, err := ioutil.ReadDir(dir)
if err != nil {
return fmt.Errorf("mocksy: Error reading history directory: %s", err.Error())
}
totLoaded := 0
errorMsgs := make([]string, 0)
for _, file := range files {
if file.IsDir() || !strings.HasSuffix(file.Name(), ".xml") {
continue
}
fp, err := os.Open(file.Name())
if err == nil {
if err = LoadResponsesFrom(fp); err != nil {
errorMsgs = append(errorMsgs, err.Error())
} else {
fmt.Fprintf(outw, "Loaded history file %s\n", file.Name())
totLoaded++
}
} else {
errorMsgs = append(errorMsgs, err.Error())
}
}
fmt.Fprintf(outw, "Loaded %d files correctly (history size = %d).\n", totLoaded, HistoryLength())
if len(errorMsgs) > 0 {
return fmt.Errorf("mocksy: Error importing %d files: %v", len(errorMsgs), errorMsgs)
}
return nil
}
// LoadResponseFrom decodes an XML source and loads all req-resp pairs in the matcher's responseHistory.
func LoadResponsesFrom(source io.ReadSeeker) error {
// Go refuses to parse any XML whose version is != "1.0". Burp sometimes
// declares XML 1.1, albeit it uses no 1.1-only features, so we trick
// the XML parser into parsing our "invalid" XML by skipping the XML header.
buf := make([]byte, len(`<?xml version="1.x"?>`))
if n, err := source.Read(buf); err == nil && n == len(buf) {
// Check we actually skipped the XML header and, if not, rewind.
if !bytes.Equal(buf[:len(`<?xml`)], []byte(`<?xml`)) {
if _, err = source.Seek(0, io.SeekStart); err != nil {
return fmt.Errorf("mocksy: error importing data: reader rewind failed.\n")
}
}
} else {
return fmt.Errorf("mocksy: error importing data: header skip failed.\n")
}
items, err := BurpImport(source)
if err != nil {
return fmt.Errorf("mocksy: error importing data:\n\t%s", err.Error())
}
for _, item := range items.Items {
AddToHistory(item)
}
log.Printf("Loaded %d Request-Response pairs.\n", len(items.Items))
return nil
}
// SetHistDir changes the value of the history load directory. Calling `LoadResponseHistory` after this
// will load all the XML files found in the given directory.
func SetHistDir(dir string) {
histDir = dir
}
// StartServer loads the response history from `histDir` and starts the Mocksy server on given `port`
func StartServer(port string) error {
if err := LoadResponseHistory(histDir); err != nil {
return fmt.Errorf("mocksy: error starting server:\n\t%s", err.Error())
}
http.HandleFunc("/", mocksyHandler)
http.ListenAndServe(port, nil)
return nil
}
// mocksyHandler is the HTTP handler of the Mocksy server
func mocksyHandler(rw http.ResponseWriter, req *http.Request) {
resp := FindMatching(req)
//if err != nil {
//rw.WriteHeader(http.StatusInternalServerError)
//log.Println(err)
//fmt.Fprintln(rw, "mocksy: internal server error :(")
//return
//}
rw.WriteHeader(http.StatusOK)
fmt.Fprintln(rw, string(resp.Value))
}