6月 132019
 

概要

参照 RFC7230 4, 3.3.1

  • HTTP メッセージボディーの転送は、HTTP/1.0 までは Content-Length で指定した長さのデータを転送する方式しかなかった
    • 転送が終わるまでボディーデータの全てをメモリ上にとどめておく必要があるなどした
  • HTTP/1.1 にて chunked transfer coding (chunked) ができるようになり、ボディーデータを分割して転送することができるようになった
    • 事前に最終的な長さが分からなくても転送可能
  • HTTP/2 には Transfer Codings の仕組み自体がない
    • Stream に取って代わられたため

  • Transfer Codings の方式は、TE および Transfer-Encoding ヘッダーにて指定する
    • TE ヘッダーでクライアントが受入可能な方式を指定
    • Transfer-Encoding ヘッダーで送信するメッセージの符号化方式を指定
  • 受信者は chunked を復号化できなければならない [RFC7230 4.1]
  • Transfer-Encoding は hop-by-hop ヘッダーであり、隣接ノード間にのみ適用される [RFC7230 3.3.1]
    • 故に、プロキシなどの中継者は Transfer-Encoding を復号化し、Content-Length 方式や別の Transfer-Encoding に変換するなどしても良い
    • Content-Encoding ヘッダーは end-to-end ヘッダーである点に注意

Continue reading »

6月 102019
 

コンポーネント凝集性の原則に閉鎖性共通の原則(CCP)もあるが、どちらも概念としては同じである。

モジュールはたったひとつのアクターに対して責務を負うべきである。
(Clean Architecture / Robert C.Martin)

クラスレベルでは、単一責任の原則(Single Responsibility Principle)。
コンポーネントレベルでは、閉鎖性共通の原則(Common Closure Principle)。

SOLID 原則は知っていても、どのようにクラスを定義するか、コンポーネントを分割するか、つまりどこに境界線を引くべきかを悩むことは多い。
単一責任、変更する理由は一つだけであるべきと言われても、その「責任」がふわっとしていて定まらないなんてことはよくある。

Clean Architecture の上記部分を読んでようやく、「責任」には当然「対象」が存在する事に気付いた。
つまりクラスにしろコンポーネントにしろ、必ず利用するアクターは存在する。

アクターとは、同じ変更理由を持ったユーザー等の集まりだ。
となると、モジュールが複数のアクターに対して責任を持ってしまうと複数の変更理由が発生する可能性が出てくる。
なので、モジュールが単一のアクターに対して責任を持つように境界線を引くべきなのだ。
一見よく似た処理や画面だったとしても、アクターが異なれば異なる変更理由で変更が入ることがあるため、分けた方が良い。

複数のアクターが全く同じように使う共通的なモジュールもあるだろうが、それは恐らくより抽象化されたアクター(汎化アクター)がそれに対応するのだろう。

5月 212019
 

ストレージのインターフェースは、物理的形状の規格、電気的接続の規格、論理的なコントローラーの規格の 3 層に分かれていると解釈できます。
これらを正しく認識することによって、製品の特性を判別できるようになるでしょう。
規格によって複数の範囲をカバーしていたりして非常にややこしくはあるのですが。

規格の例
物理的 SATA, mSATA, SATA-Express, PCI-Express, M.2, U.2, USB Type-C
電気的 SATA, PCI-Express, USB
論理的 IDE/ATAPI, SCSI, AHCI, NVMe

SCSI を SATA 上に乗せれば SAS になったり、USB に乗せれば UAS になったり、TCP/IP に乗せれば iSCSI になったりするのもこれで納得ですよね?

SSD が M.2 なのに中身 SATA 接続だったり、PCI-Express 接続なのに AHCI だったりするケースがあることも理解できるでしょう。

他にも M.2 NVMe → USB ブリッジする製品などは、PCIe & NVMe を USB & UAS(SCSI) に変換しているため、シーケンシャル速度はともかく NVMe の最大のメリットである並列性の高いコマンドキューイングなどがどの程度維持されるのか心配といったことも見えてきます。

古い規格ほど全域をカバーしていることが多いように感じます。
古い規格がパフォーマンス上の都合により電気的規格を乗り換える際も、互換性を維持するためか論理的規格は残されたりして、SCSI なんかはしぶとく生き残っているわけです。

5月 132019
 

概要

参照 RFC7230 6

  • HTTP は、リクエスト・レスポンスのセットを TCP コネクション上で送受信する
  • HTTP/1.0 の既定では、1 つのリクエスト・レスポンスが完了したら TCP コネクションは閉じられる
    • Connection: keep-alive リクエストヘッダーにより TCP コネクションを閉じず再利用する持続的接続 (Persistent Connection) ができるようになった
  • HTTP/1.1 では持続的接続は既定で有効であり、 Connection: keep-alive は必要ない
    • HTTP/1.0 サーバーとの持続的接続を望む場合は送信される
  • HTTP/1.1 における「コネクション」とは、メッセージ経路全体ではなく隣接ノード間 (クライアントとプロキシ間など) のコネクションのことを指す

Continue reading »

5月 082019
 

自作プロキシ (Nekoxy2) の WebSocket (RFC6455) 対応にあたっての私なりの理解をまとめました。

概要

WebSocket 自体はかなり単純で、TCP 上で投げっぱなし全二重通信をする方法と、HTTP/1.1 からのプロトコル アップグレード方法 (WebSocket の開始方法) が定義されているだけです。
実際に何を通信するかはサブプロトコル等のアプリケーション側にお任せとなります。

WebSocket over HTTP/2 (RFC8441) では、この内アップグレード方法が HTTP/2 向けに新しく定義されただけで、通信方法は同一となります。
※ 詳細は HTTP/2 理解メモ 参照。

注意点としては、接続・切断については到達保証がありますが、それ以外のメッセージには到達保証がないため、必要に応じてアプリケーション等で実装する必要があります。

また HTTP が利用するコネクションを再利用する形となるため、経路上に非対応の透過プロキシなどが存在する場合に通信が失敗する可能性があります。

Continue reading »

5月 072019
 

HTTP/2 理解メモ同様に、自作プロキシ (Nekoxy2) で実装した際の HPACK (RFC7541) への自分なりの理解をまとめたものです。
解説とかは他サイトのほうが良いかと。

HPACK は RFC の Appendix に具体例がたくさん載っているので、分からなくなったらそこを眺めると良いでしょう。

※RFC7541 ではバイト数は厳密に「オクテット数」と表現されているが、ここではバイト数とオクテット数は同じ意味とする

Continue reading »

4月 262019
 

自作プロキシ (Nekoxy2) の HTTP/2 (RFC7540) 対応にあたっての私なりの理解をまとめました。
HTTP/2 の解説自体は他サイトのほうがわかりやすかったり正確だったりすると思うので、あくまでも参考程度に。

RFC においては SHOULD とか MUST とかの違いは重要ですが、ここに書くの面倒なので必要に応じて調べましょう。

HPACK(RFC7541) については RFC も別だし長いし記事を分けます。
HPACK 理解メモ – CAT EARS

Continue reading »

4月 192019
 

.NET Core 3.0 Preview 4 で HttpClient の HTTP/2 サポートが追加されたようですね。
Announcing .NET Core 3 Preview 4 | .NET Blog

今までの .NET Standard では SslStream 自体が HTTP/2 の事実上必須な機能(ALPN)に対応しておらず、.NET Standard 2.1 でようやくサポートされる見込みだったため、どうやらちゃんとくるようで一安心というところです。
(HttpClient についてはこれのせいかは不明ですが…… SocketsHttpHandler が HTTP/2 対応していなかったのは確か)

しかしながら .NET Framework 4.8 の方は .NET Standard 2.0 止まりになることになっているので、HTTP/2 サポートは今後あるのかどうかすら怪しいですね……

Given many of the API additions in .NET Standard 2.1 require runtime changes in order to be meaningful, .NET Framework 4.8 will remain on .NET Standard 2.0 rather than implement .NET Standard 2.1.
Announcing .NET Standard 2.1 | .NET Blog

とはいえ .NET Standard はあくまでも API 標準を定めただけで実装は各プラットフォーム依存ですから、動くようになる可能性はあるかも?

とりあえず .NET Framework は 4.8 の時点では HttpClient + HttpClientHandler では動作しそうにありません。
BCL 以外でなら WinHttpHandler を使い、HttpRequestMessage のバージョンを明示的に指定することで、利用できます(Win10 1607↑ + .NET FW 4.6↑ に限る)。
参考: How to make the .net HttpClient use http 2.0?

実は Core 2.0 までも Windows 環境に限れば WinHttpHandler に丸投げしていたようで、HttpClient で HTTP/2 が動作します。
Core 2.1 以降 SocketsHttpHandler に移行し、環境依存を減らした為、HTTP/2 に一時的に非対応となっていたようです。

HttpClient の HTTP/2 対応

  • .NET Framework
    • HttpClientHandler では利用不可
    • WinHttpHandler (要NuGet & Win10 1607)を利用すれば利用可
  • .NET Core
    • ~2.0 : Win10 1607~のみ利用可?
      • WinHttpHandler を使ってる模様
    • 2.1~2.2 : 利用不可
      • SocketsHttpHandler に移行したため
      • ただし WinHttpHandler を利用するよう構成すれば Windows では利用可
    • 3.0~ : 利用可
      • SocketsHttpHandler の HTTP/2 対応?

Continue reading »

4月 192019
 

英語版(ndp48-devpack-enu.exe とか)を入れれば直る。

各国語版は Language Pack でしかない。
にも関わらず、少なくとも .NET Framework 4.8 時点ではブラウザの言語設定を見て勝手に言語選択されて Language Pack (ndp48-devpack-jpn.exe とか)がダウンロードされてしまう。
ので一旦ブラウザの言語設定を英語にし、英語版をダウンロードしましょう。