func (cli *OpsGenieIntegrationClient) buildRequest(method string, uri string, body interface{}) goreq.Request {
	req := goreq.Request{}
	req.Method = method
	req.Uri = uri
	if body != nil {
		req.Body = body
	}
	if cli.proxy != "" {
		req.Proxy = cli.proxy
	}
	req.UserAgent = userAgentParam.ToString()
	return req
}
Esempio n. 2
0
// Spawn sends the actual request.
func (r *Request) Spawn(parent *Response, wg *sync.WaitGroup) {
	body := ""
	if r.Data != nil {
		body = r.Data.Format(parent)
	}
	greq := goreq.Request{Method: r.Method, Body: body, UserAgent: profile.UserAgent}
	// Let's set the headers, if needed.
	if r.Headers != nil {
		for _, line := range strings.Split(r.Headers.Format(parent), "\n") {
			line = strings.TrimSpace(line)
			if line == "" {
				continue
			}
			hdr := strings.Split(line, ":")
			greq.AddHeader(strings.TrimSpace(hdr[0]), strings.TrimSpace(hdr[1]))
		}
	}
	// Let's also add the cookies.
	if r.FwdCookies && parent != nil {
		if parent.cookies != nil {
			for _, delicacy := range parent.cookies {
				greq.AddCookie(delicacy)
			}
		}
	}

	// One go routine which pops responses from the channel and moves them to the list.
	go func() {
		for {
			r.doneReqs = append(r.doneReqs, <-r.doneChan)
			r.doneWg.Done()
			perc := float64(len(r.doneReqs)) / float64(r.Repeat)
			notify := false
			if perc >= 0.75 && perc-0.75 < 1e-4 {
				notify = true
			} else if perc >= 0.5 && perc-0.5 < 1e-4 {
				notify = true
			} else if perc >= 0.25 && perc-0.25 < 1e-4 {
				notify = true
			} else if len(r.doneReqs)%100 == 0 {
				notify = true
			}
			if notify {
				log.Notice("Completed %d requests out of %d to %s.", len(r.doneReqs), r.Repeat, r.URL)
			}
		}
	}()

	// Let's spawn all the requests, with their respective concurrency.
	wg.Add(r.Repeat)
	r.doneWg.Add(r.Repeat)
	for rno := 1; rno <= r.Repeat; rno++ {
		go func(no int, greq goreq.Request) {
			r.ongoingReqs <- struct{}{} // Adding sentinel value to limit concurrency.
			greq.Uri = r.URL.Generate()
			resp := Response{}

			startTime := time.Now()
			gresp, err := greq.Do()
			resp.FromGoResp(gresp, err, startTime)
			if err != nil {
				log.Critical("could not send request to #%d %s: %s", no, r.URL, err)
			}

			<-r.ongoingReqs // We're done, let's make room for the next request.
			resp.duration = time.Since(startTime)
			// Let's add that request to the list of completed requests.
			r.doneChan <- &resp
			runtime.Gosched()
		}(rno, greq)
	}

	// Let's now have a go routine which waits for all the requests to complete
	// and spawns all the children.
	go func() {
		r.doneWg.Wait()

		if r.Children != nil {
			log.Debug("Spawning children for %s.", r.URL)
			for _, child := range r.Children {
				// Note that we always use the LAST response as the parent response.
				child.Spawn(r.doneReqs[0], wg)
			}
		}
		log.Debug("Computing result of %s.", r.URL)
		r.ComputeResult(wg)
	}()
}