Skip to content

Commit

Permalink
Merge pull request #5 from forrestjgq/flex-http
Browse files Browse the repository at this point in the history
Flex http service, allow gomark dock to external http server
  • Loading branch information
forrestjgq authored Dec 1, 2020
2 parents 74b8214 + 9e0920b commit f979db4
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 62 deletions.
5 changes: 2 additions & 3 deletions cmd/main/gomark.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ func main() {
gm.EnableInternalVariables()

for i := 0; i < total; i++ {
go testStatus("testStatus", total)
go testAdderPerSecond("testAdderPerSecond", total)
go testStatus("testStatus_"+strconv.Itoa(i), math.MaxInt64)
go testAdderPerSecond("testAdderPerSecond_"+strconv.Itoa(i), math.MaxInt64)
go testMaxWindow("max_win_"+strconv.Itoa(i), math.MaxInt64)
go testMaxer("max_"+strconv.Itoa(i), math.MaxInt64)
go testAdder("adder_"+strconv.Itoa(i), math.MaxInt64)
Expand All @@ -214,7 +214,6 @@ func main() {
go testCounter("counter_"+strconv.Itoa(i), math.MaxInt64)
}

go testPecentile(total)
wg.Wait()
default:
glog.Info("unknown mode: ", mode)
Expand Down
74 changes: 74 additions & 0 deletions gmi/gmi.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,84 @@
// Package gmi defines Marker to represent each variable by interface.
package gmi

import "net/textproto"

// Marker is an interface to provide variable marking.
type Marker interface {
// Mark a number, the number definition is bound to marker itself.
Mark(n int32)
// Stop this marking.
Cancel()
}
type Route string

const (
RouteVars Route = "vars"
RouteDebug Route = "debug"
RouteJs Route = "js"
)

type Request struct {
Router Route
Params map[string]string
headers map[string]string
}

func (r *Request) GetParam(key string) string {
if r.Params == nil {
return ""
}
if v, ok := r.Params[key]; ok {
return v
}
return ""
}
func (r *Request) HasParam(key string) bool {
if r.Params == nil {
return false
}
_, ok := r.Params[key]
return ok
}
func (r *Request) GetHeader(key string) string {
if r.headers == nil {
return ""
}
if v, ok := r.headers[textproto.CanonicalMIMEHeaderKey(key)]; ok {
return v
}
return ""
}
func (r *Request) SetHeader(key, value string) {
if r.headers == nil {
r.headers = make(map[string]string)
}
r.headers[textproto.CanonicalMIMEHeaderKey(key)] = value
}

type Response struct {
Status int
headers map[string]string
Body []byte
}
func (r *Response) SetHeader(key, value string) {
if r.headers == nil {
r.headers = make(map[string]string)
}
r.headers[textproto.CanonicalMIMEHeaderKey(key)] = value
}
func (r *Response) GetHeaders() map[string]string {
if r.headers == nil {
r.headers = make(map[string]string)
}
return r.headers
}
func (r *Response) GetHeader(key string) string {
if r.headers == nil {
return ""
}
if v, ok := r.headers[textproto.CanonicalMIMEHeaderKey(key)]; ok {
return v
}
return ""
}
178 changes: 119 additions & 59 deletions internal/httpsrv/http_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"strings"
"text/template"

"github.com/forrestjgq/gomark/gmi"

"github.com/golang/glog"

"github.com/forrestjgq/gomark/internal/gm"
Expand Down Expand Up @@ -44,69 +46,84 @@ func Start(port int) {
}()
}

func procDebug(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
w.WriteHeader(400)
_, _ = w.Write([]byte(err.Error()))
return
func RequestHTTP(req *gmi.Request) *gmi.Response {
switch req.Router {
case gmi.RouteJs:
return serveJs(req)
case gmi.RouteDebug:
return serveDebug(req)
case gmi.RouteVars:
return serveVar(req)
default:
return &gmi.Response{
Status: 404,
}
}
}

p := r.Form.Get("perf")
func procDebug(w http.ResponseWriter, r *http.Request) {
proc(gmi.RouteDebug, w, r)
}
func serveDebug(req *gmi.Request) (rsp *gmi.Response) {
rsp = &gmi.Response{
Status: 200,
}
p := req.GetParam("perf")
if p == "1" {
gm.EnableInternalVariables()
_, _ = w.Write([]byte("internal variables enabled"))
rsp.Body = []byte("internal variables enabled")
} else if p == "0" {
gm.DisableInternalVariables()
_, _ = w.Write([]byte("internal variables disabled"))
rsp.Body = []byte("internal variables disabled")
} else {
rsp.Status = 404
}

return
}

var lastModified = "Wed, 16 Sep 2015 01:25:30 GMT"

func procJs(w http.ResponseWriter, r *http.Request) {
glog.Info("js")
vars := mux.Vars(r)
w.Header().Add("content-type", "application/javascript")
proc(gmi.RouteJs, w, r)
}
func serveJs(req *gmi.Request) (rsp *gmi.Response) {
rsp = &gmi.Response{
Status: 200,
Body: nil,
}

rsp.SetHeader("content-type", "application/javascript")

if v, ok := vars["script"]; ok {
m := r.Header.Get("If-Modified-Since")
if m == lastModified {
glog.Info("no modify")
w.WriteHeader(304)
if v, ok := req.Params["script"]; ok {
if req.GetHeader("If-Modified-Since") == lastModified {
rsp.Status = 304
return
}

w.Header().Add("Last-Modified", lastModified)
rsp.SetHeader("Last-Modified", lastModified)
if v == "jquery_min" {
_, _ = w.Write([]byte(jqueryMinJs))
rsp.Body = []byte(jqueryMinJs)
} else if v == "flot_min" {
_, _ = w.Write([]byte(flotMinJs))
rsp.Body = []byte(flotMinJs)
} else {
w.WriteHeader(404)
rsp.Status = 404
}
} else {
w.WriteHeader(404)
rsp.Status = 404
}
return
}

func useHtml(h *http.Header) bool {
if h == nil {
return true
}

v := h.Get("console")
func useHtml(req *gmi.Request) bool {
v := req.GetHeader("console")
if len(v) > 0 {
return v == "0"
}

v = h.Get("user-agent")
v = req.GetHeader("user-agent")
if len(v) == 0 {
return false
}

if strings.Index(v, "curl/") < 0 {
} else if strings.Index(v, "curl/") < 0 {
return true
}

Expand Down Expand Up @@ -159,12 +176,17 @@ func (d *dumpImpl) Dump(name, desc string) bool {
return true
}

func hasParam(key string, r *http.Request) bool {
_, exist := r.Form[key]
return exist
}
func procVar(w http.ResponseWriter, r *http.Request) {
proc(gmi.RouteVars, w, r)
}
func proc(route gmi.Route, w http.ResponseWriter, r *http.Request) {
req := &gmi.Request{
Params: make(map[string]string),
}
vars := mux.Vars(r)
for k, v := range vars {
req.Params[k] = v
}

err := r.ParseForm()
if err != nil {
Expand All @@ -173,35 +195,68 @@ func procVar(w http.ResponseWriter, r *http.Request) {
return
}

for k := range r.Form {
req.Params[k] = r.Form.Get(k)
}

for k := range r.Header {
req.SetHeader(k, r.Header.Get(k))
}

var rsp *gmi.Response
switch route {
case gmi.RouteVars:
rsp = serveVar(req)
case gmi.RouteDebug:
rsp = serveDebug(req)
case gmi.RouteJs:
rsp = serveJs(req)
default:
w.WriteHeader(404)
return
}
w.WriteHeader(rsp.Status)
for k, v := range rsp.GetHeaders() {
w.Header().Add(k, v)
}
if len(rsp.Body) > 0 {
_, _ = w.Write(rsp.Body)
}
}
func serveVar(req *gmi.Request) (rsp *gmi.Response) {
rsp = &gmi.Response{
Status: 200,
}

buf := &bytes.Buffer{}
if hasParam("series", r) {
ok := false
if req.HasParam("series") {
varName := ""
if varName, ok = vars["var"]; ok && len(varName) == 0 {
w.WriteHeader(400)
_, _ = w.Write([]byte("var name not present"))
if varName = req.GetParam("var"); len(varName) == 0 {
rsp.Status = 400
rsp.Body = []byte("var name not present")
return
}

opt := gm.SeriesOption{}
err = gm.DescribeVarSeries(varName, buf, opt)
err := gm.DescribeVarSeries(varName, buf, opt)
if err != nil {
w.WriteHeader(400)
_, _ = w.Write([]byte(err.Error()))
rsp.Status = 400
rsp.Body = []byte(err.Error())
} else {
_, _ = w.Write(buf.Bytes())
rsp.Body = buf.Bytes()
}
return
}

html := useHtml(&r.Header)
html := useHtml(req)
tabs := false
if html && !hasParam("dataonly", r) {
if html && !req.HasParam("dataonly") {
tabs = true
}
if html {
w.Header().Add("content-type", "text/html")
rsp.SetHeader("content-type", "text/html")
} else {
w.Header().Add("content-type", "text/plain")
rsp.SetHeader("content-type", "text/plain")
}

dumper := &dumpImpl{html: html}
Expand All @@ -211,24 +266,25 @@ func procVar(w http.ResponseWriter, r *http.Request) {
if html {
opt.DisplayFilter = gm.DisplayOnHTML
}
opt.WhiteWildcards = vars["var"]
opt.WhiteWildcards = req.GetParam("var")
n, err := gm.Dump(dumper, opt)
if err != nil {
w.WriteHeader(400)
_, _ = w.Write([]byte(err.Error()))
rsp.Status = 400
rsp.Body = []byte(err.Error())
return
}

if len(opt.WhiteWildcards) > 0 && n == 0 {
w.WriteHeader(400)
_, _ = w.Write([]byte("fail to find any var"))
rsp.Status = 400
rsp.Body = []byte("fail to find any var")
return
}

if tabs {
in := &Input{
Content: dumper.b.String(),
}
if hasParam("expand", r) {
if req.HasParam("expand") {
in.Click = " $(\".variable\").click();\n"
} else {
in.Click = " $(\".default_expand\").click();\n"
Expand All @@ -242,13 +298,17 @@ func procVar(w http.ResponseWriter, r *http.Request) {
in.ValueEnd = " newValue += ']';\n"
}

w := &bytes.Buffer{}
err = server.template.Execute(w, in)
if err != nil {
w.WriteHeader(400)
return
rsp.Status = 400
rsp.Body = []byte(err.Error())
} else {
rsp.Body = w.Bytes()
}
} else {
_, _ = w.Write(dumper.b.Bytes())
rsp.Body = dumper.b.Bytes()
}

return
}
Loading

0 comments on commit f979db4

Please sign in to comment.