mirror of
https://github.com/httprunner/httprunner.git
synced 2026-06-08 01:09:44 +08:00
fix: http server and grpc with cert
This commit is contained in:
@@ -20,4 +20,4 @@ if __name__ == "__main__":
|
|||||||
funppy.register("concatenate", concatenate)
|
funppy.register("concatenate", concatenate)
|
||||||
funppy.register("setup_hook_example", setup_hook_example)
|
funppy.register("setup_hook_example", setup_hook_example)
|
||||||
funppy.register("teardown_hook_example", teardown_hook_example)
|
funppy.register("teardown_hook_example", teardown_hook_example)
|
||||||
funppy.serve()
|
funppy.serve()
|
||||||
|
|||||||
@@ -15,30 +15,48 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Package data provides convenience routines to access files in the data
|
|
||||||
// directory.
|
|
||||||
package data
|
package data
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"embed"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
|
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// basepath is the root directory of this package.
|
// hrpPath is .hrp directory under the user directory.
|
||||||
var basepath string
|
var hrpPath string
|
||||||
|
|
||||||
|
//go:embed x509/*
|
||||||
|
var x509Dir embed.FS
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
_, currentFile, _, _ := runtime.Caller(0)
|
home, err := os.UserHomeDir()
|
||||||
basepath = filepath.Dir(currentFile)
|
if err != nil {
|
||||||
}
|
return
|
||||||
|
|
||||||
// Path returns the absolute path the given relative file or directory path,
|
|
||||||
// relative to the google.golang.org/grpc/examples/data directory in the
|
|
||||||
// user's GOPATH. If rel is already absolute, it is returned unmodified.
|
|
||||||
func Path(rel string) string {
|
|
||||||
if filepath.IsAbs(rel) {
|
|
||||||
return rel
|
|
||||||
}
|
}
|
||||||
|
hrpPath = filepath.Join(home, ".hrp")
|
||||||
|
_ = builtin.EnsureFolderExists(filepath.Join(hrpPath, "x509"))
|
||||||
|
|
||||||
return filepath.Join(basepath, rel)
|
}
|
||||||
|
|
||||||
|
// Path returns the absolute path the given relative file or directory path
|
||||||
|
func Path(rel string) (destPath string) {
|
||||||
|
destPath = rel
|
||||||
|
if !filepath.IsAbs(rel) {
|
||||||
|
destPath = filepath.Join(hrpPath, rel)
|
||||||
|
}
|
||||||
|
if !builtin.IsFilePathExists(destPath) {
|
||||||
|
content, err := x509Dir.ReadFile(rel)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(destPath, content, 0o644)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
183
hrp/server.go
183
hrp/server.go
@@ -2,6 +2,7 @@ package hrp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
@@ -52,17 +53,13 @@ func parseBody(r *http.Request) (data map[string]interface{}, err error) {
|
|||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeResponse(w http.ResponseWriter, status int, contentType string, body []byte) {
|
func writeJSON(w http.ResponseWriter, body []byte, status int) {
|
||||||
w.Header().Set("Content-Type", contentType)
|
w.Header().Set("Content-Type", jsonContentType)
|
||||||
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(body)))
|
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(body)))
|
||||||
w.WriteHeader(status)
|
w.WriteHeader(status)
|
||||||
w.Write(body)
|
w.Write(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeJSON(w http.ResponseWriter, body []byte, status int) {
|
|
||||||
writeResponse(w, status, jsonContentType, body)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServerCode int
|
type ServerCode int
|
||||||
|
|
||||||
// server response code
|
// server response code
|
||||||
@@ -169,48 +166,100 @@ func (api *apiHandler) Index(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func (api *apiHandler) Start(w http.ResponseWriter, r *http.Request) {
|
func (api *apiHandler) Start(w http.ResponseWriter, r *http.Request) {
|
||||||
var resp *CommonResponseBody
|
var resp *CommonResponseBody
|
||||||
data, err := parseBody(r)
|
var err error
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
resp = &CommonResponseBody{
|
||||||
|
ServerStatus: EnumAPIResponseServerError(err.Error()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resp = &CommonResponseBody{
|
||||||
|
ServerStatus: EnumAPIResponseSuccess,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body, _ := json.Marshal(resp)
|
||||||
|
writeJSON(w, body, http.StatusOK)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// parse body
|
||||||
|
data, err := parseBody(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
req := StartRequestBody{
|
req := StartRequestBody{
|
||||||
Profile: *api.boomer.GetProfile(),
|
Profile: *api.boomer.GetProfile(),
|
||||||
}
|
}
|
||||||
err = mapstructure.Decode(data, &req)
|
err = mapstructure.Decode(data, &req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// recognize invalid parameters
|
||||||
if len(req.Other) > 0 {
|
if len(req.Other) > 0 {
|
||||||
keys := make([]string, 0, len(req.Other))
|
keys := make([]string, 0, len(req.Other))
|
||||||
for k := range req.Other {
|
for k := range req.Other {
|
||||||
keys = append(keys, k)
|
keys = append(keys, k)
|
||||||
}
|
}
|
||||||
resp = &CommonResponseBody{
|
err = errors.New(fmt.Sprintf("failed to recognize params: %v", keys))
|
||||||
ServerStatus: EnumAPIResponseParamError(fmt.Sprintf("failed to recognize params: %v", keys)),
|
|
||||||
}
|
|
||||||
body, _ := json.Marshal(resp)
|
|
||||||
writeJSON(w, body, http.StatusOK)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse testcase path
|
||||||
if req.TestCasePath == "" {
|
if req.TestCasePath == "" {
|
||||||
resp = &CommonResponseBody{
|
err = errors.New("missing testcases path")
|
||||||
ServerStatus: EnumAPIResponseParamError(fmt.Sprint("missing testcases path")),
|
|
||||||
}
|
|
||||||
body, _ := json.Marshal(resp)
|
|
||||||
writeJSON(w, body, http.StatusOK)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
paths := strings.Split(req.TestCasePath, ",")
|
paths := strings.Split(req.TestCasePath, ",")
|
||||||
|
|
||||||
|
// set testcase path
|
||||||
api.boomer.SetTestCasesPath(paths)
|
api.boomer.SetTestCasesPath(paths)
|
||||||
if err == nil {
|
|
||||||
err = api.boomer.Start(&req.Profile)
|
// start boomer with profile
|
||||||
}
|
err = api.boomer.Start(&req.Profile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *apiHandler) ReBalance(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var resp *CommonResponseBody
|
||||||
|
var err error
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
resp = &CommonResponseBody{
|
||||||
|
ServerStatus: EnumAPIResponseServerError(err.Error()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resp = &CommonResponseBody{
|
||||||
|
ServerStatus: EnumAPIResponseSuccess,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body, _ := json.Marshal(resp)
|
||||||
|
writeJSON(w, body, http.StatusOK)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// parse body
|
||||||
|
data, err := parseBody(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp = &CommonResponseBody{
|
return
|
||||||
ServerStatus: EnumAPIResponseServerError(err.Error()),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resp = &CommonResponseBody{
|
|
||||||
ServerStatus: EnumAPIResponseSuccess,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
body, _ := json.Marshal(resp)
|
req := RebalanceRequestBody{
|
||||||
writeJSON(w, body, http.StatusOK)
|
Profile: *api.boomer.GetProfile(),
|
||||||
|
}
|
||||||
|
err = mapstructure.Decode(data, &req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// recognize invalid parameters
|
||||||
|
if len(req.Other) > 0 {
|
||||||
|
keys := make([]string, 0, len(req.Other))
|
||||||
|
for k := range req.Other {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
err = errors.New(fmt.Sprintf("failed to recognize params: %v", keys))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// rebalance boomer with profile
|
||||||
|
err = api.boomer.ReBalance(&req.Profile)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *apiHandler) Stop(w http.ResponseWriter, r *http.Request) {
|
func (api *apiHandler) Stop(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -223,18 +272,23 @@ func (api *apiHandler) Stop(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var resp *CommonResponseBody
|
var resp *CommonResponseBody
|
||||||
err := api.boomer.Stop()
|
var err error
|
||||||
if err != nil {
|
defer func() {
|
||||||
resp = &CommonResponseBody{
|
if err != nil {
|
||||||
ServerStatus: EnumAPIResponseStopError(err.Error()),
|
resp = &CommonResponseBody{
|
||||||
|
ServerStatus: EnumAPIResponseStopError(err.Error()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resp = &CommonResponseBody{
|
||||||
|
ServerStatus: EnumAPIResponseSuccess,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
body, _ := json.Marshal(resp)
|
||||||
resp = &CommonResponseBody{
|
writeJSON(w, body, http.StatusOK)
|
||||||
ServerStatus: EnumAPIResponseSuccess,
|
}()
|
||||||
}
|
|
||||||
}
|
// stop boomer
|
||||||
body, _ := json.Marshal(resp)
|
err = api.boomer.Stop()
|
||||||
writeJSON(w, body, http.StatusOK)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *apiHandler) Quit(w http.ResponseWriter, r *http.Request) {
|
func (api *apiHandler) Quit(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -245,49 +299,16 @@ func (api *apiHandler) Quit(w http.ResponseWriter, r *http.Request) {
|
|||||||
data[k] = v
|
data[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
resp := &CommonResponseBody{
|
resp := &CommonResponseBody{
|
||||||
ServerStatus: EnumAPIResponseSuccess,
|
ServerStatus: EnumAPIResponseSuccess,
|
||||||
}
|
|
||||||
body, _ := json.Marshal(resp)
|
|
||||||
writeJSON(w, body, http.StatusOK)
|
|
||||||
api.boomer.Quit()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *apiHandler) ReBalance(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var resp *CommonResponseBody
|
|
||||||
data, err := parseBody(r)
|
|
||||||
|
|
||||||
req := RebalanceRequestBody{
|
|
||||||
Profile: *api.boomer.GetProfile(),
|
|
||||||
}
|
|
||||||
err = mapstructure.Decode(data, &req)
|
|
||||||
if len(req.Other) > 0 {
|
|
||||||
keys := make([]string, 0, len(req.Other))
|
|
||||||
for k := range req.Other {
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
resp = &CommonResponseBody{
|
|
||||||
ServerStatus: EnumAPIResponseParamError(fmt.Sprintf("failed to recognize params: %v", keys)),
|
|
||||||
}
|
}
|
||||||
body, _ := json.Marshal(resp)
|
body, _ := json.Marshal(resp)
|
||||||
writeJSON(w, body, http.StatusOK)
|
writeJSON(w, body, http.StatusOK)
|
||||||
return
|
}()
|
||||||
}
|
|
||||||
if err == nil {
|
// quit boomer
|
||||||
err = api.boomer.ReBalance(&req.Profile)
|
api.boomer.Quit()
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
resp = &CommonResponseBody{
|
|
||||||
ServerStatus: EnumAPIResponseParamError(err.Error()),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resp = &CommonResponseBody{
|
|
||||||
ServerStatus: EnumAPIResponseSuccess,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
body, _ := json.Marshal(resp)
|
|
||||||
writeJSON(w, body, http.StatusOK)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *apiHandler) GetWorkersInfo(w http.ResponseWriter, r *http.Request) {
|
func (api *apiHandler) GetWorkersInfo(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -305,9 +326,9 @@ func (api *apiHandler) Handler() http.Handler {
|
|||||||
|
|
||||||
mux.HandleFunc("/", methods(api.Index, "GET"))
|
mux.HandleFunc("/", methods(api.Index, "GET"))
|
||||||
mux.HandleFunc("/start", methods(api.Start, "POST"))
|
mux.HandleFunc("/start", methods(api.Start, "POST"))
|
||||||
|
mux.HandleFunc("/rebalance", methods(api.ReBalance, "POST"))
|
||||||
mux.HandleFunc("/stop", methods(api.Stop, "GET"))
|
mux.HandleFunc("/stop", methods(api.Stop, "GET"))
|
||||||
mux.HandleFunc("/quit", methods(api.Quit, "GET"))
|
mux.HandleFunc("/quit", methods(api.Quit, "GET"))
|
||||||
mux.HandleFunc("/rebalance", methods(api.ReBalance, "POST"))
|
|
||||||
mux.HandleFunc("/workers", methods(api.GetWorkersInfo, "GET"))
|
mux.HandleFunc("/workers", methods(api.GetWorkersInfo, "GET"))
|
||||||
|
|
||||||
return mux
|
return mux
|
||||||
|
|||||||
Reference in New Issue
Block a user