|
79 | 79 | $TIP = 1; |
80 | 80 | } |
81 | 81 |
|
82 | | -my $HTTP = HTTP::Tiny::->new; |
83 | 82 |
|
84 | 83 | # 1.12.3 -> (1.12.3, undef) |
85 | 84 | # 1.15.x -> (1.15, 4) |
@@ -114,7 +113,7 @@ sub resolve_target |
114 | 113 | } |
115 | 114 | $vreg = qr/^go$vreg\z/; |
116 | 115 |
|
117 | | - my $r = $HTTP->get('https://go.googlesource.com/go/+refs/tags?format=JSON'); |
| 116 | + my $r = http_get('https://go.googlesource.com/go/+refs/tags?format=JSON'); |
118 | 117 | $r->{success} or die "Cannot retrieve tags: $r->{status} $r->{reason}\n$r->{content}\n"; |
119 | 118 |
|
120 | 119 | my $found; |
@@ -182,7 +181,7 @@ sub get_url |
182 | 181 | $full .= ".$last_minor" if defined $last_minor; |
183 | 182 |
|
184 | 183 | say "Check https://golang.org/dl/go$full.$OS-$ARCH.$EXT"; |
185 | | - my $r = $HTTP->head("https://golang.org/dl/go$full.$OS-$ARCH.$EXT"); |
| 184 | + my $r = http_head("https://golang.org/dl/go$full.$OS-$ARCH.$EXT"); |
186 | 185 | return ($r->{url}, $full) if $r->{success}; |
187 | 186 | say "=> $r->{status}"; |
188 | 187 |
|
@@ -289,3 +288,94 @@ sub mkdir_p |
289 | 288 |
|
290 | 289 | mkdir $dir or d $dir or die "Cannot create $dir: $!\n"; |
291 | 290 | } |
| 291 | + |
| 292 | +my $use_curl; |
| 293 | + |
| 294 | +sub http_get |
| 295 | +{ |
| 296 | + my $url = shift; |
| 297 | + |
| 298 | + if ($use_curl) |
| 299 | + { |
| 300 | + my %r; |
| 301 | + open(my $fh, '-|', curl => -sLD => '/dev/fd/1', $url) |
| 302 | + or die "Cannot fork: $!\n"; |
| 303 | + |
| 304 | + for (;;) |
| 305 | + { |
| 306 | + my $status_line = <$fh>; |
| 307 | + unless (defined $status_line) |
| 308 | + { |
| 309 | + return { |
| 310 | + status => 599, |
| 311 | + reason => 'EOF', |
| 312 | + content => '', |
| 313 | + }; |
| 314 | + } |
| 315 | + |
| 316 | + (undef, $r{status}, $r{reason}) = split(' ', $status_line, 3); |
| 317 | + $r{success} = $r{status} < 400; |
| 318 | + |
| 319 | + # Consume headers |
| 320 | + { local $/ = "\r\n\r\n"; <$fh> } |
| 321 | + |
| 322 | + # Redirect -> new header |
| 323 | + last if $r{status} != 302 and $r{status} != 307; |
| 324 | + } |
| 325 | + |
| 326 | + local $/; |
| 327 | + $r{content} = <$fh>; |
| 328 | + close $fh; |
| 329 | + return \%r; |
| 330 | + } |
| 331 | + |
| 332 | + my $r = HTTP::Tiny::->new->get($url); |
| 333 | + if (not $r->{success} |
| 334 | + and $r->{status} == 599 |
| 335 | + and $r->{content} =~ /must be installed for https support/) |
| 336 | + { |
| 337 | + $use_curl = 1; |
| 338 | + return http_get($url) |
| 339 | + } |
| 340 | + return $r; |
| 341 | +} |
| 342 | + |
| 343 | +sub http_head |
| 344 | +{ |
| 345 | + my $url = shift; |
| 346 | + |
| 347 | + if ($use_curl) |
| 348 | + { |
| 349 | + my %r = (url => $url); |
| 350 | + open(my $fh, '-|', curl => '--head' => -sL => $url) |
| 351 | + or die "Cannot fork: $!\n"; |
| 352 | + |
| 353 | + for (;;) |
| 354 | + { |
| 355 | + my $status_line = <$fh>; |
| 356 | + unless (defined $status_line) |
| 357 | + { |
| 358 | + return { |
| 359 | + status => 599, |
| 360 | + reason => 'EOF', |
| 361 | + content => '', |
| 362 | + }; |
| 363 | + } |
| 364 | + |
| 365 | + (undef, $r{status}, $r{reason}) = split(' ', $status_line, 3); |
| 366 | + $r{success} = $r{status} < 400; |
| 367 | + |
| 368 | + # Redirect -> new header |
| 369 | + last if $r{status} != 302 and $r{status} != 307; |
| 370 | + |
| 371 | + # Consume headers and catch location header |
| 372 | + local $/ = "\r\n\r\n"; |
| 373 | + $r{url} = $1 if <$fh> =~ /^location:\s*([^\r\n]+)/mi; |
| 374 | + } |
| 375 | + |
| 376 | + close $fh; |
| 377 | + return \%r; |
| 378 | + } |
| 379 | + |
| 380 | + return HTTP::Tiny::->new->head($url); |
| 381 | +} |
0 commit comments