func makeBabelHandler(midl *idl.Idl, svc *idl.Service, mth *idl.Method) (httprouter.Handle, error) { destPath := path.Join(conf.BabelPath, svc.Name, mth.Name) if !strings.HasPrefix(destPath, "/") { destPath = "/" + destPath } destUrl := conf.BabelProto + "://" + conf.BabelAddr + destPath handle := func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { kubismus.Metric("Requests", 1, 0) // post to server httpreq, err := http.NewRequest("POST", destUrl, r.Body) if err != nil { log.Fatal(err) } for k, v := range r.Header { for _, vi := range v { httpreq.Header.Add(k, vi) } } httpreq.Header.Set("Content-Type", "application/json") //httpreq.Header.Set("Accept", "application/json") // httpreq.ContentLength = int64(len(b)) httpreq.Close = false doHttp(httpreq, w) } return handle, nil }
func writeFiles(mn, mx int, delay time.Duration, extension string) { b := make([]byte, mx) fn := make([]byte, 16) for { _, err := crand.Read(fn) if err != nil { panic(err) } // read data sz := mn + rand.Intn(mx-mn) _, err = crand.Read(b[:sz]) if err != nil { panic(err) } // create file fns := hex.EncodeToString(fn) + extension //log.Printf("File named [%s] is %d bytes", fns, sz) f, err := os.Create(fns) if err != nil { log.Print(err) } else { _, err = f.Write(b[:sz]) if err != nil { log.Print(err) } err = f.Close() if err != nil { log.Print(err) } kubismus.Metric("Data", 1, float64(sz)) } time.Sleep(delay) } }
func posterThread(ctx context.Context, ch <-chan L, wg *sync.WaitGroup) { done := ctx.Done() defer wg.Done() for { select { case i, ok := <-ch: if !ok { return } //log.Printf("%#v", i) var f io.ReadCloser var err error if i.Filename != "" { f, err = os.Open(i.Filename) if err != nil { log.Printf("Unable to open %s", i.Filename) continue } } req, err := http.NewRequest(i.Method, i.URL, f) if err != nil { if f != nil { f.Close() } log.Fatal(err) } if i.Filename != "" { ct := mime.TypeByExtension(filepath.Ext(i.Filename)) if ct != "" { req.Header.Set("Content-Type", ct) } req.ContentLength = i.Size } if useRequestId != "" { guid, err := uuid.NewV4() if err == nil { req.Header.Set(useRequestId, guid.String()) } } for _, h := range headers { if h.Mode == HdrSet { req.Header.Set(h.Key, h.Value) } else { req.Header.Add(h.Key, h.Value) } } req.Close = false // log.Printf("%#v", req) t := time.Now() resp, err := client.Do(req) if f != nil { f.Close() } if err != nil { kubismus.Metric("Error", 1, 0) log.Print("HTTP error ", i.URL, ": ", err) continue } kubismus.Metric("Sent", 1, float64(i.Size)) name := urlToFilename(&i) // log.Print("File would be ", name) var outfile io.WriteCloser writeTo := ioutil.Discard if !discard { outfile, err := os.Create(name) if err != nil { log.Print("Unable to create file ", name) } else { writeTo = outfile } } if !(resp.StatusCode >= 200 && resp.StatusCode <= 299) { log.Print("Failed to post to ", i.URL, ", status ", resp.Status) } //if resp.ContentLength > 0 { statusRange := resp.StatusCode / 100 switch statusRange { case 1: kubismus.Metric("Received100", 1, 0) case 2: kubismus.Metric("Received200", 1, 0) case 3: kubismus.Metric("Received300", 1, 0) case 4: kubismus.Metric("Received400", 1, 0) case 5: kubismus.Metric("Received500", 1, 0) } sz, err := io.Copy(writeTo, resp.Body) if err == nil { kubismus.Metric("Received", 1, float64(sz)) } //} resp.Body.Close() d := time.Since(t) kubismus.Metric("ResponseTime", 1, float64(d.Nanoseconds())/float64(time.Second)) if outfile != nil { outfile.Close() } case <-done: return } } }
func makeHandler(midl *idl.Idl, svc *idl.Service, mth *idl.Method) (httprouter.Handle, error) { destPath := path.Join(conf.BabelPath, svc.Name, mth.Name) if !strings.HasPrefix(destPath, "/") { destPath = "/" + destPath } destUrl := conf.BabelProto + "://" + conf.BabelAddr + destPath handle := func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { kubismus.Metric("Requests", 1, 0) // make parameter structure req := make(map[string]interface{}) for _, fld := range mth.Parameters { annotation, err := rest.ReadParm(fld) if err != nil { http.Error(w, err.Error(), 500) return } nm := fld.Name if annotation.Name != "" { nm = annotation.Name } switch annotation.In { case rest.QUERY: val := r.URL.Query()[nm] if len(val) > 0 || annotation.Required { v, err := toType(val, midl, fld.Type, annotation.Format) if err != nil { http.Error(w, err.Error(), 500) return } req[fld.Name] = v } case rest.HEADER: val := r.Header[nm] if len(val) > 0 || annotation.Required { v, err := toType(val, midl, fld.Type, annotation.Format) if err != nil { http.Error(w, err.Error(), 500) return } req[fld.Name] = v } case rest.PATH: val := p.ByName(nm) if val != "" || annotation.Required { v, err := toType([]string{val}, midl, fld.Type, annotation.Format) if err != nil { http.Error(w, err.Error(), 500) return } req[fld.Name] = v } case rest.FORMDATA: // in theory form data is not legal // but this is how it could be processed err := r.ParseForm() if err != nil { http.Error(w, err.Error(), 500) return } vals := make(map[string]interface{}) for k, v := range r.PostForm { switch len(v) { case 0: vals[k] = nil case 1: vals[k] = v[0] default: vals[k] = v } } req[fld.Name] = vals case rest.BODY: enc := json.NewDecoder(r.Body) var m interface{} err := enc.Decode(&m) if err != nil { http.Error(w, err.Error(), 500) return } req[fld.Name] = m } } // post to server b, err := json.Marshal(req) if err != nil { http.Error(w, err.Error(), 500) } httpreq, err := http.NewRequest("POST", destUrl, bytes.NewReader(b)) if err != nil { log.Fatal(err) } for k, v := range r.Header { for _, vi := range v { httpreq.Header.Add(k, vi) } } httpreq.Header.Set("Content-Type", "application/json") //httpreq.Header.Set("Accept", "application/json") httpreq.ContentLength = int64(len(b)) httpreq.Close = false doHttp(httpreq, w) } return handle, nil }