トリビア:Google+アカウントにアップデートするときは気をつけないと全データが全部飛ぶ

Posted on

 泣きたい

 GoogleのGoogle+へのプッシュ具合は最近すごいですよね。今までほとんどGoogle+はつかっていなかったのですが、最近必要にせまられたので登録してみました。

 Google+ができてしばらくたってからのアカウントでは、gmailのアカウントでもPicasaのアカウントでも登録時にGoogle+にも一緒に登録することが必要になっていますが、比較的昔から使っているアカウントの場合には、Google+へ追加で登録を行う(Google曰く「アップデート」)ことになっています。

 今回、ふるいgmailアカウントをGoogle+にアップデートしようとしたら悲しい自体になったので周知徹底等させて頂きたく存じ上げます(敬語)

 Google+の登録時の画面で、性別と年齢を入れるわけですが…

20120711_01.png

 はまちちゃんも実名だけはやめとくよう言うし、私も実際その通りだと思うので、年齢も性別も毎度適当に入れています。で、今回は歌詞になってて覚えやすい鉄腕アトムの誕生日を入れて登録してみたのですが…

20120711_02.png

 …ん?

 20120711_03.png

 なん…だと…10年間分のメール…が…

 どうやら13歳以上じゃないと使えない、ということらしいです。小学生はgmailを使ってお友達とメールすることができないらしい!です。うーん、リアル小学生のときyahoo!mailもhotmailも取ったような気がするのですが…。Google先生は厳しいですね。Google社内にスーパー小学生エンジニアとか居ないのかしらん(ぉ

 Googleに身分証明書を送付するなどすれば解除と削除回避は可能だそうですが、Googleにそこまで個人情報を教える気にはどうしてもなれませんし、そもそも偽名だし…であきらめるしかなさそうです。規約上たぶん本名を入れることになってると思うので、私の自業自得ではあるのですが…悲しい。

 そういえば上の画像だと「波動関数 ぷさい」ですが、最初これははじかれました。Google+の命名ルールに従っていない、もっというと「本名じゃないでしょそれ」と言われてしまいました。でも昨今の「DQNネーム」とやらを見てると、これぐらい変わった名前の人がいてもおかしくないと思うのだけど…Googleに身分証明書送らないとアカウント作らせて貰えないのかな??そこまでしてやるもんんかなあ?

 ファーストサーバの中の人の気持ちがわかった気がします


HTTP1.1のLocationヘッダは、絶対URLでないとRFC違反

Posted on

さきゅばす2のバグ対処で知ったお話です。とりあえず、HTTPの基礎知識はあることを前提にします。

さきゅばす2では、公式動画のDLがどうしても出来ませんでした。こんなエラーが出ちゃうんです。

[E][    PyBridgeImpl] Python says:
(略)
HTTPError: HTTP Error 302: Found - Redirection to url '/watch/1339405721' is not allowed

どうやらリダイレクションの段階で問題が発生してるみたいですねぇ。

HTTPでのリダイレクション

とあるページにアクセスした時に他のページにジャンプしなおさせる「リダイレクション」ですが、このリダレクションはHTTPはレスポンスヘッダで301,302,303,307のレスポンスコードを返した上で、Locationヘッダを設定することで実現しています。

どこかのページのレスポンスヘッダで、

Location: http://www.google.com/

こういうふうなヘッダを返すと、そのページにアクセスした人がGoogleに無条件で飛ばされるわけですね。

で、ニコニコ動画のリダイレクションでは、

Location: /watch/1339405721

となっていて、http://www.nicovideo.jp/watch/1339405721 にジャンプするようになっていました。うーん、特に問題なさそう。

Locationヘッダは絶対パスしか認められない。

…ところがどっこい、実はLocationヘッダのURLは絶対パスしか認められないのです。RFC見ましょうか。

Location       = "Location" ":" absoluteURI

で、このabsoluteURIはRFC2396: Uniform Resource Identifiers (URI): Generic Syntaxで定義されておりまして、

absoluteURI   = scheme ":" ( hier_part | opaque_part )

ということで、URIスキーム(httpとかftpとか)から始まる絶対URIであることがわかります。

とはいえ、色々調べてみると、携帯とか一部のブラウザを除くと大体相対パスでも動くそうで、絶対URIを作成時に予測するのが難しい、他人に配布するスクリプトなどでは相対パスで指定していることが多いそうです。

 

ニコニコ動画の場合は絶対URIでも良いと思うのですが今回は相対パスで指定されていて、ふつうのブラウザなどではこれで意図通りに動くのですが、さきゅばす2のPythonでは最近のバージョンまで相対パスに対応していなかったため問題になったようです。で、最新のバージョンでは相対パスに対応しているので、配布バイナリを最新バージョンに差し替えることにしました。

で、ほかのヘッダではどうなってるの?

HTTPのヘッダには、ほかにもいくつかパスを指定できるものがありましたよね。いくつか調べてみました。

Request-URI

リクエストURIは、GET ****** HTTP/1.1みたいな形式で指定されるときの、あのURIです。

Request-URI    = "*" | absoluteURI | abs_path | authority

なんと…。実は絶対URI指定でも良いのですね。たまに絶対URIでのリクエストがこのサーバに飛んでくるのですが、てっきり不正なリクエストなんだと思ってました。…とはいえ、ほとんどのクライアントは絶対パスで取得するのがふつうなので、ちょっと警戒すべきだとは思いますけど…。

 

Content-Location:

Locationと似てますが別物です。リクエストされたコンテンツが別のところからも取得可能な時に使われる…そうですが、実際使われてるのを見たことがありません…。だれか教えて(ぇ

Content-Location = "Content-Location" ":"
( absoluteURI | relativeURI )

こっちは相対URIも可能です。同じサーバであることが自然だからなのかなあ。

Referer

リファラです。ほかのページのリンクなどをたどって来たことを示すわけですが…

Referer        = "Referer" ":" ( absoluteURI | relativeURI )

なんと!これも相対URIはOKでした。とはいえ、世の中のクライアントは大体絶対URIじゃないでしょうか?

以上です。たまにはRFC読んでみると意外な発見がいろいろありますね。

追記:RFC7321では相対URLが認められている

その後2012に出たRFC7231では相対URLもOKになりました。以下、引用です:

7.1.2. Location

   The "Location" header field is used in some responses to refer to a
   specific resource in relation to the response.  The type of
   relationship is defined by the combination of request method and
   status code semantics.

     Location = URI-reference

   The field value consists of a single URI-reference.  When it has the
   form of a relative reference ([RFC3986], Section 4.2), the final
   value is computed by resolving it against the effective request URI
   ([RFC3986], Section 5).

   For 201 (Created) responses, the Location value refers to the primary
   resource created by the request.  For 3xx (Redirection) responses,
   the Location value refers to the preferred target resource for
   automatically redirecting the request.

   If the Location value provided in a 3xx (Redirection) response does
   not have a fragment component, a user agent MUST process the
   redirection as if the value inherits the fragment component of the
   URI reference used to generate the request target (i.e., the
   redirection inherits the original reference's fragment, if any).

   For example, a GET request generated for the URI reference
   "http://www.example.org/~tim" might result in a 303 (See Other)
   response containing the header field:

     Location: /People.html#tim

   which suggests that the user agent redirect to
   "http://www.example.org/People.html#tim"

Lazy aKari:わぁいLazy K あかりLazyKインタプリタだいすき

Posted on

Abstract

CPUのクロック数が頭打ちになり、1コアあたりの性能を向上させるよりもコア数を増やす事による並列性能向上が行われるようになった昨今では、並列化の行い易い純粋関数型プログラミング言語が注目されています。本研究で題材とするLazyKは、トークンが4つというシンプルさでありながら、チューリング完全な純粋関数型プログラミング言語です。

一方、近年のアニメシーンにおいて、アニメ本編よりもインターネット上での罵声の浴びせかけあいやステマばかりが着目され、アンチと信者のせめぎあいがより激しくなり荒廃が進んでいます。

7/2より放送されている「ゆるゆり♪♪」の主人公赤座あかりは、彼女の必殺技「\アッカリ~ン/」によって可視光における強い参照透過性を実現し、彼女のすべてを愛す性格によって、世界に愛をもたらしています。

本研究では、LazyKに赤座あかりの愛を組み合わせた独自言語「Lazy aKari」を実装することで、LazyKの啓蒙と世界に愛を広めました。

いつも通りの「トークン変えただけのゴミ言語のお時間」です。Brainfuckでやってる事が多い気がしますが、毎度毎度Brainfuckでやるのも流石に秋田ので別のにしました。トークンが4つで調度良かったのでLazyKです。で、毎度毎度手続き型で書くのも秋田ので今回はLISPで書いて見ました。ほとんどLISPの機能を使ったので随分楽ちんな実装となっております。

Scheme処理系の一つであるgaucheを使ってます。

Unlambdaスタイルのみに対応しております。トークンの対応は次の通り

  • わぁい⇨`
  • うすしお⇨s
  • あかり⇨k
  • だいすき⇨i
$ gosh akari.scm <ソースファイル>

として、入力を入れたらCtrl+D(WindowsではCtrl+Zらしい)を押して入力を確定すると、プログラムが実行されて結果が表示されます。

サンプル:echoプログラム

入力をそのまま返します。

大好き

これを保存してgosh akari.scm echo.txtとして実行し、入力したらCtrl+D(WindowsではCtrl+Z)を押してね。入力した結果がそのまま表示されます。

% gosh akari.scm echo.akari
yryr[Ctrl+D]
yryr

大好きはエコー…。そう、人と人との絆は、相互承認なのです(鼻で笑いながら

サンプル:Hello World

Hello Worldです。メッセージ変えたかったのですがLazyKは書ける気がしなかった()のでWikipediaのをそのまま使いました

わぁいあかりわぁいわぁいうすしおわぁいわぁいうすしお大好きわぁいあかりわぁいわぁいうすしおわぁい
 あかりわぁいわぁいわぁいうすしお大好き大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかり
 うすしおあかり大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁい
 うすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいわぁいうすしおわぁい
 わぁいうすしお大好き大好き大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり
 大好きわぁいあかりわぁいわぁいうすしおわぁいわぁいうすしお大好きわぁいあかりわぁいわぁいうすしおわぁい
 わぁいうすしおわぁいあかりうすしおあかりわぁいわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかり
 うすしおあかり大好きわぁいわぁいうすしおわぁいあかりわぁいわぁいうすしおわぁいわぁいうすしおわぁい
 あかりうすしおあかり大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁい
 わぁいわぁいうすしお大好き大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり
 大好きわぁいあかりわぁいわぁいうすしおわぁいわぁいうすしお大好きわぁいあかりわぁい
 わぁいうすしおわぁいあかりわぁいわぁいわぁいうすしお大好き大好きわぁいわぁいうすしお
 わぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいわぁいわぁいうすしお大好き
 大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁい
 うすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいあかりわぁいわぁいうすしお
 わぁいわぁいうすしお大好きわぁいあかりわぁいわぁいうすしおわぁいあかりわぁいわぁいわぁい
 うすしお大好き大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり
 大好きわぁいわぁいわぁいうすしお大好き大好きわぁいわぁいうすしおわぁいわぁいうすしお
 わぁいあかりうすしおあかりわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり
 大好きわぁいあかりわぁいわぁいうすしおわぁいわぁいうすしお大好きわぁいあかりわぁいわぁい
 うすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいうすしおわぁいあかりわぁい
 わぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいわぁいうすしおわぁい
 わぁいうすしおわぁいあかりうすしおあかりわぁいわぁいうすしおわぁいあかりわぁいわぁいうすしお
 わぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいわぁいわぁいうすしお大好き
 大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいうすしお
 わぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいあかりわぁいわぁいうすしおわぁい
 わぁいうすしお大好きわぁいあかりわぁいわぁいわぁいわぁいうすしおわぁいわぁいうすしおわぁい
 あかりうすしおあかりわぁいわぁいわぁいうすしおわぁいわぁいうすしお大好き大好き大好き
 わぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいうすしお
 わぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいわぁいうすしお大好き大好き
 わぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいうすしお
 わぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいあかりわぁいわぁいうすしお
 わぁいわぁいうすしお大好きわぁいあかりわぁいわぁいうすしおわぁいあかりわぁいわぁいうすしお
 わぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいわぁいわぁいうすしおわぁい
 わぁいうすしお大好き大好き大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁい
 あかりうすしおあかり大好きわぁいあかりわぁいわぁいうすしおわぁいわぁいうすしお大好き
 わぁいあかりわぁいわぁいうすしおわぁいあかりわぁいわぁいうすしおわぁいわぁいうすしお
 わぁいあかりうすしおあかりわぁいわぁいうすしおわぁいあかりわぁいわぁいうすしおわぁい
 わぁいうすしおわぁいあかりうすしおあかり大好きわぁいわぁいうすしおわぁいわぁいうすしお
 わぁいあかりうすしおあかりわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり
 大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいわぁい
 うすしおわぁいわぁいうすしお大好き大好き大好きわぁいわぁいうすしおわぁいわぁいうすしお
 わぁいあかりうすしおあかり大好きわぁいあかりわぁいわぁいうすしおわぁいわぁいうすしお大好き
 わぁいあかりわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいうすしお
 わぁいあかりわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいわぁい
 うすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいうすしおわぁいあかりわぁいわぁい
 うすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいわぁいわぁいうすしお大好き大好き
 わぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいうすしおわぁいわぁい
 うすしおわぁいあかりうすしおあかり大好きわぁいあかりわぁいわぁいうすしおわぁいわぁいうすしお大好き
 わぁいあかりわぁいわぁいうすしおわぁいあかりわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしお
 あかり大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいうすしお
 わぁいあかりわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいわぁいうすしお
 わぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいわぁいうすしお大好き大好きわぁいわぁいうすしお
 わぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり
 大好きわぁいあかりわぁいわぁいうすしおわぁいわぁいうすしお大好きわぁいあかりわぁいわぁいうすしおわぁいあかり
 わぁいわぁいわぁいうすしお大好き大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好き
 わぁいわぁいわぁいうすしお大好き大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしお
 あかりわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいあかりわぁいわぁい
 うすしおわぁいわぁいうすしお大好きわぁいあかりわぁいわぁいわぁいうすしおわぁいわぁいうすしおわぁい
 あかりうすしおあかり大好きわぁいわぁいうすしおわぁいあかりわぁいわぁいうすしおわぁいわぁいうすしお
 わぁいあかりうすしおあかり大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり
 わぁいわぁいわぁいうすしお大好き大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうす
 しおあかり大好きわぁいあかりわぁいわぁいうすしおわぁいわぁいうすしお大好きわぁいあかりわぁいわぁい
 うすしおわぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいうすしおわぁいあかりわぁいわぁいうすしお
 わぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいわぁいわぁいうすしおわぁいわぁいうすしお
 大好き大好き大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好き
 わぁいあかりわぁいわぁいうすしおわぁいわぁいうすしお大好きわぁいあかりわぁいわぁいうすしおわぁい
 あかりわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいわぁいうすしお
 わぁいわぁいうすしおわぁいあかりうすしおあかりわぁいわぁいわぁいうすしお大好き大好きわぁいわぁい
 うすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好きわぁいあかりわぁいわぁいうすしおわぁい
 わぁいうすしお大好きわぁいあかりわぁいわぁいわぁいうすしお大好き大好きわぁいわぁいわぁい
 うすしお大好き大好きわぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好き
 わぁいあかりわぁいわぁいわぁいうすしお大好き大好きわぁいわぁいわぁいうすしお大好き大好き
 わぁいわぁいうすしおわぁいわぁいうすしおわぁいあかりうすしおあかり大好き

どうしたあかり。たまにはのり塩も食べないと。

% gosh akari.scm hello.akari
[Ctrl+D]
Hello, world!

かんたんなかいせつ

LazyKは上にあるように、4つのトークン`skiをつかいます。で、そのうちskiの3つは関数です。LISPで書くとこんな関数。

(define (S x) (lambda (y) (lambda (z) ( (x z) (y z)))))
(define (K x) (lambda (y) x))
(define (I x) x)

で、`というのは関数呼び出しを表します。つまり、`ikは(I K)で、“skiは( (S K) I)のことで、`s`kiは(S (K I) )ということです。関数は必ず1つだけ引数を取ります。以下可読性を重視してLISP形式で書きます。

Iは引数をそのまま返す関数なので簡単ですね。

Kは関数を返す関数です。つまり、(K 1)の戻り値は (lambda (y) 1)という「関数」で、((K 1) 2)としてさらに戻ってきた関数を呼び出すと1(=x)という結果になります。なんでこんな面倒な事をするかというと、LazyKの世界では関数は引数を1つしか取れないのですが、Kという関数にはどうしても2つ引数を取らせたかったからです。LazyKでは関数は関数を返すことができるので、関数を返す関数を作ることで引数が1個しかとれない問題を回避しています。これをカリー化と言うそうです。

Sはちょっと厄介ですね。((S K) K)が関数Iと等しい関数であることを確かめると理解できると思います。

((S K) K) -> (lambda (z) ( (K z) (K z))) ;定義にしたがって、xとyをKに置き換えただけ
-> (lambda (z) ( (lambda (w) z) (K z))) ;最初の(K z)を展開した。内側のラムダ式でwは使われないことに注目。
-> (lambda (z) z)
-> これはIそのもの

…うーん、面倒ですね。

数字は?

LazyKは上記でみた3つの要素しかありません。数字というリテラルはありません。えっ、でも計算くらいできないと困るじゃん。

そこでLazyKでは、数をチャーチ数というので表します。数とありますがやっぱり関数で、この関数に別の関数fを渡すと、fをn回適用してくれる関数を返してくれる関数です。「関数」がゲシュタルト崩壊してきてはあ?って感じですね。たとえば、チャーチ数で3を表す関数をchurch-3は、引数として関数fをとり、「f(f(f(x)))を返す関数」を返してくれます。つまり、渡す関数を「引数に1を足して返す関数」にすると、

(define (adder x) (+1 x)) ;1を足した引数を返す
((church-3 adder) 0) -> 3

というわけです。ちなみに、チャーチ数の0は(K I)です。

リストは?

よくわからないんですけどこれも関数で表します。LISPのcar/cdrなリストと同じような構造で、具体的にはリストの関数を_LIST_とすると、(_LIST_ K)とするとcarが、(_LIST_ (K I))とするとcdrをしたことになるらしいです…。同様にconsも定義できるそうです。 終了条件がわからない(lispでのpair?はどうやるの?)ので誰か教えてください。

入出力は?

入出力は上で紹介したチャーチ数とリスト構造を使います。LazyKのプログラムは関数を組み合わせて作られる大きな大きなひとつの関数なので、これへ引数として入力値のASCIIコードをチャーチ数で表したもののリストを入れて実行されます。で、その戻り値(チャーチ数のリスト)が出力というわけです。

なので、「大好き」(=i)だけのプログラムは、入力値をそのまま返すechoプログラムになったわけですね。

というかですね

LazyKは情報がなさ過ぎます。あと実をいうと二期はまだ見てないです(

二期みた

こwwwwwねwwwwwこwwwwwwwちゃんwwwwwwwwwwwwwwwwwwwたちwwwwwwwwwwwwwwwwwww