(ctx context.Context, o clientOptions)
| 245 | } |
| 246 | |
| 247 | func client(ctx context.Context, o clientOptions) error { |
| 248 | type stat struct { |
| 249 | job int |
| 250 | duration time.Duration |
| 251 | status int |
| 252 | } |
| 253 | stats := make(chan stat) |
| 254 | for i := 0; i < o.jobs; i++ { |
| 255 | go func(i int) { |
| 256 | tr := &http.Transport{ |
| 257 | TLSClientConfig: &tls.Config{ |
| 258 | MinVersion: tls.VersionTLS12, |
| 259 | InsecureSkipVerify: o.insecure, |
| 260 | }, |
| 261 | } |
| 262 | client := &http.Client{Transport: tr} |
| 263 | |
| 264 | cookies := map[string]*http.Cookie{} |
| 265 | for { |
| 266 | // Check if context is cancelled |
| 267 | select { |
| 268 | case <-ctx.Done(): |
| 269 | return |
| 270 | default: |
| 271 | } |
| 272 | |
| 273 | req, err := http.NewRequest(o.request, o.url, bytes.NewReader(o.data)) |
| 274 | if err != nil { |
| 275 | log.Printf("client %d: could not create request: %s\n", i, err) |
| 276 | return |
| 277 | } |
| 278 | req.Header.Set("Authorization", strings.TrimSpace(o.auth())) |
| 279 | for k, v := range o.headers { |
| 280 | req.Header.Set(k, v) |
| 281 | } |
| 282 | for _, cookie := range cookies { |
| 283 | req.AddCookie(cookie) |
| 284 | } |
| 285 | |
| 286 | start := time.Now() |
| 287 | res, err := client.Do(req) |
| 288 | duration := -time.Until(start) |
| 289 | if err != nil { |
| 290 | // Check if error is due to context cancellation |
| 291 | if ctx.Err() != nil { |
| 292 | return |
| 293 | } |
| 294 | log.Printf("client %d: could not create request: %s\n", i, err) |
| 295 | time.Sleep(time.Second) |
| 296 | } else { |
| 297 | res.Body.Close() |
| 298 | select { |
| 299 | case stats <- stat{ |
| 300 | job: i, |
| 301 | duration: duration, |
| 302 | status: res.StatusCode, |
| 303 | }: |
| 304 | case <-ctx.Done(): |
no test coverage detected