2018年12月30日日曜日

curlを使ってサーバーからファイルをダウンロードしようとしたらできなかった話

ネットワーク周りを調べ始めて一週間ほどたち、ローカルだけど自作ホームページを表示できたので、じゃやりたいことを本格的にするかと、curlを使ってサーバーからアップロードしたファイルをダウンロードしようとしたら違うものが保存された。
#失敗したもの
curl -X POST localhost/page/download > test.txt
サーバー側のログを見るとCan't verify CSRF token authenticityとでていて頭?である。
上のエラーメッセージで調べるとこちらのページに解決策があった。
要は、ブラウザが裏側で行っていたことをしてなかったのが、失敗の原因だった。 なので、そのページ通りにコマンドを実行したら無事できて、よかった(月並み)。
curl localhost/ --cokkie-jar cookie | grep csrf
curl localhost/page \
  -F "authenticty_token='上のgrepしたもの中のcsrf-tokenのcontentにある文字列を入れる'" --cookie cookie > test.txt

CSRFについて

CSRFはCross-Site Request Forgeries(クロスサイトリクエストフォージェリ)と呼ばれるWebアプリケーションの脆弱性の一つ。 Wikepediaを見ると「ぼくはまちちゃん」事件で利用されたそうだ。

いくつかサイトを調べているとサーバー側の不備が原因の脆弱性だそうだ。 ユーザー側の対策としては、使っていないときはログアウトする、怪しいURLにはアクセスしないがある。 (個人的にスマホで毎回ログイン/ログアウトしている人いるのかな?って。スマホに危機が迫っている。何者かに侵略されているぞ!)

リンク一覧

  1. IPA 3. CSRF (クロスサイト・リクエスト・フォージェリ)
  2. 大量の「はまちちゃん」を生み出したCSRFの脆弱性とは?
  3. 外部からPOSTできない?RailsのCSRF対策をまとめてみた

リンク最後のQiitaを読むと今回したいことはPOSTではなくGETリクエストを使用する方があっているのでは?と思ったので修正。(POSTにしていたのはなんていうか流れ、惰性、なんか変わったことをするにはPOSTみたいな思い込みですかね)

そういえばWebサービスにはRESTという設計モデルがあるって、どこかで聞いていた覚えがある。RESTに当てはめると今回の機能は取得(GET)にあたる機能だから、POSTはおかしい。別にサーバー内のデータを書き換える訳ではないし。 さらにいうと更新とか削除とかすべてPOSTで行っているので、PUT、DELETEに置き換えないと…。公開する前から修正するところだらけである。

さらにいうと、作っている間にみたサイトで、最近のWebサービスにはSSR(Server Side Rendering)を使ったAjaxで1ページだけで画面遷移を行うとかみて、Webの進歩の速さは速すぎると、毎度思う。(格好いいサイトは歓迎です!) SSRはWebページの不正コピーを防ぐため手段としても活用されているみたいでコンテンツを重要視しているサイトとかだと必須になるのかな?とか思ったり。

SSRなページを作るならVue.jsかなーって、思っていたり、Webページばかり作っていたら、オンラインゲームを作る余裕がないじゃんとか思ったり、そんな日々です。

とりあず、今回の件でRails使っていて良かったなぁと。セキュリティについてはさっぱりだから、フレームワーク側で対策してくれているのはありがたいです。

2018年12月28日金曜日

Rails Validatesまとめ

とりあえず、公式ガイドを見よう

  • Rubyのバージョンは2.5.1
  • Railsのバージョンは5.2.2

以下、使ったもの

メールアドレス

Rubyの標準ライブラリのURIにメールアドレスの正規表現が用意されているのでそれをformatwithオプションに指定してあげる。
# メールアドレスのバリデーション
validates :email, format: {with: URI::MailTo::EMAIL_REGEXP}
参考HP

バリデーションエラーの日本語化

デフォルトのままだとエラーメッセージが日本語のままだったので、こちらのサイトを参考に日本語化した。

日本語化した後は、起動しているサーバーを再起動させれば適応される。

2018年12月27日木曜日

CSSを触っていてレイアウトが崩れたので、その対処方法メモ

floatプロパティを指定しているときそのまま親タグを閉じてしまうと、レイアウトが崩れてしまった。CSS初心者あるあるみたいで、その解決方法はこちらのサイトが詳しいので、そちらを見た方がいい。

目指しているレイアウト


崩れてしまった現実.下が崩れたのは別の原因なので関係ない。

結論


float指定したら、疑似要素を利用して最後にはclearプロパティを使ってfloatの効果を無効化しよう。

なぜ崩れるの?


floatを指定したら、親タグはそのタグを高さ計算に含めない仕様となっているから。
そう策定されているので従う他ないので、解決策を下に書いていく。

1.clearプロパティを使う


空タグをfloatを無効化したい部分(今回の場合は最後)に入れて、cssでclear:bothを指定して上げるとOK。
学習サイトではこちらの方法を教えていたので、はじめはこちらを使っていたが、下の方法がよりスマートである。

2.:afterを持つCSS要素を親タグにつけるとよりスマート


cssに.hogehoge:afterと書くと、そのcssを指定されたタグの末尾へ自動的に.hogehoge:afterでスタイルされたタグを追加してくれる。便利機能。
これを使うとHTMLに余計なタグを追加する必要がなくなってよりよい感じになる。

(下にあるタグの親の高さが0になっている状態…)
.clearfix::after {
  content: "";
  clear: both;
  display: block;
}


:afterは疑似要素と呼ばれるもので他にも:beforeとかある。もう一度上げるがこちらのサイトが詳しい。疑似要素を利用したテクニックを紹介しているので参考になる。


まとめ

floatプロパティを使うとCSSの仕様上、レイアウトが崩れてしまうケースがでてくるので、floatを適応させたい部分の末尾にはclearプロパティでfloatの効果を無効化しておく。
そのさい、htmlに空タグを追加するのではなく、疑似要素である:afterを使うとhtmlがきれいに保てる。

2018年12月16日日曜日

Direct3D12について雑記

Direct3D12について雑記


自分が作った自作Direct3D12ライブラリを公開したのも年単位で過ぎ去り、Direct3D12について結構忘れてきたので、忘れないようにBlogに書き留めておく。

数パートに分けて書くと思うが、Githubに公開してるDirect3D11の解説程かっちりしたものにはせず、箇条書きに申し訳程度の追記と簡素なものにするつもり。
それと、あやふやな記憶を頼りに書いているので(特に歴史とかは聞きかじった程度の物)誤りを指摘いただける大変助かります。

この記事で言いたいこと

  • Direct3D11からDirect3D12へのバージョンアップはJavaからC言語へバージョンアップするみたいなこと
  • 下手なDirect3D12実装よりDirect3D11を使った方がましであるということ
  • 速くするためのものではなく、無駄を削るものである

後、Direct3D12についてはこちらの記事の方が詳しいです

Direct3D12とは?


Direct3D12とは非常によくできたグラフィックスAPIであったDirect3D11を基盤に、CPUオーバーヘッドを限りなく減らすため修正されたグラフィックスAPIである。

Direct3D12が公開された当初はLow CPU Overheadだ!なんやらと宣言され、それに触発されてかOpenGLは昔からLow CPU Overheadだったぜと言っていたり、Low CPU OverheadのきっかけとなったMantleの影が薄くなったり、それよりマルチプラットフォームでLow CPU OverheadなVulkanがあればDirect3Dなんていらないしと、数年前はグラフィックAPI界隈は賑やかであったと思う。
(個人的には今から勉強するならVulkanだと思う)

Low CPU Overhead化するということは、コンシューマゲーム機のように生身のGPUにPC上から触ることができることである。ゲーム業界に詳しくないなら、Direct3D11からDirect3D12へのバージョンアップは、JavaからC言語に進化したものだと思ってほしい。

さすがに使っているGPU全てにアクセスできる訳ではないが、NVIDIAやAMDなどのGPUベンダーは独自拡張した機能をDirect3D12からアクセスできる拡張機能を提供している。
が、拡張機能を使うならVulkanの方が情報が多いのでやりやすい。
(やっぱり覚えるならVulkanじゃないかな…?)

Direct3D12を使うメリットは最新機能が比較的早く公開&触れる。(GPUは別売り)
それとWindowsという安定したプラットフォームで動作するので安心感がある、が挙げられる。
個人的にはDirect3Dのシェーダ言語、HLSLを気に入っているが、Vulkanでも使えるようになったので、昔のOpenGLとDirect3D9程の違いは現在のグラフィックスAPI間にはあまりない。

長々と書いたが、Direct3D12とはLow CPU Overhead化を実現するためにDirect3D11から省けるところを省いたグラフィックスAPIである。

省かれた部分


それでは省かれた部分はどういったものかというと、下のものになる。
  1. GPUへのコマンド発行
  2. メモリ管理
  3. パイプラインステート管理

Low CPU Overhead化と宣伝されていたので1.GPUへのコマンド発行と3.のパイプラインステート管理が注目を集めていたが、2.メモリ管理も大変重要なところで、アロケータからメモリの断片化対策までこちらで面倒を見る必要がでてきた。後、リソースの初期化も手順が増えている。

Direct3D11までの時代はメモリ管理はGPUドライバー側が面倒を見ていた。
が、それに不満を持った開発者側と肥大化していくGPU機能の管理に疲れたGPUドライバー開発者側の意見の一致でこうなったのである。(たぶん)
(汎用的なメモリアロケータではゲームやCAD、モデリングツールすべてで最適なものを提供できるかと言われたら無理でしょう。)

なので、Direct3D12は誰でも触るものではなく、本当にプロフェッショナルな人が扱うAPIである。

記事にでも出ていたが、下手なDirect3D12実装されたレンダラーとDirect3D11実装されたレンダラーではパフォーマンス的にみるとDirect3D11の方が速くなるし(=GPUドライバー製作者の上を行く必要が出てくる + Direct3D12専用の処理の流れにしないといけない)、使っているCPUが速いと両者で違いがでないので注意が必要だ。(Direct3D11で生じるコストをCPUが十分にカバーしている)

低性能なCPU上では速くなりやすいが、そんな環境ってスマフォの方が多いという現実がある。(Vulkanの方が活躍できる環境が多いといえる)

あと、GPUが原因のボトルネックはDirect3Dは関係ないのでどうしようもない。

Direct3D12で速くなる場面が限られているので注意が必要だ。

実際に体験してみたくて、時間に余裕がある人は、私の作ったライブラリにあるBetterDrawCallSceneを実行して一度に発行するDrawコールの数を調節してみると体験できると思う。

(色々コードをいじる必要がある+動かないかもしれないので、面倒です。
dx12Test/scene/IScene.cpp内のIScene::sGetStartSceneNo関数の戻り値をeSCENE_BETTER_DRAW_CALLに変えてもらえたら確認用シーンは実行できます。
実行したら後は矢印キーでDrawコールの数を調節してください。
リングバッファの上限を超えると落ちます。)

速くするというより最大限にGPUとCPUを稼働させるためには、互いに待ち時間を持たせないようにすることが大事です。

じゃ、どうなのDirect3D12って


手放しで喜べるものではないDirect3D12であるが、(関係者ではないので)個人的には過去のGPUとのお別れを告げたものだと思う。昔はいろいろなGPUベンダーがいて、なかなか共通化が大変だったのが、近年はNVIDIAとAMDぐらいとベンダーの減少、それとGPU機能も似たものになった+昔は固定機能をもつ頂点シェーダやピクセルシェーダを実行するだけだったGPUがGPGPUといった汎用計算が可能なアーキテクチャに変化していった背景もあり、関係会社にってもはや過去の遺物となったものを清算するのにいい機会だったのではないでしょうか?
(特に21世紀以前から現役のOpenGLからVulkanへの変化は判りやすいと)

今後のGPUはDirect3D12とVulkanという土台を元に発展していくでしょう。
なので、GPUにとってのC言語的な役割を果たしていくDirect3D12は今後長く使われていくと思う。

速くするためじゃない、無駄を削るため、より作り手の思い通りにGPUを操るためにDirect3D12は誕生したといえるかもしれない。