package data import ( "bytes" "errors" "fmt" "io/ioutil" "net/http" "strings" "text/template" "git.bullercodeworks.com/brian/netcaptain/internal/cli" "git.bullercodeworks.com/brian/netcaptain/internal/web" ) type Quest struct { Name string Dir string Verbose bool Headers map[string]string Method string Url string Body string Raw string Processed string Args map[string]string loaded bool } func NewQuest(dir, nm string) *Quest { return &Quest{ Name: nm, Dir: dir, Headers: make(map[string]string), Args: make(map[string]string), } } func (q *Quest) Load() error { if !cli.FileExists(q.FilePath()) { return errors.New("File Not Found") } data, err := ioutil.ReadFile(q.FilePath()) if err != nil { return err } q.Raw = string(data) t, err := template.New(q.Name).Parse(q.Raw) if err != nil { return errors.New(fmt.Sprintf("Error parsing Quest as template: %s", err.Error())) } var tpl bytes.Buffer err = t.Execute(&tpl, q) if err != nil { return errors.New(fmt.Sprintf("Error executing Quest template: %s\n->%s", q.Name, err.Error())) } q.Processed = tpl.String() q.loaded = true return nil } func (q *Quest) LoadArgs(parms []string) { for k, v := range parms { q.Args[fmt.Sprintf("Arg%d", k)] = v } } func (q *Quest) FilePath() string { return fmt.Sprintf("%s/quests/%s", q.Dir, q.Name) } func (q *Quest) IsValid() bool { return q.loaded } func (q *Quest) request() *http.Request { headers := make(map[string][]string) var method, url, body string for _, v := range strings.Split(q.Processed, "\n") { flds := strings.Fields(v) if len(flds) > 0 { if web.IsHttpMethod(flds[0]) { // This is the request line method = flds[0] url = flds[1] } else if method == "" && len(flds) > 1 { // Headers k := strings.TrimSuffix(flds[0], ":") v := strings.Join(flds[1:], " ") headers[k] = append(headers[k], v) } else { // Body if body != "" { body = body + "\n" } body = body + v } } } request, _ := http.NewRequest(method, url, bytes.NewBuffer([]byte(body))) for k, v := range headers { request.Header[k] = v } return request } func (q *Quest) Completer() (*http.Response, error) { client := &http.Client{} return client.Do(q.request()) } func (q *Quest) Complete() int { resp, _ := q.Completer() if q.Verbose { for k, v := range resp.Header { fmt.Println(k, v) } } defer resp.Body.Close() rbody, err := ioutil.ReadAll(resp.Body) if err != nil { cli.PrintErr(err.Error()) return 1 } fmt.Println(string(rbody)) return 0 }