fix: build url, handle request params

This commit is contained in:
lilong.129
2023-07-23 13:49:56 +08:00
parent 192b8b6c3c
commit 46639cae18
3 changed files with 62 additions and 85 deletions
+15 -5
View File
@@ -28,24 +28,34 @@ type Parser struct {
plugin funplugin.IPlugin // plugin is used to call functions plugin funplugin.IPlugin // plugin is used to call functions
} }
func buildURL(baseURL, stepURL string) (fullUrl string) { func buildURL(baseURL, stepURL string, queryParams url.Values) (fullUrl *url.URL) {
uStep, err := url.Parse(stepURL) uStep, err := url.Parse(stepURL)
if err != nil { if err != nil {
log.Error().Str("stepURL", stepURL).Err(err).Msg("[buildURL] parse url failed") log.Error().Str("stepURL", stepURL).Err(err).Msg("[buildURL] parse url failed")
return stepURL return nil
} }
defer func() { defer func() {
// append query params
if paramStr := queryParams.Encode(); paramStr != "" {
if uStep.RawQuery == "" {
uStep.RawQuery = paramStr
} else {
uStep.RawQuery = uStep.RawQuery + "&" + paramStr
}
}
// ensure path suffix '/' exists // ensure path suffix '/' exists
if uStep.RawQuery == "" { if uStep.RawQuery == "" {
uStep.Path = strings.TrimRight(uStep.Path, "/") + "/" uStep.Path = strings.TrimRight(uStep.Path, "/") + "/"
} }
fullUrl = uStep.String()
fullUrl = uStep
}() }()
// step url is absolute url // step url is absolute url
if uStep.Host != "" { if uStep.Host != "" {
return return uStep
} }
// step url is relative, based on base url // step url is relative, based on base url
@@ -59,7 +69,7 @@ func buildURL(baseURL, stepURL string) (fullUrl string) {
uStep.Scheme = uConfig.Scheme uStep.Scheme = uConfig.Scheme
uStep.Host = uConfig.Host uStep.Host = uConfig.Host
uStep.Path = path.Join(uConfig.Path, uStep.Path) uStep.Path = path.Join(uConfig.Path, uStep.Path)
return return uStep
} }
func (p *Parser) ParseHeaders(rawHeaders map[string]string, variablesMapping map[string]interface{}) (map[string]string, error) { func (p *Parser) ParseHeaders(rawHeaders map[string]string, variablesMapping map[string]interface{}) (map[string]string, error) {
+36 -23
View File
@@ -1,6 +1,7 @@
package hrp package hrp
import ( import (
"net/url"
"sort" "sort"
"testing" "testing"
"time" "time"
@@ -9,60 +10,72 @@ import (
) )
func TestBuildURL(t *testing.T) { func TestBuildURL(t *testing.T) {
var url string var preparedURL *url.URL
url = buildURL("https://postman-echo.com", "/get") preparedURL = buildURL("https://postman-echo.com", "/get", nil)
if !assert.Equal(t, url, "https://postman-echo.com/get/") { if !assert.Equal(t, preparedURL.String(), "https://postman-echo.com/get/") {
t.Fatal() t.Fatal()
} }
url = buildURL("https://postman-echo.com", "get") preparedURL = buildURL("https://postman-echo.com", "get", nil)
if !assert.Equal(t, url, "https://postman-echo.com/get/") { if !assert.Equal(t, preparedURL.String(), "https://postman-echo.com/get/") {
t.Fatal() t.Fatal()
} }
url = buildURL("https://postman-echo.com/", "/get") preparedURL = buildURL("https://postman-echo.com/", "/get", nil)
if !assert.Equal(t, url, "https://postman-echo.com/get/") { if !assert.Equal(t, preparedURL.String(), "https://postman-echo.com/get/") {
t.Fatal() t.Fatal()
} }
url = buildURL("https://postman-echo.com/abc/", "/get?a=1&b=2") preparedURL = buildURL("https://postman-echo.com/abc/", "/get?a=1&b=2", nil)
if !assert.Equal(t, url, "https://postman-echo.com/abc/get?a=1&b=2") { if !assert.Equal(t, preparedURL.String(), "https://postman-echo.com/abc/get?a=1&b=2") {
t.Fatal() t.Fatal()
} }
url = buildURL("https://postman-echo.com/abc", "get?a=1&b=2") preparedURL = buildURL("https://postman-echo.com/abc", "get?a=1&b=2", nil)
if !assert.Equal(t, url, "https://postman-echo.com/abc/get?a=1&b=2") { if !assert.Equal(t, preparedURL.String(), "https://postman-echo.com/abc/get?a=1&b=2") {
t.Fatal() t.Fatal()
} }
// omit query string in base url // omit query string in base url
url = buildURL("https://postman-echo.com/abc?x=6&y=9", "/get?a=1&b=2") preparedURL = buildURL("https://postman-echo.com/abc?x=6&y=9", "/get?a=1&b=2", nil)
if !assert.Equal(t, url, "https://postman-echo.com/abc/get?a=1&b=2") { if !assert.Equal(t, preparedURL.String(), "https://postman-echo.com/abc/get?a=1&b=2") {
t.Fatal() t.Fatal()
} }
url = buildURL("", "https://postman-echo.com/get") preparedURL = buildURL("", "https://postman-echo.com/get", nil)
if !assert.Equal(t, url, "https://postman-echo.com/get/") { if !assert.Equal(t, preparedURL.String(), "https://postman-echo.com/get/") {
t.Fatal() t.Fatal()
} }
// notice: step request url > config base url // notice: step request url > config base url
url = buildURL("https://postman-echo.com", "https://httpbin.org/get") preparedURL = buildURL("https://postman-echo.com", "https://httpbin.org/get", nil)
if !assert.Equal(t, url, "https://httpbin.org/get/") { if !assert.Equal(t, preparedURL.String(), "https://httpbin.org/get/") {
t.Fatal() t.Fatal()
} }
// websocket url // websocket url
url = buildURL("wss://ws.postman-echo.com/raw", "") preparedURL = buildURL("wss://ws.postman-echo.com/raw", "", nil)
if !assert.Equal(t, url, "wss://ws.postman-echo.com/raw/") { if !assert.Equal(t, preparedURL.String(), "wss://ws.postman-echo.com/raw/") {
t.Fatal() t.Fatal()
} }
url = buildURL("wss://ws.postman-echo.com", "/raw") preparedURL = buildURL("wss://ws.postman-echo.com", "/raw", nil)
if !assert.Equal(t, url, "wss://ws.postman-echo.com/raw/") { if !assert.Equal(t, preparedURL.String(), "wss://ws.postman-echo.com/raw/") {
t.Fatal() t.Fatal()
} }
url = buildURL("wss://ws.postman-echo.com/raw", "ws://echo.websocket.events") preparedURL = buildURL("wss://ws.postman-echo.com/raw", "ws://echo.websocket.events", nil)
if !assert.Equal(t, url, "ws://echo.websocket.events/") { if !assert.Equal(t, preparedURL.String(), "ws://echo.websocket.events/") {
t.Fatal()
}
queryParams := url.Values{}
queryParams.Add("c", "3")
queryParams.Add("d", "4")
preparedURL = buildURL("https://postman-echo.com/", "/get/", queryParams)
if !assert.Equal(t, preparedURL.String(), "https://postman-echo.com/get?c=3&d=4") {
t.Fatal()
}
preparedURL = buildURL("https://postman-echo.com/abc", "get?a=1&b=2", queryParams)
if !assert.Equal(t, preparedURL.String(), "https://postman-echo.com/abc/get?a=1&b=2&c=3&d=4") {
t.Fatal() t.Fatal()
} }
} }
+11 -57
View File
@@ -149,9 +149,8 @@ func (r *requestBuilder) prepareUrlParams(stepVariables map[string]interface{})
} }
var baseURL string var baseURL string
if stepVariables["base_url"] != nil { if stepVariables["base_url"] != nil {
baseURL = stepVariables["base_url"].(string) baseURL, _ = stepVariables["base_url"].(string)
} }
rawUrl := buildURL(baseURL, convertString(requestUrl))
// prepare request params // prepare request params
var queryParams url.Values var queryParams url.Values
@@ -161,35 +160,24 @@ func (r *requestBuilder) prepareUrlParams(stepVariables map[string]interface{})
return errors.Wrap(err, "parse request params failed") return errors.Wrap(err, "parse request params failed")
} }
parsedParams := params.(map[string]interface{}) parsedParams := params.(map[string]interface{})
r.requestMap["params"] = parsedParams
if len(parsedParams) > 0 { if len(parsedParams) > 0 {
queryParams = make(url.Values) queryParams = make(url.Values)
for k, v := range parsedParams { for k, v := range parsedParams {
queryParams.Add(k, convertString(v)) queryParams.Add(k, convertString(v))
} }
} }
}
if queryParams != nil { // request params has been appended to url, thus delete it here
// append params to url delete(r.requestMap, "params")
paramStr := queryParams.Encode()
if strings.IndexByte(rawUrl, '?') == -1 {
rawUrl = strings.TrimRight(rawUrl, "/") + "?" + paramStr
} else {
rawUrl = rawUrl + "&" + paramStr
}
} }
// prepare url // prepare url
u, err := url.Parse(rawUrl) preparedURL := buildURL(baseURL, convertString(requestUrl), queryParams)
if err != nil { r.req.URL = preparedURL
return errors.Wrap(err, "parse url failed") r.req.Host = preparedURL.Host
}
r.req.URL = u
r.req.Host = u.Host
// update url // update url
r.requestMap["url"] = u.String() r.requestMap["url"] = preparedURL.String()
return nil return nil
} }
@@ -340,43 +328,14 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
// add request object to step variables, could be used in setup hooks // add request object to step variables, could be used in setup hooks
stepVariables["hrp_step_name"] = step.Name stepVariables["hrp_step_name"] = step.Name
stepVariables["hrp_step_request"] = rb.requestMap stepVariables["hrp_step_request"] = rb.requestMap
stepVariables["request"] = rb.requestMap stepVariables["request"] = rb.requestMap // setup hooks compatible with v3
// deal with setup hooks // deal with setup hooks
for _, setupHook := range step.SetupHooks { for _, setupHook := range step.SetupHooks {
req, err := parser.Parse(setupHook, stepVariables) _, err := parser.Parse(setupHook, stepVariables)
if err != nil { if err != nil {
return stepResult, errors.Wrap(err, "run setup hooks failed") return stepResult, errors.Wrap(err, "run setup hooks failed")
} }
reqMap, ok := req.(map[string]interface{})
if ok && reqMap != nil {
rb.requestMap = reqMap
stepVariables["request"] = reqMap
}
}
if len(step.SetupHooks) > 0 {
requestBody, ok := rb.requestMap["body"].(map[string]interface{})
if ok {
body, err := json.Marshal(requestBody)
if err == nil {
rb.req.Body = io.NopCloser(bytes.NewReader(body))
rb.req.ContentLength = int64(len(body))
}
}
requestParams, ok := rb.requestMap["params"].(map[string]interface{})
if ok {
params, err := json.Marshal(requestParams)
if err == nil {
rb.req.URL.RawQuery = string(params)
}
}
requestHeaders, ok := rb.requestMap["headers"].(map[string]interface{})
if ok {
rb.req.Header = http.Header{}
for k, v := range requestHeaders {
rb.req.Header.Set(k, v.(string))
}
}
} }
// log & print request // log & print request
@@ -451,15 +410,10 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
// deal with teardown hooks // deal with teardown hooks
for _, teardownHook := range step.TeardownHooks { for _, teardownHook := range step.TeardownHooks {
res, err := parser.Parse(teardownHook, stepVariables) _, err := parser.Parse(teardownHook, stepVariables)
if err != nil { if err != nil {
return stepResult, errors.Wrap(err, "run teardown hooks failed") return stepResult, errors.Wrap(err, "run teardown hooks failed")
} }
resMpa, ok := res.(map[string]interface{})
if ok {
stepVariables["response"] = resMpa
respObj.respObjMeta = resMpa
}
} }
sessionData.ReqResps.Request = rb.requestMap sessionData.ReqResps.Request = rb.requestMap