Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 14523] ファイルの概要

このコミットは、Go言語のコードレビューツールであるRietveldとの連携において、HTTPからHTTPSへのプロトコル変更に対応するための修正です。具体的には、RietveldサーバーがHTTPS接続を必須とするようになったため、クライアント側のcodereview.pyスクリプト内のURLスキームをHTTPからHTTPSへ、または両方を許容するように変更しています。

コミット

  • コミットハッシュ: 372cf8fe87de7a49818de2157429ccbc76c35c2d
  • Author: Brad Fitzpatrick bradfitz@golang.org
  • Date: Thu Nov 29 11:19:55 2012 -0800

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/372cf8fe87de7a49818de2157429ccbc76c35c2d

元コミット内容

codereview: always use HTTPS

The new version of rietveld pushed 1.5 hours ago
requires HTTPS now, otherwise it issues a 301
to HTTPS which we barfed on.

R=golang-dev
CC=golang-dev
https://golang.org/cl/6782135

変更の背景

このコミットが行われた背景には、Go言語のコードレビューシステムとして利用されていたRietveld(codereview.appspot.com)のサーバー側の変更があります。コミットメッセージによると、コミットの約1.5時間前にデプロイされたRietveldの新しいバージョンが、HTTPS接続を必須とするようになりました。

以前はHTTPでアクセス可能だったRietveldに対して、クライアント側のcodereview.pyスクリプトがHTTPでリクエストを送信していました。しかし、RietveldサーバーがHTTPSを必須としたことで、HTTPリクエストに対してはHTTP 301 (Moved Permanently) ステータスコードを返し、HTTPSへのリダイレクトを指示するようになりました。

この301リダイレクトが、codereview.pyスクリプト内で適切に処理されず、エラー("barfed on")を引き起こしていたため、コードレビュープロセスが中断される問題が発生しました。この問題を解決するため、クライアント側でRietveldへのアクセスを常にHTTPSで行うように、またはHTTPSも許容するようにコードを修正する必要が生じました。

前提知識の解説

Rietveld

Rietveldは、Googleによって開発されたオープンソースのコードレビューツールです。Pythonで書かれており、Google App Engine上で動作するように設計されています。元々はGoogleの内部コードレビューシステムであるMondrianをベースにしており、特にPerforceやGit、Mercurialといったバージョン管理システムと連携して、差分表示、コメント、承認などのコードレビュー機能を提供します。Go言語プロジェクトでは、初期の頃からこのRietveldがコードレビューに利用されていました。

HTTPS (Hypertext Transfer Protocol Secure)

HTTPSは、HTTPプロトコルにSSL/TLSプロトコルを組み合わせることで、通信のセキュリティを強化したものです。主な目的は以下の通りです。

  1. 暗号化: クライアントとサーバー間の通信内容を暗号化し、第三者による盗聴を防ぎます。
  2. データ整合性: 送信中にデータが改ざんされていないことを保証します。
  3. 認証: 接続先のサーバーが正当なものであることを証明し、中間者攻撃を防ぎます。

WebサイトがHTTPSを導入する主な理由は、ユーザーのプライバシー保護、データのセキュリティ確保、そして検索エンジン最適化(SEO)の観点からも推奨されるためです。

HTTP 301 (Moved Permanently) リダイレクト

HTTP 301ステータスコードは、リクエストされたリソースが恒久的に新しいURIに移動したことを示すレスポンスです。サーバーがこのステータスコードを返すと、クライアント(ウェブブラウザやスクリプトなど)は、その後の同じリソースへのリクエストを新しいURIに対して行うべきであると解釈します。

今回のケースでは、RietveldサーバーがHTTPリクエストを受け取った際に、そのリクエストをHTTPS版のURIにリダイレクトするために301を返していました。通常、ウェブブラウザはこのようなリダイレクトを自動的に追跡しますが、codereview.pyのようなスクリプトでは、リダイレクトの自動追跡が実装されていないか、または特定のリダイレクト処理に問題があった可能性があります。その結果、スクリプトが予期しないレスポンスを受け取り、処理を中断してしまっていたと考えられます。

技術的詳細

このコミットの技術的な変更は、主にlib/codereview/codereview.pyファイル内のURLスキームの指定方法に集中しています。

  1. 正規表現の変更:

    • re.findall関数で使用されている正規表現パターンが変更されました。
    • 変更前: ^http://codereview.appspot.com/([0-9]+)$
    • 変更後: ^https?://codereview.appspot.com/([0-9]+)$
    • この変更により、http://だけでなくhttps://で始まるURLもマッチするようになります。s?sが0回または1回出現することを意味し、HTTPとHTTPSの両方を許容します。これは、コミットメッセージの「always use HTTPS」という意図とは少し異なり、より柔軟な対応を示唆しています。ただし、後述のURL生成部分では明示的にHTTPSを使用するように変更されています。
  2. URL生成部分の変更:

    • changeURLurlを構築する際に、明示的にhttp://https://に置き換えています。
    • http://code.google.com/p/%s/... のようなURLが https://code.google.com/p/%s/... に変更されています。
    • url = "http://%s%s" % (self.host, request_path) のような箇所が url = "https://%s%s" % (self.host, request_path) に変更されています。
    • これは、Rietveldサーバーへのリクエストだけでなく、Google Codeのソースリポジトリへのリンク生成や、認証関連のURL生成においてもHTTPSを強制する変更です。

これらの変更により、codereview.pyスクリプトはRietveldおよび関連サービスとの通信をHTTPS経由で行うようになり、サーバー側のプロトコル変更に起因する問題を回避できるようになりました。

コアとなるコードの変更箇所

--- a/lib/codereview/codereview.py
+++ b/lib/codereview/codereview.py
@@ -1471,7 +1471,7 @@ def rev2clname(rev):
 	# Extract CL name from revision description.
 	# The last line in the description that is a codereview URL is the real one.
 	# Earlier lines might be part of the user-written description.
-\tall = re.findall(\'(?m)^http://codereview.appspot.com/([0-9]+)$\', rev.description())\n+\tall = re.findall(\'(?m)^https?://codereview.appspot.com/([0-9]+)$\', rev.description())\n \tif len(all) > 0:\n \t\treturn all[-1]\n \treturn \"\"\n@@ -1969,11 +1969,11 @@ def submit(ui, repo, *pats, **opts):\n \t\t\"(^https?://([^@/]+@)?code\\.google\\.com/p/([^/.]+)(\\.[^./]+)?/?)\", url)\n \tif m:\n \t\tif m.group(1): # prj.googlecode.com/hg/ case\n-\t\t\tchangeURL = \"http://code.google.com/p/%s/source/detail?r=%s\" % (m.group(3), changeURL)\n+\t\t\tchangeURL = \"https://code.google.com/p/%s/source/detail?r=%s\" % (m.group(3), changeURL)\n \t\telif m.group(4) and m.group(7): # code.google.com/p/prj.subrepo/ case\n-\t\t\tchangeURL = \"http://code.google.com/p/%s/source/detail?r=%s&repo=%s\" % (m.group(6), changeURL, m.group(7)[1:])\n+\t\t\tchangeURL = \"https://code.google.com/p/%s/source/detail?r=%s&repo=%s\" % (m.group(6), changeURL, m.group(7)[1:])\n \t\telif m.group(4): # code.google.com/p/prj/ case\n-\t\t\tchangeURL = \"http://code.google.com/p/%s/source/detail?r=%s\" % (m.group(6), changeURL)\n+\t\t\tchangeURL = \"https://code.google.com/p/%s/source/detail?r=%s\" % (m.group(6), changeURL)\n \t\telse:\n \t\t\tprint >>sys.stderr, \"URL: \", url\n \telse:\n@@ -2021,7 +2021,7 @@ def sync_changes(ui, repo):\n \t# Double-check them by looking at the Rietveld log.\n \tfor rev in hg_log(ui, repo, limit=100, template=\"{node}\\n\").split():\n \t\tdesc = repo[rev].description().strip()\n-\t\tfor clname in re.findall(\'(?m)^http://(?:[^\\n]+)/([0-9]+)$\', desc):\n+\t\tfor clname in re.findall(\'(?m)^https?://(?:[^\\n]+)/([0-9]+)$\', desc):\n \t\t\tif IsLocalCL(ui, repo, clname) and IsRietveldSubmitted(ui, clname, repo[rev].hex()):\n \t\t\t\tui.warn(\"CL %s submitted as %s; closing\\n\" % (clname, repo[rev]))\n \t\t\t\tcl, err = LoadCL(ui, repo, clname, web=False)\n@@ -2452,7 +2452,7 @@ def MySend1(request_path, payload=None,\n \t\twhile True:\n \t\t\ttries += 1\n \t\t\targs = dict(kwargs)\n-\t\t\turl = \"http://%s%s\" % (self.host, request_path)\n+\t\t\turl = \"https://%s%s\" % (self.host, request_path)\n \t\t\tif args:\n \t\t\t\turl += \"?\" + urllib.urlencode(args)\n \t\t\treq = self._CreateRequest(url=url, data=payload)\n@@ -2564,7 +2564,7 @@ def RietveldSetup(ui, repo):\n \tif x is not None:\n \t\temail = x\n \n-\tserver_url_base = \"http://\" + server + \"/\"\n+\tserver_url_base = \"https://\" + server + \"/\"\n \n \ttesting = ui.config(\"codereview\", \"testing\")\n \tforce_google_account = ui.configbool(\"codereview\", \"force_google_account\", False)\n@@ -2844,7 +2844,7 @@ class AbstractRpcServer(object):\n \t\t# This is a dummy value to allow us to identify when we\'re successful.\n \t\tcontinue_location = \"http://localhost/\"\n \t\targs = {\"continue\": continue_location, \"auth\": auth_token}\n-\t\treq = self._CreateRequest(\"http://%s/_ah/login?%s\" % (self.host, urllib.urlencode(args)))\n+\t\treq = self._CreateRequest(\"https://%s/_ah/login?%s\" % (self.host, urllib.urlencode(args)))\n \t\ttry:\n \t\t\tresponse = self.opener.open(req)\n \t\texcept urllib2.HTTPError, e:\n@@ -2934,7 +2934,7 @@ class AbstractRpcServer(object):\n \t\t\twhile True:\n \t\t\t\ttries += 1\n \t\t\t\targs = dict(kwargs)\n-\t\t\t\turl = \"http://%s%s\" % (self.host, request_path)\n+\t\t\t\turl = \"https://%s%s\" % (self.host, request_path)\n \t\t\t\tif args:\n \t\t\t\t\turl += \"?\" + urllib.urlencode(args)\n \t\t\t\treq = self._CreateRequest(url=url, data=payload)\n```

## コアとなるコードの解説

上記の差分は、`lib/codereview/codereview.py`ファイル内の複数の箇所で、URLのプロトコル指定を`http`から`https`へ、または正規表現で`https?`(httpまたはhttps)を許容するように変更していることを示しています。

1.  **`rev2clname` 関数内 (`@@ -1471,7 +1471,7 @@`)**:
    *   この関数は、リビジョン記述からコードレビュー(CL)の名前(ID)を抽出するために使用されます。
    *   変更前は`http://codereview.appspot.com/`で始まるURLのみを正規表現で検索していましたが、変更後は`https?://codereview.appspot.com/`となり、HTTPとHTTPSの両方のスキームに対応できるようになりました。これにより、既存のHTTPリンクと新しいHTTPSリンクの両方からCL名を正しく抽出できます。

2.  **`submit` 関数内 (`@@ -1969,11 +1969,11 @@`)**:
    *   この関数は、変更を提出する際に関連するURLを構築するために使用されます。
    *   `code.google.com/p/`に関連する`changeURL`の生成において、明示的に`http://`を`https://`に置き換えています。これは、Google CodeのソースリポジトリへのリンクもHTTPSを使用するように変更されたことを示唆しています。

3.  **`sync_changes` 関数内 (`@@ -2021,7 +2021,7 @@`)**:
    *   この関数は、Rietveldのログを調べて変更を同期する際に使用されます。
    *   ここでも`re.findall`の正規表現が変更され、`^http://(?:[^\\n]+)/([0-9]+)$`から`^https?://(?:[^\\n]+)/([0-9]+)$`となり、HTTPとHTTPSの両方のURLを認識できるようになりました。

4.  **`MySend1` 関数内 (`@@ -2452,7 +2452,7 @@`)**:
    *   この関数は、Rietveldサーバーへのリクエストを送信する際の基盤となる部分です。
    *   `url = "http://%s%s" % (self.host, request_path)` の行が `url = "https://%s%s" % (self.host, request_path)` に変更されています。これにより、Rietveldサーバーへのすべての通信が強制的にHTTPS経由で行われるようになります。これがコミットメッセージの「always use HTTPS」の主要な実装箇所です。

5.  **`RietveldSetup` 関数内 (`@@ -2564,7 +2564,7 @@`)**:
    *   Rietveldのセットアップに関連する部分で、`server_url_base`の生成において`http://`が`https://`に置き換えられています。

6.  **`AbstractRpcServer` クラス内のメソッド (`@@ -2844,7 +2844,7 @@` および `@@ -2934,7 +2934,7 @@`)**:
    *   RPCサーバーの抽象クラス内で、認証ログインURLや一般的なリクエストURLを生成する際に、`http://`が`https://`に置き換えられています。これにより、RPC通信もHTTPS経由で行われるようになります。

これらの変更は、`codereview.py`がRietveldおよび関連するGoogleサービスとの通信において、セキュリティを強化し、サーバー側のプロトコル変更に適切に対応するための重要な修正です。

## 関連リンク

*   [https://golang.org/cl/6782135](https://golang.org/cl/6782135)

## 参考にした情報源リンク

*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFrT81zBuSObuj1OqQOhV9-FaCP2EKUt-lOcnjJhkUJudMLW3CKFMqGsf3jvvBch7e01ZrbKsPoRMCWPpjmyEEBkhWspcUEG-M2NqeolOOZxtUb-oFoS0Y6u690IFdKRsdHlWapvduer2DxFmfaR-ubDNp7uMXXn8qGViZLNKN5az_9YImTlGjBXBocTQFlGCW_dtSaqJ_Em6iZVdl2y50M4c_3mmkkAPdUg0v49R9NXKqFsb0hplg=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFrT81zBuSObuj1OqQOhV9-FaCP2EKUt-lOcnjJhkUJudMLW3CKFMqGsf3jvvBch7e01ZrbKsPoRMCWPpjmyEEBkhWspcUEG-M2NqeolOOZxtUb-oFoS0Y6u690IFdKRsdHlWapvduer2DxFmfaR-ubDNp7uMXXn8qGViZLNKN5az_9YImTlGjBXBocTQFlGCW_dtSaqJ_Em6iZVdl2y50M4c_3mmkkAPdUg0v49R9NXKqFsb0hplg=)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEZ1uwnOdagVCn4abkYd7mk5tqBKAuglp5I-aC3lMiJPiITrJEM8BFmvwtQiDthIblDsggKo06fkrl--3VNu0O51boj33k-YX6pklU8-KnbtOsdXY6N0ma_YpOkouWLDEKj_IUGeEpyTHl-OIbSmHG9FyFwS8ZWnOte57cdtW_BPB-hnjaBnw==](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEZ1uwnOdagVCn4abkYd7mk5tqBKAuglp5I-aC3lMiJPiITrJEM8BFmvwtQiDthIblDsggKo06fkrl--3VNu0O51boj33k-YX6pklU8-KnbtOsdXY6N0ma_YpOkouWLDEKj_IUGeEpyTHl-OIbSmHG9FyFwS8ZWnOte57cdtW_BPB-hnjaBnw==)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQER2SYLSA0qbtg6DpttBoANSp2--8uKltWwGvq1c2qDOyqMwCHywPUV_o4-046C47nS0uwmIXKWkmT96-3x4r_pEN_W9kJp5CHsy4FUc7ruidFSZKwJ9LetcXn4ZwF_y6ojC1AuW1o1z9TMVPw4FnNlsi1XsSg_wIVCs1HHeojhAgekw==](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQER2SYLSA0qbtg6DpttBoANSp2--8uKltWwGvq1c2qDOyqMwCHywPUV_o4-046C47nS0uwmIXKWkmT96-3x4r_pEN_W9kJp5CHsy4FUc7ruidFSZKwJ9LetcXn4ZwF_y6ojC1AuW1o1z9TMVPw4FnNlsi1XsSg_wIVCs1HHeojhAgekw==)