blog

フロントエンドVIの再学習 - HTTPリクエスト

ウェブサービスとエンドユーザー間のインターフェース。 データ表現、セキュリティ、圧縮。 セッションの確立、管理、終了。 データ転送用のプロトコル・ポート番号、フロー制御、エラー・チェックの定義。 論理...

Feb 29, 2020 · 4 min. read
シェア

HTTPプロトコル解析

ISO-OSIの7層ネットワークモデル

  • アプリケーション層

    ウェブサービスとエンドユーザーの間のインターフェース。以下のプロトコルがあります。

  • プレゼンテーション層

    データ表現、セキュリティ、圧縮。JPEG、ASCll、EBCDIC、暗号化フォーマットなど。

  • セッション層

    セッションの確立、管理、終了。対応ホストプロセス、ローカルホストとリモートホスト間の進行中のセッション

  • トランスポート層

    データを送信するためのプロトコル・ポート番号、フロー制御、エラー・チェックを定義します。プロトコルは、TCP UDP、パケットがネットワークカードを出ると、ネットワーク・トランスポート層に入ります。

  • ネットワーク・レイヤ 論理アドレス・アドレッシングを実行し、異なるネットワーク間のパス選択を可能にします。プロトコルは次のとおりです。

  • データリンク層

    論理接続の確立、ハードウェアアドレスのアドレス指定、エラーチェックなどの機能。ビットをバイトとフレームに結合し、MACアドレスでメディアにアクセス。

  • 物理層

    物理的な接続の確立、維持、切断。

ストリーミング:ユニットの明確な分割はなく、前後の正しい順序のみが保証されます。

ポート:受信パケットは様々なアプリケーションに分配されます。

require('net'):ノード依存ライブラリ

パッケージ

IPアドレス

libnet/libpcap: libnet は IP パケットを構築して送信し、libpcap は NIC を流れる NIC からのすべてのパケットを取得します。

全二重チャンネルには優先順位関係はありませんが、HTTPはクライアントがリクエストを開始し、サーバーがレスポンスを返す必要があります。

サーバ側の環境準備

  • POST / HTTP/1.1

    Request line

  • headers

  • field1=aaa&code=x%3D1

    body

const http = require('http');
http.createServer((request, response) => {
 let body = [];
 request.on('error',(err) => {
 console.error(err);
 }).on('data',(chunk) =>{
 body.push(chunk.toString())
 }).on('end',()=>{
 body = Buffer.concat(body).toString();
 console.log('body:',body);
 response.writeHead(200,{'Content-T':'text/html'});
 response.end("<div style='width:200px;height:200px;background:red'>123</div>")
 })
}).listen(8080);
console.log('server started');

HTTPリクエストの実装

const net = require("net");
class Request {
 constructor(option) {
 this.method = option.method || 'GET';
 this.host = option.host;
 this.port = option.port || 80;
 this.path = option.path || '/';
 this.body = option.body || {};
 this.headers = option.headers || {};
 if(!this.headers["Content-Type"]){
 this.headers["Content-Type"] = "application/x-www-form-urlencoded"
 }
 if(this.headers["Content-Type"] ==="application/json"){
 this.bodyText = JSON.stringify(this.body)
 }else if(this.headers["Content-Type"] === "application/x-www-form-urlencoded"){
 this.bodyText = Object.keys(this.body).map(key => `${key}=${encodeURIComponent(this.body[key])}`).join('&')
 }
 this.headers["Content-Length"] = this.bodyText.length;
 }
 send(){
 return new Promise((resolve, reject) => {
 //.....
 });
 }
}
void async function () {
 let request = new Request({
 method: "POST",
 host: ".1",
 port: "8088",
 path: "/",
 headers: {
 ["X-Foo2"]: "customed"
 },
 body: {
 name: 'Midsummer'
 }
 })
 let response = await request.send();
 console.log(response);
}()

IV.書き込み関数を送信し、応答形式を理解します。

  • state line HTTP/1.1 200 OK
  • headers
  • body

リクエストの送信

response

  • レスポンスは分割して作成しなければならないので、ResponseParser で "組み立て" ます。
  • ResponseParser は、ResponseText をセグメント化し、ステートマシンを使用してテキストの構造を分析します。

response body

  • レスポンス本体はContent-Typeによって異なる構造を持つ可能性があるため、サブパーサーの構造を使用して問題を解決します。
  • TrunkedBodyParserを例にとると、同じステートマシンがボディのフォーマット処理に使われます。
Read next

python3 basic 06 フロー制御ステートメント

インデントを示すために、スペースと"*"を使用することができますが、この 2 つを混在させることはできません。 elifとelseはどちらも省略可能で、elifは無限に、elseは最大でも1つです。 #条件が満たされたらxを返し、そうでなければyを返します。 pythonにはforループと...

Feb 28, 2020 · 3 min read