LoginSignup
1
0

【Golang】リダイレクトされた最終的な URL を取得する【Go 1.20】

Last updated at Posted at 2023-05-15

Go 言語(以下 golang)で URL をリクエストした際の最終的にリダイレクトされる先の URL が知りたい

例えば、GitHub の Gist や Qiita で ID だけを指定してリクエストすると、コンテンツ・オーナーのユーザー名を付けた URL にリダイレクトされます。

- https://gist.github.com/42f5f23053ab59ca480f480b8d01e1fd
+ https://gist.github.com/KEINOS/42f5f23053ab59ca480f480b8d01e1fd

- https://qiita.com/items/6f3bbc7f4682887c0b89
+ https://qiita.com/KEINOS/items/6f3bbc7f4682887c0b89
リクエスト例
$ # リダイレクト先に /KEINOS が付加されている

$ # Gist@GitHub
$ curl -Ls -o /dev/null -w %{url_effective} https://gist.github.com/42f5f23053ab59ca480f480b8d01e1fd
https://gist.github.com/KEINOS/42f5f23053ab59ca480f480b8d01e1fd

$ # Items@Qiita
$ curl -Ls -o /dev/null -w %{url_effective} https://qiita.com/items/6f3bbc7f4682887c0b89
https://qiita.com/KEINOS/items/6f3bbc7f4682887c0b89

コンテンツもサルことながら、単純に golang で、この URL を取得したいのです。

「"golang" リダイレクト 最終 URL 取得」でググっても、ソースが動かなかったり、HEAD メソッドを受け付けてないエラーが出たりしたので、自分のググラビリティとして。

TL; DR (今北産業)

import (
	"net/http"
	"time"
)

// FindRedirectURL はリダイレクトされた最終的な URL を返します。15 秒経過してもレスポンスが
// ない場合はタイムアウトでエラーを返します。
func FindRedirectURL(url string) (string, error) {
	client := &http.Client{
		Timeout: 15 * time.Second,
	}

	resp, err := client.Get(url)
	if err != nil {
		return "", err
	}

	finalURL := resp.Request.URL.String()

	return finalURL, nil
}
ヘッダー情報だけで判断したい場合(軽量版)
import (
	"net/http"
	"time"
)

// FindRedirectURL はリダイレクトされた最終的な URL を返します。15 秒経過してもレスポンスが
// ない場合はタイムアウトでエラーを返します。
func FindRedirectURL(url string) (string, error) {
	client := &http.Client{
		Timeout: 15 * time.Second,
	}

-	resp, err := client.Get(url)
+	resp, err := client.Head(url)
	if err != nil {
		return "", err
	}

	finalURL := resp.Request.URL.String()

	return finalURL, nil
}
example.go
package main

import (
	"fmt"
	"log"
	"net/http"
	"time"
)

func FindRedirectURL(url string) (string, error) {
	client := &http.Client{
		Timeout: 15 * time.Second,
	}

	resp, err := client.Head(url)
	if err != nil {
		return "", err
	}

	finalURL := resp.Request.URL.String()

	return finalURL, nil
}

func main() {
    urlOriginal := "https://gist.github.com/42f5f23053ab59ca480f480b8d01e1fd"
    
    fmt.Println("Original:", urlOriginal)
    
	urlRedirect, err := FindRedirectURL(urlOriginal)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Redirect:", urlRedirect)
    // Output:
    // Original: https://gist.github.com/42f5f23053ab59ca480f480b8d01e1fd
    // Redirect: https://gist.github.com/KEINOS/42f5f23053ab59ca480f480b8d01e1fd
}
検証環境
$ date
2023年 5月15日 月曜日 12時26分29秒 JST

$ go version
go version go1.20.4 darwin/amd64

$ sw_vers
ProductName:	macOS
ProductVersion:	12.6.5
BuildVersion:	21G531
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0