github.com/go-graphite/carbonapi@v0.17.0/cmd/mockbackend/tags.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"net/http"
     6  	"time"
     7  
     8  	"go.uber.org/zap"
     9  )
    10  
    11  func (cfg *listener) tagsAutocompleteHandler(wr http.ResponseWriter, req *http.Request, isValues bool) {
    12  	_ = req.ParseMultipartForm(16 * 1024 * 1024)
    13  	hdrs := make(map[string][]string)
    14  
    15  	for n, v := range req.Header {
    16  		hdrs[n] = v
    17  	}
    18  
    19  	logger := cfg.logger.With(
    20  		zap.String("function", "findHandler"),
    21  		zap.String("method", req.Method),
    22  		zap.String("path", req.URL.Path),
    23  		zap.Any("form", req.Form),
    24  		zap.Any("headers", hdrs),
    25  	)
    26  	logger.Info("got request")
    27  
    28  	if cfg.Code != http.StatusOK {
    29  		wr.WriteHeader(cfg.Code)
    30  		return
    31  	}
    32  
    33  	format, err := getFormat(req)
    34  	if err != nil {
    35  		wr.WriteHeader(http.StatusBadRequest)
    36  		_, _ = wr.Write([]byte(err.Error()))
    37  		return
    38  	}
    39  
    40  	url := req.URL.String()
    41  
    42  	logger.Info("request details",
    43  		zap.Any("query", req.Form),
    44  	)
    45  
    46  	returnCode := http.StatusOK
    47  	var tags []string
    48  	if response, ok := cfg.Expressions[url]; ok {
    49  		if response.ReplyDelayMS > 0 {
    50  			delay := time.Duration(response.ReplyDelayMS) * time.Millisecond
    51  			time.Sleep(delay)
    52  		}
    53  		if response.Code == http.StatusNotFound {
    54  			returnCode = http.StatusNotFound
    55  		} else if response.Code != 0 && response.Code != http.StatusOK {
    56  			returnCode = response.Code
    57  			http.Error(wr, http.StatusText(returnCode), returnCode)
    58  			return
    59  		} else {
    60  			tags = response.Tags
    61  		}
    62  	}
    63  
    64  	if returnCode == http.StatusNotFound {
    65  		// return 404 when no data
    66  		http.Error(wr, http.StatusText(returnCode), returnCode)
    67  		return
    68  	}
    69  
    70  	logger.Info("will return", zap.Strings("response", tags))
    71  
    72  	var b []byte
    73  	switch format {
    74  	case jsonFormat:
    75  		var buf bytes.Buffer
    76  		buf.WriteByte('[')
    77  		for i, t := range tags {
    78  			if i == 0 {
    79  				buf.WriteByte('"')
    80  			} else {
    81  				buf.WriteString(`, "`)
    82  			}
    83  			buf.WriteString(t)
    84  			buf.WriteByte('"')
    85  		}
    86  		buf.WriteByte(']')
    87  		b = buf.Bytes()
    88  		wr.Header().Set("Content-Type", contentTypeJSON)
    89  	default:
    90  		returCode := http.StatusBadRequest
    91  		http.Error(wr, http.StatusText(returnCode), returCode)
    92  		return
    93  	}
    94  
    95  	_, _ = wr.Write(b)
    96  }
    97  
    98  func (cfg *listener) tagsValuesHandler(wr http.ResponseWriter, req *http.Request) {
    99  	cfg.tagsAutocompleteHandler(wr, req, true)
   100  }
   101  
   102  func (cfg *listener) tagsNamesHandler(wr http.ResponseWriter, req *http.Request) {
   103  	cfg.tagsAutocompleteHandler(wr, req, false)
   104  }