github.com/mponton/terratest@v0.44.0/modules/http-helper/http_helper.go (about) 1 // Package http_helper contains helpers to interact with deployed resources through HTTP. 2 package http_helper 3 4 import ( 5 "bytes" 6 "crypto/tls" 7 "fmt" 8 "io" 9 "io/ioutil" 10 "net/http" 11 "strings" 12 "time" 13 14 "github.com/mponton/terratest/modules/logger" 15 "github.com/mponton/terratest/modules/retry" 16 "github.com/mponton/terratest/modules/testing" 17 ) 18 19 type HttpGetOptions struct { 20 Url string 21 TlsConfig *tls.Config 22 Timeout int 23 } 24 25 type HttpDoOptions struct { 26 Method string 27 Url string 28 Body io.Reader 29 Headers map[string]string 30 TlsConfig *tls.Config 31 Timeout int 32 } 33 34 // HttpGet performs an HTTP GET, with an optional pointer to a custom TLS configuration, on the given URL and 35 // return the HTTP status code and body. If there's any error, fail the test. 36 func HttpGet(t testing.TestingT, url string, tlsConfig *tls.Config) (int, string) { 37 return HttpGetWithOptions(t, HttpGetOptions{Url: url, TlsConfig: tlsConfig, Timeout: 10}) 38 } 39 40 // HttpGetWithOptions performs an HTTP GET, with an optional pointer to a custom TLS configuration, on the given URL and 41 // return the HTTP status code and body. If there's any error, fail the test. 42 func HttpGetWithOptions(t testing.TestingT, options HttpGetOptions) (int, string) { 43 statusCode, body, err := HttpGetWithOptionsE(t, options) 44 if err != nil { 45 t.Fatal(err) 46 } 47 return statusCode, body 48 } 49 50 // HttpGetE performs an HTTP GET, with an optional pointer to a custom TLS configuration, on the given URL and 51 // return the HTTP status code, body, and any error. 52 func HttpGetE(t testing.TestingT, url string, tlsConfig *tls.Config) (int, string, error) { 53 return HttpGetWithOptionsE(t, HttpGetOptions{Url: url, TlsConfig: tlsConfig, Timeout: 10}) 54 } 55 56 // HttpGetWithOptionsE performs an HTTP GET, with an optional pointer to a custom TLS configuration, on the given URL and 57 // return the HTTP status code, body, and any error. 58 func HttpGetWithOptionsE(t testing.TestingT, options HttpGetOptions) (int, string, error) { 59 logger.Logf(t, "Making an HTTP GET call to URL %s", options.Url) 60 61 // Set HTTP client transport config 62 tr := http.DefaultTransport.(*http.Transport).Clone() 63 tr.TLSClientConfig = options.TlsConfig 64 65 client := http.Client{ 66 // By default, Go does not impose a timeout, so an HTTP connection attempt can hang for a LONG time. 67 Timeout: time.Duration(options.Timeout) * time.Second, 68 // Include the previously created transport config 69 Transport: tr, 70 } 71 72 resp, err := client.Get(options.Url) 73 if err != nil { 74 return -1, "", err 75 } 76 77 defer resp.Body.Close() 78 body, err := ioutil.ReadAll(resp.Body) 79 80 if err != nil { 81 return -1, "", err 82 } 83 84 return resp.StatusCode, strings.TrimSpace(string(body)), nil 85 } 86 87 // HttpGetWithValidation performs an HTTP GET on the given URL and verify that you get back the expected status code and body. If either 88 // doesn't match, fail the test. 89 func HttpGetWithValidation(t testing.TestingT, url string, tlsConfig *tls.Config, expectedStatusCode int, expectedBody string) { 90 options := HttpGetOptions{Url: url, TlsConfig: tlsConfig, Timeout: 10} 91 HttpGetWithValidationWithOptions(t, options, expectedStatusCode, expectedBody) 92 } 93 94 // HttpGetWithValidationWithOptions performs an HTTP GET on the given URL and verify that you get back the expected status code and body. If either 95 // doesn't match, fail the test. 96 func HttpGetWithValidationWithOptions(t testing.TestingT, options HttpGetOptions, expectedStatusCode int, expectedBody string) { 97 err := HttpGetWithValidationWithOptionsE(t, options, expectedStatusCode, expectedBody) 98 if err != nil { 99 t.Fatal(err) 100 } 101 } 102 103 // HttpGetWithValidationE performs an HTTP GET on the given URL and verify that you get back the expected status code and body. If either 104 // doesn't match, return an error. 105 func HttpGetWithValidationE(t testing.TestingT, url string, tlsConfig *tls.Config, expectedStatusCode int, expectedBody string) error { 106 options := HttpGetOptions{Url: url, TlsConfig: tlsConfig, Timeout: 10} 107 return HttpGetWithValidationWithOptionsE(t, options, expectedStatusCode, expectedBody) 108 } 109 110 // HttpGetWithValidationWithOptionsE performs an HTTP GET on the given URL and verify that you get back the expected status code and body. If either 111 // doesn't match, return an error. 112 func HttpGetWithValidationWithOptionsE(t testing.TestingT, options HttpGetOptions, expectedStatusCode int, expectedBody string) error { 113 return HttpGetWithCustomValidationWithOptionsE(t, options, func(statusCode int, body string) bool { 114 return statusCode == expectedStatusCode && body == expectedBody 115 }) 116 } 117 118 // HttpGetWithCustomValidation performs an HTTP GET on the given URL and validate the returned status code and body using the given function. 119 func HttpGetWithCustomValidation(t testing.TestingT, url string, tlsConfig *tls.Config, validateResponse func(int, string) bool) { 120 HttpGetWithCustomValidationWithOptions(t, HttpGetOptions{Url: url, TlsConfig: tlsConfig, Timeout: 10}, validateResponse) 121 } 122 123 // HttpGetWithCustomValidationWithOptions performs an HTTP GET on the given URL and validate the returned status code and body using the given function. 124 func HttpGetWithCustomValidationWithOptions(t testing.TestingT, options HttpGetOptions, validateResponse func(int, string) bool) { 125 err := HttpGetWithCustomValidationWithOptionsE(t, options, validateResponse) 126 if err != nil { 127 t.Fatal(err) 128 } 129 } 130 131 // HttpGetWithCustomValidationE performs an HTTP GET on the given URL and validate the returned status code and body using the given function. 132 func HttpGetWithCustomValidationE(t testing.TestingT, url string, tlsConfig *tls.Config, validateResponse func(int, string) bool) error { 133 return HttpGetWithCustomValidationWithOptionsE(t, HttpGetOptions{Url: url, TlsConfig: tlsConfig, Timeout: 10}, validateResponse) 134 } 135 136 // HttpGetWithCustomValidationWithOptionsE performs an HTTP GET on the given URL and validate the returned status code and body using the given function. 137 func HttpGetWithCustomValidationWithOptionsE(t testing.TestingT, options HttpGetOptions, validateResponse func(int, string) bool) error { 138 statusCode, body, err := HttpGetWithOptionsE(t, options) 139 140 if err != nil { 141 return err 142 } 143 144 if !validateResponse(statusCode, body) { 145 return ValidationFunctionFailed{Url: options.Url, Status: statusCode, Body: body} 146 } 147 148 return nil 149 } 150 151 // HttpGetWithRetry repeatedly performs an HTTP GET on the given URL until the given status code and body are returned or until max 152 // retries has been exceeded. 153 func HttpGetWithRetry(t testing.TestingT, url string, tlsConfig *tls.Config, expectedStatus int, expectedBody string, retries int, sleepBetweenRetries time.Duration) { 154 options := HttpGetOptions{Url: url, TlsConfig: tlsConfig, Timeout: 10} 155 HttpGetWithRetryWithOptions(t, options, expectedStatus, expectedBody, retries, sleepBetweenRetries) 156 } 157 158 // HttpGetWithRetryWithOptions repeatedly performs an HTTP GET on the given URL until the given status code and body are returned or until max 159 // retries has been exceeded. 160 func HttpGetWithRetryWithOptions(t testing.TestingT, options HttpGetOptions, expectedStatus int, expectedBody string, retries int, sleepBetweenRetries time.Duration) { 161 err := HttpGetWithRetryWithOptionsE(t, options, expectedStatus, expectedBody, retries, sleepBetweenRetries) 162 if err != nil { 163 t.Fatal(err) 164 } 165 } 166 167 // HttpGetWithRetryE repeatedly performs an HTTP GET on the given URL until the given status code and body are returned or until max 168 // retries has been exceeded. 169 func HttpGetWithRetryE(t testing.TestingT, url string, tlsConfig *tls.Config, expectedStatus int, expectedBody string, retries int, sleepBetweenRetries time.Duration) error { 170 options := HttpGetOptions{Url: url, TlsConfig: tlsConfig, Timeout: 10} 171 return HttpGetWithRetryWithOptionsE(t, options, expectedStatus, expectedBody, retries, sleepBetweenRetries) 172 } 173 174 // HttpGetWithRetryWithOptionsE repeatedly performs an HTTP GET on the given URL until the given status code and body are returned or until max 175 // retries has been exceeded. 176 func HttpGetWithRetryWithOptionsE(t testing.TestingT, options HttpGetOptions, expectedStatus int, expectedBody string, retries int, sleepBetweenRetries time.Duration) error { 177 _, err := retry.DoWithRetryE(t, fmt.Sprintf("HTTP GET to URL %s", options.Url), retries, sleepBetweenRetries, func() (string, error) { 178 return "", HttpGetWithValidationWithOptionsE(t, options, expectedStatus, expectedBody) 179 }) 180 181 return err 182 } 183 184 // HttpGetWithRetryWithCustomValidation repeatedly performs an HTTP GET on the given URL until the given validation function returns true or max retries 185 // has been exceeded. 186 func HttpGetWithRetryWithCustomValidation(t testing.TestingT, url string, tlsConfig *tls.Config, retries int, sleepBetweenRetries time.Duration, validateResponse func(int, string) bool) { 187 options := HttpGetOptions{Url: url, TlsConfig: tlsConfig, Timeout: 10} 188 HttpGetWithRetryWithCustomValidationWithOptions(t, options, retries, sleepBetweenRetries, validateResponse) 189 } 190 191 // HttpGetWithRetryWithCustomValidationWithOptions repeatedly performs an HTTP GET on the given URL until the given validation function returns true or max retries 192 // has been exceeded. 193 func HttpGetWithRetryWithCustomValidationWithOptions(t testing.TestingT, options HttpGetOptions, retries int, sleepBetweenRetries time.Duration, validateResponse func(int, string) bool) { 194 err := HttpGetWithRetryWithCustomValidationWithOptionsE(t, options, retries, sleepBetweenRetries, validateResponse) 195 if err != nil { 196 t.Fatal(err) 197 } 198 } 199 200 // HttpGetWithRetryWithCustomValidationE repeatedly performs an HTTP GET on the given URL until the given validation function returns true or max retries 201 // has been exceeded. 202 func HttpGetWithRetryWithCustomValidationE(t testing.TestingT, url string, tlsConfig *tls.Config, retries int, sleepBetweenRetries time.Duration, validateResponse func(int, string) bool) error { 203 options := HttpGetOptions{Url: url, TlsConfig: tlsConfig, Timeout: 10} 204 return HttpGetWithRetryWithCustomValidationWithOptionsE(t, options, retries, sleepBetweenRetries, validateResponse) 205 } 206 207 // HttpGetWithRetryWithCustomValidationWithOptionsE repeatedly performs an HTTP GET on the given URL until the given validation function returns true or max retries 208 // has been exceeded. 209 func HttpGetWithRetryWithCustomValidationWithOptionsE(t testing.TestingT, options HttpGetOptions, retries int, sleepBetweenRetries time.Duration, validateResponse func(int, string) bool) error { 210 _, err := retry.DoWithRetryE(t, fmt.Sprintf("HTTP GET to URL %s", options.Url), retries, sleepBetweenRetries, func() (string, error) { 211 return "", HttpGetWithCustomValidationWithOptionsE(t, options, validateResponse) 212 }) 213 214 return err 215 } 216 217 // HTTPDo performs the given HTTP method on the given URL and return the HTTP status code and body. 218 // If there's any error, fail the test. 219 func HTTPDo( 220 t testing.TestingT, method string, url string, body io.Reader, 221 headers map[string]string, tlsConfig *tls.Config, 222 ) (int, string) { 223 options := HttpDoOptions{ 224 Method: method, 225 Url: url, 226 Body: body, 227 Headers: headers, 228 TlsConfig: tlsConfig, 229 Timeout: 10} 230 return HTTPDoWithOptions(t, options) 231 } 232 233 // HTTPDoWithOptions performs the given HTTP method on the given URL and return the HTTP status code and body. 234 // If there's any error, fail the test. 235 func HTTPDoWithOptions( 236 t testing.TestingT, options HttpDoOptions, 237 ) (int, string) { 238 statusCode, respBody, err := HTTPDoWithOptionsE(t, options) 239 if err != nil { 240 t.Fatal(err) 241 } 242 return statusCode, respBody 243 } 244 245 // HTTPDoE performs the given HTTP method on the given URL and return the HTTP status code, body, and any error. 246 func HTTPDoE( 247 t testing.TestingT, method string, url string, body io.Reader, 248 headers map[string]string, tlsConfig *tls.Config, 249 ) (int, string, error) { 250 options := HttpDoOptions{ 251 Method: method, 252 Url: url, 253 Body: body, 254 Headers: headers, 255 Timeout: 10, 256 TlsConfig: tlsConfig} 257 return HTTPDoWithOptionsE(t, options) 258 } 259 260 // HTTPDoWithOptionsE performs the given HTTP method on the given URL and return the HTTP status code, body, and any error. 261 func HTTPDoWithOptionsE( 262 t testing.TestingT, options HttpDoOptions, 263 ) (int, string, error) { 264 logger.Logf(t, "Making an HTTP %s call to URL %s", options.Method, options.Url) 265 266 tr := &http.Transport{ 267 TLSClientConfig: options.TlsConfig, 268 } 269 270 client := http.Client{ 271 // By default, Go does not impose a timeout, so an HTTP connection attempt can hang for a LONG time. 272 Timeout: time.Duration(options.Timeout) * time.Second, 273 Transport: tr, 274 } 275 276 req := newRequest(options.Method, options.Url, options.Body, options.Headers) 277 resp, err := client.Do(req) 278 if err != nil { 279 return -1, "", err 280 } 281 282 defer resp.Body.Close() 283 respBody, err := ioutil.ReadAll(resp.Body) 284 285 if err != nil { 286 return -1, "", err 287 } 288 289 return resp.StatusCode, strings.TrimSpace(string(respBody)), nil 290 } 291 292 // HTTPDoWithRetry repeatedly performs the given HTTP method on the given URL until the given status code and body are 293 // returned or until max retries has been exceeded. 294 // The function compares the expected status code against the received one and fails if they don't match. 295 func HTTPDoWithRetry( 296 t testing.TestingT, method string, url string, 297 body []byte, headers map[string]string, expectedStatus int, 298 retries int, sleepBetweenRetries time.Duration, tlsConfig *tls.Config, 299 ) string { 300 options := HttpDoOptions{ 301 Method: method, 302 Url: url, 303 Body: bytes.NewReader(body), 304 Headers: headers, 305 TlsConfig: tlsConfig, 306 Timeout: 10} 307 return HTTPDoWithRetryWithOptions(t, options, expectedStatus, retries, sleepBetweenRetries) 308 } 309 310 // HTTPDoWithRetryWithOptions repeatedly performs the given HTTP method on the given URL until the given status code and body are 311 // returned or until max retries has been exceeded. 312 // The function compares the expected status code against the received one and fails if they don't match. 313 func HTTPDoWithRetryWithOptions( 314 t testing.TestingT, options HttpDoOptions, expectedStatus int, 315 retries int, sleepBetweenRetries time.Duration, 316 ) string { 317 out, err := HTTPDoWithRetryWithOptionsE(t, options, expectedStatus, retries, sleepBetweenRetries) 318 if err != nil { 319 t.Fatal(err) 320 } 321 return out 322 } 323 324 // HTTPDoWithRetryE repeatedly performs the given HTTP method on the given URL until the given status code and body are 325 // returned or until max retries has been exceeded. 326 // The function compares the expected status code against the received one and fails if they don't match. 327 func HTTPDoWithRetryE( 328 t testing.TestingT, method string, url string, 329 body []byte, headers map[string]string, expectedStatus int, 330 retries int, sleepBetweenRetries time.Duration, tlsConfig *tls.Config, 331 ) (string, error) { 332 options := HttpDoOptions{ 333 Method: method, 334 Url: url, 335 Body: bytes.NewReader(body), 336 Headers: headers, 337 TlsConfig: tlsConfig, 338 Timeout: 10} 339 340 return HTTPDoWithRetryWithOptionsE(t, options, expectedStatus, retries, sleepBetweenRetries) 341 } 342 343 // HTTPDoWithRetryWithOptionsE repeatedly performs the given HTTP method on the given URL until the given status code and body are 344 // returned or until max retries has been exceeded. 345 // The function compares the expected status code against the received one and fails if they don't match. 346 func HTTPDoWithRetryWithOptionsE( 347 t testing.TestingT, options HttpDoOptions, expectedStatus int, 348 retries int, sleepBetweenRetries time.Duration, 349 ) (string, error) { 350 // The request body is closed after a request is complete. 351 // Extract the underlying data and cache it so we can reuse for retried requests 352 data, err := io.ReadAll(options.Body) 353 if err != nil { 354 return "", err 355 } 356 357 options.Body = nil 358 359 out, err := retry.DoWithRetryE( 360 t, fmt.Sprintf("HTTP %s to URL %s", options.Method, options.Url), retries, 361 sleepBetweenRetries, func() (string, error) { 362 options.Body = bytes.NewReader(data) 363 statusCode, out, err := HTTPDoWithOptionsE(t, options) 364 if err != nil { 365 return "", err 366 } 367 logger.Logf(t, "output: %v", out) 368 if statusCode != expectedStatus { 369 return "", ValidationFunctionFailed{Url: options.Url, Status: statusCode} 370 } 371 return out, nil 372 }) 373 374 return out, err 375 } 376 377 // HTTPDoWithValidationRetry repeatedly performs the given HTTP method on the given URL until the given status code and 378 // body are returned or until max retries has been exceeded. 379 func HTTPDoWithValidationRetry( 380 t testing.TestingT, method string, url string, 381 body []byte, headers map[string]string, expectedStatus int, 382 expectedBody string, retries int, sleepBetweenRetries time.Duration, tlsConfig *tls.Config, 383 ) { 384 options := HttpDoOptions{ 385 Method: method, 386 Url: url, 387 Body: bytes.NewReader(body), 388 Headers: headers, 389 TlsConfig: tlsConfig, 390 Timeout: 10} 391 392 HTTPDoWithValidationRetryWithOptions(t, options, expectedStatus, expectedBody, retries, sleepBetweenRetries) 393 } 394 395 // HTTPDoWithValidationRetryWithOptions repeatedly performs the given HTTP method on the given URL until the given status code and 396 // body are returned or until max retries has been exceeded. 397 func HTTPDoWithValidationRetryWithOptions( 398 t testing.TestingT, options HttpDoOptions, expectedStatus int, 399 expectedBody string, retries int, sleepBetweenRetries time.Duration, 400 ) { 401 err := HTTPDoWithValidationRetryWithOptionsE(t, options, expectedStatus, expectedBody, retries, sleepBetweenRetries) 402 if err != nil { 403 t.Fatal(err) 404 } 405 } 406 407 // HTTPDoWithValidationRetryE repeatedly performs the given HTTP method on the given URL until the given status code and 408 // body are returned or until max retries has been exceeded. 409 func HTTPDoWithValidationRetryE( 410 t testing.TestingT, method string, url string, 411 body []byte, headers map[string]string, expectedStatus int, 412 expectedBody string, retries int, sleepBetweenRetries time.Duration, tlsConfig *tls.Config, 413 ) error { 414 options := HttpDoOptions{ 415 Method: method, 416 Url: url, 417 Body: bytes.NewReader(body), 418 Headers: headers, 419 TlsConfig: tlsConfig, 420 Timeout: 10} 421 422 return HTTPDoWithValidationRetryWithOptionsE(t, options, expectedStatus, expectedBody, retries, sleepBetweenRetries) 423 } 424 425 // HTTPDoWithValidationRetryWithOptionsE repeatedly performs the given HTTP method on the given URL until the given status code and 426 // body are returned or until max retries has been exceeded. 427 func HTTPDoWithValidationRetryWithOptionsE( 428 t testing.TestingT, options HttpDoOptions, expectedStatus int, 429 expectedBody string, retries int, sleepBetweenRetries time.Duration, 430 ) error { 431 _, err := retry.DoWithRetryE(t, fmt.Sprintf("HTTP %s to URL %s", options.Method, options.Url), retries, 432 sleepBetweenRetries, func() (string, error) { 433 return "", HTTPDoWithValidationWithOptionsE(t, options, expectedStatus, expectedBody) 434 }) 435 436 return err 437 } 438 439 // HTTPDoWithValidation performs the given HTTP method on the given URL and verify that you get back the expected status 440 // code and body. If either doesn't match, fail the test. 441 func HTTPDoWithValidation(t testing.TestingT, method string, url string, body io.Reader, headers map[string]string, expectedStatusCode int, expectedBody string, tlsConfig *tls.Config) { 442 options := HttpDoOptions{ 443 Method: method, 444 Url: url, 445 Body: body, 446 Headers: headers, 447 TlsConfig: tlsConfig, 448 Timeout: 10} 449 450 HTTPDoWithValidationWithOptions(t, options, expectedStatusCode, expectedBody) 451 } 452 453 // HTTPDoWithValidationWithOptions performs the given HTTP method on the given URL and verify that you get back the expected status 454 // code and body. If either doesn't match, fail the test. 455 func HTTPDoWithValidationWithOptions(t testing.TestingT, options HttpDoOptions, expectedStatusCode int, expectedBody string) { 456 err := HTTPDoWithValidationWithOptionsE(t, options, expectedStatusCode, expectedBody) 457 if err != nil { 458 t.Fatal(err) 459 } 460 } 461 462 // HTTPDoWithValidationE performs the given HTTP method on the given URL and verify that you get back the expected status 463 // code and body. If either doesn't match, return an error. 464 func HTTPDoWithValidationE(t testing.TestingT, method string, url string, body io.Reader, headers map[string]string, expectedStatusCode int, expectedBody string, tlsConfig *tls.Config) error { 465 options := HttpDoOptions{ 466 Method: method, 467 Url: url, 468 Body: body, 469 Headers: headers, 470 TlsConfig: tlsConfig, 471 Timeout: 10} 472 473 return HTTPDoWithValidationWithOptionsE(t, options, expectedStatusCode, expectedBody) 474 } 475 476 // HTTPDoWithValidationWithOptionsE performs the given HTTP method on the given URL and verify that you get back the expected status 477 // code and body. If either doesn't match, return an error. 478 func HTTPDoWithValidationWithOptionsE(t testing.TestingT, options HttpDoOptions, expectedStatusCode int, expectedBody string) error { 479 return HTTPDoWithCustomValidationWithOptionsE(t, options, func(statusCode int, body string) bool { 480 return statusCode == expectedStatusCode && body == expectedBody 481 }) 482 } 483 484 // HTTPDoWithCustomValidation performs the given HTTP method on the given URL and validate the returned status code and 485 // body using the given function. 486 func HTTPDoWithCustomValidation(t testing.TestingT, method string, url string, body io.Reader, headers map[string]string, validateResponse func(int, string) bool, tlsConfig *tls.Config) { 487 options := HttpDoOptions{ 488 Method: method, 489 Url: url, 490 Body: body, 491 Headers: headers, 492 TlsConfig: tlsConfig, 493 Timeout: 10} 494 495 HTTPDoWithCustomValidationWithOptions(t, options, validateResponse) 496 } 497 498 // HTTPDoWithCustomValidationWithOptions performs the given HTTP method on the given URL and validate the returned status code and 499 // body using the given function. 500 func HTTPDoWithCustomValidationWithOptions(t testing.TestingT, options HttpDoOptions, validateResponse func(int, string) bool) { 501 err := HTTPDoWithCustomValidationWithOptionsE(t, options, validateResponse) 502 if err != nil { 503 t.Fatal(err) 504 } 505 } 506 507 // HTTPDoWithCustomValidationE performs the given HTTP method on the given URL and validate the returned status code and 508 // body using the given function. 509 func HTTPDoWithCustomValidationE(t testing.TestingT, method string, url string, body io.Reader, headers map[string]string, validateResponse func(int, string) bool, tlsConfig *tls.Config) error { 510 options := HttpDoOptions{ 511 Method: method, 512 Url: url, 513 Body: body, 514 Headers: headers, 515 TlsConfig: tlsConfig, 516 Timeout: 10} 517 518 return HTTPDoWithCustomValidationWithOptionsE(t, options, validateResponse) 519 } 520 521 // HTTPDoWithCustomValidationWithOptionsE performs the given HTTP method on the given URL and validate the returned status code and 522 // body using the given function. 523 func HTTPDoWithCustomValidationWithOptionsE(t testing.TestingT, options HttpDoOptions, validateResponse func(int, string) bool) error { 524 statusCode, respBody, err := HTTPDoWithOptionsE(t, options) 525 526 if err != nil { 527 return err 528 } 529 530 if !validateResponse(statusCode, respBody) { 531 return ValidationFunctionFailed{Url: options.Url, Status: statusCode, Body: respBody} 532 } 533 534 return nil 535 } 536 537 func newRequest(method string, url string, body io.Reader, headers map[string]string) *http.Request { 538 req, err := http.NewRequest(method, url, body) 539 if err != nil { 540 return nil 541 } 542 for k, v := range headers { 543 switch k { 544 case "Host": 545 req.Host = v 546 default: 547 req.Header.Add(k, v) 548 } 549 } 550 return req 551 }