Merge pull request #74 from zbb93/master

#65 - Save Requests
This commit is contained in:
Adam Tauber 2017-03-13 10:35:54 +01:00 committed by GitHub
commit 0e747e8c35
3 changed files with 156 additions and 67 deletions

View File

@ -1,7 +1,9 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"io/ioutil"
"strings" "strings"
"unicode" "unicode"
@ -14,8 +16,66 @@ var COMMANDS map[string]func(string, *App) CommandFunc = map[string]func(string,
"submit": func(_ string, a *App) CommandFunc { "submit": func(_ string, a *App) CommandFunc {
return a.SubmitRequest return a.SubmitRequest
}, },
"save": func(_ string, a *App) CommandFunc { "saveResponse": func(_ string, a *App) CommandFunc {
return a.OpenSaveDialog return func(g *gocui.Gui, _ *gocui.View) error {
return a.OpenSaveDialog(VIEW_TITLES[SAVE_RESPONSE_DIALOG_VIEW], g,
func(g *gocui.Gui, _ *gocui.View) error {
saveLocation := getViewValue(g, SAVE_DIALOG_VIEW)
if len(a.history) == 0 {
return nil
}
req := a.history[a.historyIndex]
if req.RawResponseBody == nil {
return nil
}
err := ioutil.WriteFile(saveLocation, req.RawResponseBody, 0644)
var saveResult string
if err == nil {
saveResult = "Response saved successfully."
} else {
saveResult = "Error saving response: " + err.Error()
}
viewErr := a.OpenSaveResultView(saveResult, g)
return viewErr
})
}
},
"saveRequest": func(_ string, a *App) CommandFunc {
return func(g *gocui.Gui, _ *gocui.View) error {
return a.OpenSaveDialog(VIEW_TITLES[SAVE_REQUEST_DIALOG_VIEW], g,
func(g *gocui.Gui, _ *gocui.View) error {
defer a.closePopup(g, SAVE_DIALOG_VIEW)
saveLocation := getViewValue(g, SAVE_DIALOG_VIEW)
var requestMap map[string]string
requestMap = make(map[string]string)
requestMap[URL_VIEW] = getViewValue(g, URL_VIEW)
requestMap[REQUEST_METHOD_VIEW] = getViewValue(g, REQUEST_METHOD_VIEW)
requestMap[URL_PARAMS_VIEW] = getViewValue(g, URL_PARAMS_VIEW)
requestMap[REQUEST_DATA_VIEW] = getViewValue(g, REQUEST_DATA_VIEW)
requestMap[REQUEST_HEADERS_VIEW] = getViewValue(g, REQUEST_HEADERS_VIEW)
requestJson, err := json.Marshal(requestMap)
if err != nil {
return err
}
ioerr := ioutil.WriteFile(saveLocation, []byte(requestJson), 0644)
var saveResult string
if ioerr == nil {
saveResult = "Request saved successfully."
} else {
saveResult = "Error saving request: " + err.Error()
}
viewErr := a.OpenSaveResultView(saveResult, g)
return viewErr
})
}
}, },
"history": func(_ string, a *App) CommandFunc { "history": func(_ string, a *App) CommandFunc {
return a.ToggleHistory return a.ToggleHistory

View File

@ -51,7 +51,8 @@ var DefaultKeys = map[string]map[string]string{
"global": map[string]string{ "global": map[string]string{
"CtrlR": "submit", "CtrlR": "submit",
"CtrlC": "quit", "CtrlC": "quit",
"CtrlS": "save", "CtrlS": "saveResponse",
"CtrlE": "saveRequest",
"CtrlD": "deleteLine", "CtrlD": "deleteLine",
"CtrlW": "deleteWord", "CtrlW": "deleteWord",
"Tab": "nextView", "Tab": "nextView",

156
wuzz.go
View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"crypto/tls" "crypto/tls"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -47,24 +48,28 @@ const (
RESPONSE_HEADERS_VIEW = "response-headers" RESPONSE_HEADERS_VIEW = "response-headers"
RESPONSE_BODY_VIEW = "response-body" RESPONSE_BODY_VIEW = "response-body"
SEARCH_PROMPT_VIEW = "prompt" SEARCH_PROMPT_VIEW = "prompt"
POPUP_VIEW = "popup_view" POPUP_VIEW = "popup_view"
AUTOCOMPLETE_VIEW = "autocomplete_view" AUTOCOMPLETE_VIEW = "autocomplete_view"
ERROR_VIEW = "error_view" ERROR_VIEW = "error_view"
HISTORY_VIEW = "history" HISTORY_VIEW = "history"
SAVE_DIALOG_VIEW = "save-dialog" SAVE_DIALOG_VIEW = "save-dialog"
SAVE_RESULT_VIEW = "save-result" SAVE_RESPONSE_DIALOG_VIEW = "save-response-dialog"
METHOD_LIST_VIEW = "method-list" SAVE_REQUEST_DIALOG_VIEW = "save-request-dialog"
HELP_VIEW = "help" SAVE_RESULT_VIEW = "save-result"
METHOD_LIST_VIEW = "method-list"
HELP_VIEW = "help"
) )
var VIEW_TITLES = map[string]string{ var VIEW_TITLES = map[string]string{
POPUP_VIEW: "Info", POPUP_VIEW: "Info",
ERROR_VIEW: "Error", ERROR_VIEW: "Error",
HISTORY_VIEW: "History", HISTORY_VIEW: "History",
SAVE_DIALOG_VIEW: "Save Response (enter to submit, ctrl+q to cancel)", SAVE_RESPONSE_DIALOG_VIEW: "Save Response (enter to submit, ctrl+q to cancel)",
METHOD_LIST_VIEW: "Methods", SAVE_REQUEST_DIALOG_VIEW: "Save Request (enter to submit, ctrl+q to cancel)",
HELP_VIEW: "Help", SAVE_RESULT_VIEW: "Save Result (press enter to close)",
METHOD_LIST_VIEW: "Methods",
HELP_VIEW: "Help",
} }
type position struct { type position struct {
@ -1055,50 +1060,6 @@ func (a *App) SetKeys(g *gocui.Gui) error {
return nil return nil
}) })
g.SetKeybinding(SAVE_DIALOG_VIEW, gocui.KeyEnter, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error {
defer a.closePopup(g, SAVE_DIALOG_VIEW)
saveLocation := getViewValue(g, SAVE_DIALOG_VIEW)
if len(a.history) == 0 {
return nil
}
req := a.history[a.historyIndex]
if req.RawResponseBody == nil {
return nil
}
err := ioutil.WriteFile(saveLocation, req.RawResponseBody, 0644)
var saveResult string
if err == nil {
saveResult = "Response saved successfully."
} else {
saveResult = "Error saving response: " + err.Error()
}
popupTitle := "Save Result (press enter to close)"
saveResHeight := 1
saveResWidth := len(saveResult) + 1
if len(popupTitle)+2 > saveResWidth {
saveResWidth = len(popupTitle) + 2
}
maxX, _ := g.Size()
if saveResWidth > maxX {
saveResHeight = saveResWidth/maxX + 1
saveResWidth = maxX
}
saveResultPopup, err := a.CreatePopupView(SAVE_RESULT_VIEW, saveResWidth, saveResHeight, g)
saveResultPopup.Title = popupTitle
setViewTextAndCursor(saveResultPopup, saveResult)
g.SetViewOnTop(SAVE_RESULT_VIEW)
g.SetCurrentView(SAVE_RESULT_VIEW)
return err
})
g.SetKeybinding(SAVE_DIALOG_VIEW, gocui.KeyCtrlQ, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { g.SetKeybinding(SAVE_DIALOG_VIEW, gocui.KeyCtrlQ, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error {
a.closePopup(g, SAVE_DIALOG_VIEW) a.closePopup(g, SAVE_DIALOG_VIEW)
return nil return nil
@ -1211,15 +1172,14 @@ func (a *App) ToggleMethodList(g *gocui.Gui, _ *gocui.View) (err error) {
return return
} }
func (a *App) OpenSaveDialog(g *gocui.Gui, _ *gocui.View) (err error) { func (a *App) OpenSaveDialog(title string, g *gocui.Gui, save func(g *gocui.Gui, v *gocui.View) error) error {
dialog, err := a.CreatePopupView(SAVE_DIALOG_VIEW, 60, 1, g) dialog, err := a.CreatePopupView(SAVE_DIALOG_VIEW, 60, 1, g)
if err != nil { if err != nil {
return return err
} }
g.Cursor = true g.Cursor = true
dialog.Title = VIEW_TITLES[SAVE_DIALOG_VIEW] dialog.Title = title
dialog.Editable = true dialog.Editable = true
dialog.Wrap = false dialog.Wrap = false
@ -1234,7 +1194,30 @@ func (a *App) OpenSaveDialog(g *gocui.Gui, _ *gocui.View) (err error) {
g.SetViewOnTop(SAVE_DIALOG_VIEW) g.SetViewOnTop(SAVE_DIALOG_VIEW)
g.SetCurrentView(SAVE_DIALOG_VIEW) g.SetCurrentView(SAVE_DIALOG_VIEW)
dialog.SetCursor(0, len(currentDir)) dialog.SetCursor(0, len(currentDir))
return g.DeleteKeybinding(SAVE_DIALOG_VIEW, gocui.KeyEnter, gocui.ModNone)
g.SetKeybinding(SAVE_DIALOG_VIEW, gocui.KeyEnter, gocui.ModNone, save)
return nil
}
func (a *App) OpenSaveResultView(saveResult string, g *gocui.Gui) (err error) {
popupTitle := VIEW_TITLES[SAVE_RESULT_VIEW]
saveResHeight := 1
saveResWidth := len(saveResult) + 1
if len(popupTitle)+2 > saveResWidth {
saveResWidth = len(popupTitle) + 2
}
maxX, _ := g.Size()
if saveResWidth > maxX {
saveResHeight = saveResWidth/maxX + 1
saveResWidth = maxX
}
saveResultPopup, err := a.CreatePopupView(SAVE_RESULT_VIEW, saveResWidth, saveResHeight, g)
saveResultPopup.Title = popupTitle
setViewTextAndCursor(saveResultPopup, saveResult)
g.SetViewOnTop(SAVE_RESULT_VIEW)
g.SetCurrentView(SAVE_RESULT_VIEW)
return err
} }
func (a *App) restoreRequest(g *gocui.Gui, idx int) { func (a *App) restoreRequest(g *gocui.Gui, idx int) {
@ -1440,6 +1423,51 @@ func (a *App) ParseArgs(g *gocui.Gui, args []string) error {
default: default:
return errors.New("Unknown proxy protocol") return errors.New("Unknown proxy protocol")
} }
case "-f", "--file":
if arg_index == args_len-1 {
return errors.New("-f or --file requires a file path be provided as an argument")
}
arg_index += 1
requestJson, ioErr := ioutil.ReadFile(args[arg_index])
if ioErr != nil {
return ioErr
}
var requestMap map[string]string
jsonErr := json.Unmarshal(requestJson, &requestMap)
if jsonErr != nil {
return jsonErr
}
var v *gocui.View
url, exists := requestMap[URL_VIEW]
if exists {
v, _ = g.View(URL_VIEW)
setViewTextAndCursor(v, url)
}
method, exists := requestMap[REQUEST_METHOD_VIEW]
if exists {
v, _ = g.View(REQUEST_METHOD_VIEW)
setViewTextAndCursor(v, method)
}
params, exists := requestMap[URL_PARAMS_VIEW]
if exists {
v, _ = g.View(URL_PARAMS_VIEW)
setViewTextAndCursor(v, params)
}
data, exists := requestMap[REQUEST_DATA_VIEW]
if exists {
v, _ = g.View(REQUEST_DATA_VIEW)
setViewTextAndCursor(v, data)
}
headers, exists := requestMap[REQUEST_HEADERS_VIEW]
if exists {
v, _ = g.View(REQUEST_HEADERS_VIEW)
setViewTextAndCursor(v, headers)
}
default: default:
u := args[arg_index] u := args[arg_index]
if strings.Index(u, "http://") != 0 && strings.Index(u, "https://") != 0 { if strings.Index(u, "http://") != 0 && strings.Index(u, "https://") != 0 {