| | @@ -409,33 +409,22 @@ |
| 409 | 409 | $request .= "{$accept}\r\n"; |
| 410 | 410 | $request .= "Connection: close\r\n"; |
| 411 | 411 | |
| 412 | + // 認証ヘッダー |
| 412 | 413 | if (!empty($authHeader)) { |
| 413 | 414 | $request .= $authHeader; |
| 414 | 415 | } |
| 415 | 416 | |
| 416 | 417 | // ヘッダーを追加 |
| 417 | | - foreach ($this->headers as $name => $value) { |
| 418 | | - $request .= "{$name}: {$value}\r\n"; |
| 418 | + $ext = $this->buildHeaderString(); |
| 419 | + if (!empty($ext)) { |
| 420 | + $request .= $ext; |
| 419 | 421 | } |
| 420 | 422 | |
| 421 | | - // リファラーが設定されていれば追加 |
| 422 | | - if (!empty($this->referer) && !isset($this->headers['Referer'])) { |
| 423 | | - $request .= "Referer: {$this->referer}\r\n"; |
| 424 | | - } |
| 425 | | - |
| 426 | | - // クッキーヘッダーを追加 |
| 427 | | - if (!empty($this->cookies) && !isset($this->headers['Cookie'])) { |
| 428 | | - $cookieStrings = []; |
| 429 | | - foreach ($this->cookies as $name => $value) { |
| 430 | | - $cookieStrings[] = $name.'='.urlencode($value); |
| 431 | | - } |
| 432 | | - $request .= 'Cookie: '.implode('; ', $cookieStrings)."\r\n"; |
| 433 | | - } |
| 434 | | - |
| 423 | + // ヘッダー終了 |
| 435 | 424 | $request .= "\r\n"; |
| 436 | 425 | |
| 437 | 426 | // POSTデータを追加 |
| 438 | | - if ($method === 'POST' || $method === 'PUT') { |
| 427 | + if ($httpData !== '') { |
| 439 | 428 | $request .= $httpData; |
| 440 | 429 | } |
| 441 | 430 | |
| | @@ -507,6 +496,7 @@ |
| 507 | 496 | // ヘッダーを解析 |
| 508 | 497 | $this->responseHeaders = []; |
| 509 | 498 | $this->responseCode = 0; |
| 499 | + $redirectUrl = ''; |
| 510 | 500 | |
| 511 | 501 | foreach ($headerLines as $index => $header) { |
| 512 | 502 | if ($index === 0) { |
| | @@ -520,6 +510,8 @@ |
| 520 | 510 | $name = trim($name); |
| 521 | 511 | $value = trim($value); |
| 522 | 512 | $this->responseHeaders[$name] = $value; |
| 513 | + |
| 514 | + $redirectUrl = $this->checkReds($name, $value, $currentUrl); |
| 523 | 515 | } |
| 524 | 516 | } |
| 525 | 517 | |
| | @@ -541,20 +533,23 @@ |
| 541 | 533 | } |
| 542 | 534 | |
| 543 | 535 | // リダイレクトが必要な場合 |
| 544 | | - if (!empty($redirectUrl) && $redirectCount < $this->maxRedirects) { |
| 536 | + if ($redirectUrl !== '' && $redirectCount < $this->maxRedirects) { |
| 545 | 537 | $currentUrl = $redirectUrl; |
| 546 | 538 | $redirectCount++; |
| 547 | 539 | $this->info['redirect_count'] = $redirectCount; |
| 540 | + $this->info['redirect_url'] = $redirectUrl; |
| 548 | 541 | |
| 549 | 542 | // 302や303リダイレクトはGETにメソッドを変更 |
| 550 | | - if ($this->responseCode == 302 || $this->responseCode == 303) { |
| 543 | + if (in_array($this->responseCode, [302, 303], true)) { |
| 551 | 544 | $this->method = 'GET'; |
| 552 | 545 | $this->postRaw = ''; |
| 553 | 546 | $this->postFields = []; |
| 554 | 547 | } |
| 555 | | - } else { |
| 556 | | - break; |
| 548 | + |
| 549 | + continue; |
| 557 | 550 | } |
| 551 | + |
| 552 | + break; |
| 558 | 553 | } while (true); |
| 559 | 554 | |
| 560 | 555 | // リクエスト完了後、元のメソッドに戻す |
| | @@ -629,22 +624,20 @@ |
| 629 | 624 | * @return string リダイレクトURL、リダイレクトがない場合は空文字 |
| 630 | 625 | */ |
| 631 | 626 | private function checkReds(string $name, string $value, string $currentUrl): string { |
| 632 | | - $redirectUrl = ''; |
| 627 | + if (!$this->followRedirects) return ''; |
| 628 | + if (strtolower($name) !== 'location') return ''; |
| 629 | + if ($this->responseCode < 300 || $this->responseCode >= 400) return ''; |
| 630 | + $redirectUrl = $value; |
| 633 | 631 | |
| 634 | | - if ($this->followRedirects && (strtolower($name) === 'location' |
| 635 | | - && $this->responseCode >= 300 && $this->responseCode < 400)) { |
| 636 | | - $redirectUrl = $value; |
| 637 | | - |
| 638 | | - if (strpos($redirectUrl, 'http') !== 0) { |
| 639 | | - if ($redirectUrl[0] === '/') { |
| 640 | | - $uri = new Uri($currentUrl); |
| 641 | | - $redirectUrl = $uri->getScheme().'://'.$uri->getHost() |
| 642 | | - .(NULL !== $uri->getPort() ? ':'.$uri->getPort() : '') |
| 643 | | - .$redirectUrl; |
| 644 | | - } else { |
| 645 | | - $redirectUrl = dirname($currentUrl).'/'.$redirectUrl; |
| 646 | | - } |
| 647 | | - } |
| 632 | + if (strpos($redirectUrl, 'http') !== 0) { |
| 633 | + if ($redirectUrl[0] === '/') { |
| 634 | + $uri = new Uri($currentUrl); |
| 635 | + $redirectUrl = $uri->getScheme().'://'.$uri->getHost() |
| 636 | + .(NULL !== $uri->getPort() ? ':'.$uri->getPort() : '') |
| 637 | + .$redirectUrl; |
| 638 | + } else { |
| 639 | + $redirectUrl = dirname($currentUrl).'/'.$redirectUrl; |
| 640 | + } |
| 648 | 641 | } |
| 649 | 642 | |
| 650 | 643 | return $redirectUrl; |
| | @@ -656,16 +649,16 @@ |
| 656 | 649 | * @return string 構築されたヘッダー文字列 |
| 657 | 650 | */ |
| 658 | 651 | private function buildHeaderString(): string { |
| 659 | | - $headers = []; |
| 652 | + $request = ''; |
| 660 | 653 | |
| 661 | 654 | // ユーザー指定のヘッダーを追加 |
| 662 | 655 | foreach ($this->headers as $name => $value) { |
| 663 | | - $headers[] = "{$name}: {$value}"; |
| 656 | + $request .= "{$name}: {$value}\r\n"; |
| 664 | 657 | } |
| 665 | 658 | |
| 666 | 659 | // リファラーが設定されていれば追加 |
| 667 | 660 | if (!empty($this->referer) && !isset($this->headers['Referer'])) { |
| 668 | | - $headers[] = "Referer: {$this->referer}"; |
| 661 | + $request .= "Referer: {$this->referer}\r\n"; |
| 669 | 662 | } |
| 670 | 663 | |
| 671 | 664 | // 必要に応じてクッキーヘッダーを追加 |
| | @@ -675,10 +668,10 @@ |
| 675 | 668 | $cookieStrings[] = $name.'='.urlencode($value); |
| 676 | 669 | } |
| 677 | 670 | |
| 678 | | - $headers[] = 'Cookie: '.implode('; ', $cookieStrings); |
| 671 | + $request .= 'Cookie: '.implode('; ', $cookieStrings)."\r\n"; |
| 679 | 672 | } |
| 680 | 673 | |
| 681 | | - return implode("\r\n", $headers)."\r\n"; |
| 674 | + return $request; |
| 682 | 675 | } |
| 683 | 676 | |
| 684 | 677 | /** |