情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

expressモジュールによるHTTPサーバ(20)条件リクエスト

この記事は「expressモジュールによるHTTPサーバ」という連載記事の20つ目の記事です。

その他の記事に関しては下を参照してください。

また、HTTP自体について知りたい方は下を参照してください。

この記事ではexpressモジュールを使ってHTTPリクエストのIf-None-MatchヘッダフィールドやIf-Modified-Sinceヘッダフィールドによる条件が満たされているかをチェックするHTTPサーバを作成する方法について説明します。

If-None-MatchヘッダフィールドとIf-Modified-Sinceヘッダフィールド

req.freshにはHTTPリクエストのIf-None-MatchヘッダフィールドやIf-Modified-Sinceヘッダフィールドによる条件が満たされているかが真偽値として格納されています。

var express = require('express');

var app = express();
app.use(function (req, res, next) {
    var fresh = req.fresh;
    next();
});

条件が満たされている場合にはtrueが格納されており、満たされていない場合にはfalseが格納されています。

また、req.staleにはHTTPリクエストのIf-None-MatchヘッダフィールドやIf-Modified-Sinceヘッダフィールドによる条件が満たされていないかが真偽値として格納されています。

app.use(function (req, res, next) {
    var stale = req.stale;
    next();
});

条件が満たされていない場合にはtrueが格納されており、満たされている場合にはfalseが格納されています。

ただし、HTTPリクエストのCache-Controlヘッダフィールドの値がno-cacheを含む場合には必ずreq.freshの値はfalseとなり、req.staleの値はtrueとなりますので注意してください。

存在タグに関する設定項目

存在タグに関するアプリケーションの設定項目としてetag設定項目があります。

これは存在タグを使用しないか、弱い存在タグを使用するか、強い存在タグを使用するかを設定するためのものであり、デフォルトはtrueです。

falseを設定した場合には存在タグを使用しません。

trueを設定した場合には弱い存在タグを使用します。

また、strongを設定した場合には強い存在タグを使用し、weakを設定した場合には弱い存在タグを使用します。

あるいは、存在タグを生成する関数を指定することもできます。この関数の第1引数はHTTPレスポンスボディであり、第2引数はボディの文字コードです。この関数では存在タグを返り値として返すようにします。

サンプルコード1

クライアントからリクエストを受け取ったらURLに応じて様々なテキストデータを返すHTTPサーバを作成し、起動します。

Enterキーが押されたらサーバを停止し、プログラムを終了します。

express-server-etag.js

var express = require('express');
var http = require('http');

var app = express();
app.set('env', 'development');
app.set('x-powered-by', false);
app.set('case sensitive routing', true);
app.set('strict routing', true);
app.set('etag', 'strong');
app.use(function (req, res, next) {
    console.log(req.fresh);
    console.log(req.stale);

    res.status(200);
    res.type('text/plain; charset=utf-8');
    next();
});
app.get('/', function (req, res, next) {
    res.send('welcome to pizyumi\'s website. this is home page.\r\n');
});
app.get('/author', function (req, res, next) {
    res.send('author is pizyumi.\r\n');
});
app.get('*', function (req, res, next) {
    res.status(404);
    res.send(http.STATUS_CODES[404] + '\r\n');
});
app.post('*', function (req, res, next) {
    res.send('request method is post.\r\n');
});
app.all('*', function (req, res, next) {
    res.status(501);
    res.send(http.STATUS_CODES[501] + '\r\n');
});
var server = app.listen(3000, function () {
    console.log('http server is running...press enter key to exit.');

    process.stdin.on('data', function (data) {
        if (data.indexOf('\n') !== -1) {
            server.close(function () {
                console.log('http server closed.');
                process.exit(0);
            });
        }
    });
});
server.on('error', function (err) {
    console.error(err);
    process.exit(1);
});

使用パッケージ

  • express
    npm install expressでインストールします。

実行結果

実行結果の確認のためにcURLを使用しています。

コードを実行するとHTTPサーバが起動します。

C:\work\node>node express-server-etag.js
http server is running...press enter key to exit.

cURLを使ってサーバに対して普通のHTTPリクエストを行います。

C:\work\node>curl -v http://localhost:3000/
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Content-Length: 50
< ETag: "32-juTlohfTcZy04HpD+lfkLw"
< Date: Wed, 15 Mar 2017 02:39:26 GMT
< Connection: keep-alive
<
welcome to pizyumi's website. this is home page.
* Connection #0 to host localhost left intact
C:\work\node>curl -v http://localhost:3000/author
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET /author HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Content-Length: 20
< ETag: "14-sE0PITZfvap0ovAO45JijA"
< Date: Wed, 15 Mar 2017 02:40:00 GMT
< Connection: keep-alive
<
author is pizyumi.
* Connection #0 to host localhost left intact

サーバから正しくレスポンスが返っていることが分かります。

cURLを使ってサーバに対してIf-None-Matchヘッダフィールドを設定したHTTPリクエストを行います。

C:\work\node>curl -H If-None-Match:* -v http://localhost:3000/
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
> If-None-Match:*
>
< HTTP/1.1 304 Not Modified
< ETag: "32-juTlohfTcZy04HpD+lfkLw"
< Date: Wed, 15 Mar 2017 02:44:04 GMT
< Connection: keep-alive
<
* Connection #0 to host localhost left intact
C:\work\node>curl -H If-None-Match:* -v http://localhost:3000/author
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET /author HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
> If-None-Match:*
>
< HTTP/1.1 304 Not Modified
< ETag: "14-sE0PITZfvap0ovAO45JijA"
< Date: Wed, 15 Mar 2017 02:45:48 GMT
< Connection: keep-alive
<
* Connection #0 to host localhost left intact

サーバから正しくレスポンスが返っている(ステータスコードが304Not Modified)のレスポンスが返っている)ことが分かります。

また、HTTPリクエストのIf-None-MatchヘッダフィールドやIf-Modified-Sinceヘッダフィールドによる条件が満たされているかが正しく取得できていることが分かります。

C:\work\node>node express-server-etag.js
http server is running...press enter key to exit.
false
true
false
true
true
false
true
false

Enterキーを押すとサーバが停止し、プログラムが終了します。

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-express, Node.js