@@ -3301,17 +3301,43 @@ type BrowsersCurlInput struct {
33013301 Silent bool
33023302}
33033303
3304- func parseCurlHeaders (raw []string ) map [string ]string {
3304+ type silentCurlError struct {
3305+ err error
3306+ }
3307+
3308+ func (e silentCurlError ) Error () string {
3309+ return e .err .Error ()
3310+ }
3311+
3312+ func (e silentCurlError ) Unwrap () error {
3313+ return e .err
3314+ }
3315+
3316+ func (e silentCurlError ) Silent () bool {
3317+ return true
3318+ }
3319+
3320+ func curlError (in BrowsersCurlInput , err error ) error {
3321+ if err == nil {
3322+ return nil
3323+ }
3324+ if in .Silent {
3325+ return silentCurlError {err : err }
3326+ }
3327+ return err
3328+ }
3329+
3330+ func parseCurlHeaders (raw []string ) http.Header {
33053331 if len (raw ) == 0 {
33063332 return nil
33073333 }
3308- headers := make (map [ string ] string )
3334+ headers := make (http. Header )
33093335 for _ , h := range raw {
33103336 k , v , ok := strings .Cut (h , ":" )
33113337 if ! ok {
33123338 continue
33133339 }
3314- headers [ strings .TrimSpace (k )] = strings .TrimSpace (v )
3340+ headers . Add ( strings .TrimSpace (k ), strings .TrimSpace (v ) )
33153341 }
33163342 return headers
33173343}
@@ -3328,7 +3354,7 @@ func readCurlBody(in BrowsersCurlInput) (string, error) {
33283354 return string (data ), nil
33293355}
33303356
3331- func hasCurlHeader (headers map [ string ] string , name string ) bool {
3357+ func hasCurlHeader (headers http. Header , name string ) bool {
33323358 for key := range headers {
33333359 if strings .EqualFold (key , name ) {
33343360 return true
@@ -3375,18 +3401,18 @@ func openCurlOutputFile(path string) (io.Writer, func() error, error) {
33753401func (b BrowsersCmd ) Curl (ctx context.Context , in BrowsersCurlInput ) error {
33763402 body , err := readCurlBody (in )
33773403 if err != nil {
3378- return err
3404+ return curlError ( in , err )
33793405 }
33803406
33813407 method := in .Method
33823408 if method == "" {
33833409 method = "GET"
3384- if in .Head {
3385- method = "HEAD"
3386- }
33873410 if body != "" {
33883411 method = "POST"
33893412 }
3413+ if in .Head {
3414+ method = "HEAD"
3415+ }
33903416 }
33913417 include := in .Include || in .Head
33923418
@@ -3397,24 +3423,26 @@ func (b BrowsersCmd) Curl(ctx context.Context, in BrowsersCurlInput) error {
33973423
33983424 // Seed the SDK's browser route cache before constructing the raw curl client.
33993425 if _ , err := b .browsers .Get (ctx , in .Identifier , kernel.BrowserGetParams {}); err != nil {
3400- return util.CleanedUpSdkError {Err : err }
3426+ return curlError ( in , util.CleanedUpSdkError {Err : err })
34013427 }
34023428
34033429 httpClient , err := b .browsers .HTTPClient (in .Identifier )
34043430 if err != nil {
3405- return util.CleanedUpSdkError {Err : err }
3431+ return curlError ( in , util.CleanedUpSdkError {Err : err })
34063432 }
34073433 if in .MaxTime > 0 {
34083434 httpClient .Timeout = in .MaxTime
34093435 }
34103436
34113437 req , err := http .NewRequestWithContext (ctx , method , in .URL , bodyReader )
34123438 if err != nil {
3413- return fmt .Errorf ("creating request: %w" , err )
3439+ return curlError ( in , fmt .Errorf ("creating request: %w" , err ) )
34143440 }
34153441 headers := parseCurlHeaders (in .Headers )
3416- for key , value := range headers {
3417- req .Header .Set (key , value )
3442+ for key , values := range headers {
3443+ for _ , value := range values {
3444+ req .Header .Add (key , value )
3445+ }
34183446 }
34193447 if body != "" && ! hasCurlHeader (headers , "Content-Type" ) {
34203448 req .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
@@ -3423,7 +3451,7 @@ func (b BrowsersCmd) Curl(ctx context.Context, in BrowsersCurlInput) error {
34233451 start := time .Now ()
34243452 resp , err := httpClient .Do (req )
34253453 if err != nil {
3426- return fmt .Errorf ("request failed: %w" , err )
3454+ return curlError ( in , fmt .Errorf ("request failed: %w" , err ) )
34273455 }
34283456 defer resp .Body .Close ()
34293457
@@ -3432,7 +3460,7 @@ func (b BrowsersCmd) Curl(ctx context.Context, in BrowsersCurlInput) error {
34323460 if in .OutputFile != "" {
34333461 f , err := os .Create (in .OutputFile )
34343462 if err != nil {
3435- return fmt .Errorf ("creating output file: %w" , err )
3463+ return curlError ( in , fmt .Errorf ("creating output file: %w" , err ) )
34363464 }
34373465 outputFile = f
34383466 defer outputFile .Close ()
@@ -3442,7 +3470,7 @@ func (b BrowsersCmd) Curl(ctx context.Context, in BrowsersCurlInput) error {
34423470 if in .DumpHeader != "" {
34433471 headerWriter , closeHeaderWriter , err := openCurlOutputFile (in .DumpHeader )
34443472 if err != nil {
3445- return fmt .Errorf ("creating dump header file: %w" , err )
3473+ return curlError ( in , fmt .Errorf ("creating dump header file: %w" , err ) )
34463474 }
34473475 defer closeHeaderWriter ()
34483476 writeCurlResponseHeaders (headerWriter , resp )
@@ -3455,7 +3483,7 @@ func (b BrowsersCmd) Curl(ctx context.Context, in BrowsersCurlInput) error {
34553483 timeTotal : time .Since (start ),
34563484 }))
34573485 }
3458- return fmt .Errorf ("HTTP error: %s" , resp .Status )
3486+ return curlError ( in , fmt .Errorf ("HTTP error: %s" , resp .Status ) )
34593487 }
34603488
34613489 if include {
@@ -3467,9 +3495,9 @@ func (b BrowsersCmd) Curl(ctx context.Context, in BrowsersCurlInput) error {
34673495 sizeDownload , err = io .Copy (writer , resp .Body )
34683496 if err != nil {
34693497 if in .OutputFile != "" {
3470- return fmt .Errorf ("writing output file: %w" , err )
3498+ return curlError ( in , fmt .Errorf ("writing output file: %w" , err ) )
34713499 }
3472- return err
3500+ return curlError ( in , err )
34733501 }
34743502 }
34753503
0 commit comments