@@ -13,13 +13,20 @@ import (
1313 "path/filepath"
1414 "runtime"
1515 "strings"
16+
17+ "github.com/playwright-community/playwright-go/internal/multierror"
1618)
1719
1820const (
1921 playwrightCliVersion = "1.39.0"
20- playwrightCDN = "https://playwright.azureedge.net"
2122)
2223
24+ var playwrightCDNMirrors = []string {
25+ "https://playwright.azureedge.net" ,
26+ "https://playwright-akamai.azureedge.net" ,
27+ "https://playwright-verizon.azureedge.net" ,
28+ }
29+
2330type PlaywrightDriver struct {
2431 DriverDirectory , DriverBinaryLocation , Version string
2532 options * RunOptions
@@ -134,19 +141,10 @@ func (d *PlaywrightDriver) DownloadDriver() error {
134141 if d .options .Verbose {
135142 log .Printf ("Downloading driver to %s" , d .DriverDirectory )
136143 }
137- driverURL := d .getDriverURL ()
138- resp , err := http .Get (driverURL )
139- if err != nil {
140- return fmt .Errorf ("could not download driver: %w" , err )
141- }
142- if resp .StatusCode != http .StatusOK {
143- return fmt .Errorf ("error: got non 200 status code: %d (%s)" , resp .StatusCode , resp .Status )
144- }
145- defer resp .Body .Close ()
146144
147- body , err := io . ReadAll ( resp . Body )
145+ body , err := downloadDriver ( d . getDriverURLs () )
148146 if err != nil {
149- return fmt . Errorf ( "could not read response body: %w" , err )
147+ return err
150148 }
151149 zipReader , err := zip .NewReader (bytes .NewReader (body ), int64 (len (body )))
152150 if err != nil {
@@ -310,7 +308,7 @@ func getDriverName() string {
310308 panic ("Not supported OS!" )
311309}
312310
313- func (d * PlaywrightDriver ) getDriverURL () string {
311+ func (d * PlaywrightDriver ) getDriverURLs () [] string {
314312 platform := ""
315313 switch runtime .GOOS {
316314 case "windows" :
@@ -329,16 +327,20 @@ func (d *PlaywrightDriver) getDriverURL() string {
329327 }
330328 }
331329
332- baseURL := fmt .Sprintf ("%s/builds/driver" , playwrightCDN )
333- if hostEnv := os .Getenv ("PLAYWRIGHT_DOWNLOAD_HOST" ); hostEnv != "" {
334- baseURL = fmt .Sprintf ("%s/builds/driver" , hostEnv )
330+ baseURLs := []string {}
331+ pattern := "%s/builds/driver/playwright-%s-%s.zip"
332+ if ! d .isReleaseVersion () {
333+ pattern = "%s/next/builds/driver/playwright-%s-%s.zip"
335334 }
336335
337- if d .isReleaseVersion () {
338- return fmt .Sprintf ("%s/playwright-%s-%s.zip" , baseURL , d .Version , platform )
336+ if hostEnv := os .Getenv ("PLAYWRIGHT_DOWNLOAD_HOST" ); hostEnv != "" {
337+ baseURLs = append (baseURLs , fmt .Sprintf (pattern , hostEnv , d .Version , platform ))
338+ } else {
339+ for _ , mirror := range playwrightCDNMirrors {
340+ baseURLs = append (baseURLs , fmt .Sprintf (pattern , mirror , d .Version , platform ))
341+ }
339342 }
340-
341- return fmt .Sprintf ("%s/next/playwright-%s-%s.zip" , baseURL , d .Version , platform )
343+ return baseURLs
342344}
343345
344346// isReleaseVersion checks if the version is not a beta or alpha release
@@ -357,3 +359,25 @@ func makeFileExecutable(path string) error {
357359 }
358360 return nil
359361}
362+
363+ func downloadDriver (driverURLs []string ) (body []byte , e error ) {
364+ for _ , driverURL := range driverURLs {
365+ resp , err := http .Get (driverURL )
366+ if err != nil {
367+ e = multierror .Join (e , fmt .Errorf ("could not download driver from %s: %w" , driverURL , err ))
368+ continue
369+ }
370+ defer resp .Body .Close ()
371+ if resp .StatusCode != http .StatusOK {
372+ e = multierror .Join (e , fmt .Errorf ("error: got non 200 status code: %d (%s) from %s" , resp .StatusCode , resp .Status , driverURL ))
373+ continue
374+ }
375+ body , err = io .ReadAll (resp .Body )
376+ if err != nil {
377+ e = multierror .Join (e , fmt .Errorf ("could not read response body: %w" , err ))
378+ continue
379+ }
380+ return body , nil
381+ }
382+ return nil , e
383+ }
0 commit comments