情報アイランド

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

expressモジュールによるHTTPサーバ(4)HTTPリクエストの内容の取得

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

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

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

この記事ではexpressモジュールを使ってクライアントからのHTTPリクエストの内容の取得を行うHTTPサーバを作成する方法について説明します。

プロトコル

req.protocolにはHTTPリクエストのプロトコル(HTTPかHTTPSか)が格納されています。

また、HTTPリクエストのプロトコルがHTTPSである場合にはreq.securetrueとなり、そうでない場合にはfalseとなります。

var express = require('express');

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

プロトコルはHTTPリクエストヘッダのX-Forwarded-Protoフィールドの値などから導出されます。

リクエストメソッド

req.methodにはHTTPリクエストメソッドが格納されています。

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

ドメイン名に関する設定項目

ドメイン名に関するアプリケーションの設定項目としてsubdomain offset設定項目があります。

これはサブドメインの数を設定するためのものであり、デフォルトは2です。

リクエストURL(リクエストターゲット)

req.hostnameにはHTTPリクエストのURLのホスト部分が格納されています。

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

ホスト部分はHTTPリクエストヘッダのHostフィールドかX-Forwarded-Hostフィールドの値から導出されます。

req.subdomainsにはHTTPリクエストのURLのホスト部分のサブドメインが配列として格納されています。

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

このサブドメインの数はsubdomain offset設定項目で設定されている数となります。

req.originalUrlにはHTTPリクエストのURLのパス部分以降が格納されています。

また、req.baseUrlにはミドルウェアのパスが格納されており、req.pathにはHTTPリクエストのURLのパス部分からミドルウェアのパスを除いたものが格納されています。

app.use(function (req, res, next) {
    var originalUrl = req.originalUrl;
    var baseUrl = req.baseUrl;
    var path = req.path;
    next();
});

クエリ文字列に関する設定項目

クエリ文字列に関するアプリケーションの設定項目としてquery parser設定項目があります。

これはクエリ文字列のパーサを設定するためのものであり、デフォルトはextendedです。

simpleを指定した場合にはquerystringモジュールを利用したパーサが使用されます。

extendedを指定した場合にはqsモジュールを利用したパーサが使用されます。

falseを指定した場合にはクエリ文字列のパースは行われません。

パーサを関数として指定することもできます。

この関数の第1引数はクエリ文字列です。

この関数ではクエリ文字列のパース結果をオブジェクトとして返すようにします。

クエリ文字列

req.queryにはHTTPリクエストのURLのクエリ文字列部分のパース結果がオブジェクトとして格納されています。

ただし、query parser設定項目の値がfalseである場合には空のオブジェクトが格納されます

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

リクエストヘッダ

HTTPリクエストヘッダのフィールドの値を取得するにはreq.header関数かreq.get関数を使用します。

app.use(function (req, res, next) {
    var value = req.header('xxx');
    next();
});
app.use(function (req, res, next) {
    var value = req.get('xxx');
    next();
});

第1引数にフィールド名を指定します。

返り値としてフィールドの値が得られます。

Content-Typeフィールド

HTTPリクエストヘッダのContent-Typeフィールドの値をチェックするにはreq.is関数を使用します。

app.use(function (req, res, next) {
    var is = req.is('xxx');
    next();
});

第1引数にメディアタイプ(MIMEタイプ)を指定します。

MIMEタイプの代わりに拡張子を指定することもできます。

返り値としてリクエストヘッダのContent-Typeフィールドの値が第1引数のMIMEタイプか拡張子に合致する場合にはMIMEタイプが得られ、合致しない場合にはfalseが得られます。

ただし、HTTPリクエストボディが存在しない場合にはnullが返ります。

サンプルコード1

クライアントからのHTTPリクエストの内容を標準出力に出力するHTTPサーバを作成し、起動します。

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

express-server-request-info.js

var express = require('express');

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.use(function (req, res, next) {
    console.log('requested.');
    console.log('hostname: ' + req.hostname);
    console.log('subdomains: ' + req.subdomains);
    console.log('protocol: ' + req.protocol);
    console.log('secure: ' + req.secure);
    console.log('method: ' + req.method);
    console.log('originalUrl: ' + req.originalUrl);
    console.log('baseUrl: ' + req.baseUrl);
    console.log('path: ' + req.path);
    console.log('query: %j', req.query);
    console.log('user agent: ' + req.header('User-Agent'));
    console.log('is text: ' + req.is('text/*'));
    next();
});
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-request-info.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 404 Not Found
< X-Content-Type-Options: nosniff
< Content-Type: text/html; charset=utf-8
< Content-Length: 13
< Date: Sat, 09 Jul 2016 11:20:41 GMT
< Connection: keep-alive
<
Cannot GET /
* Connection #0 to host localhost left intact
C:\work\node>curl -v http://localhost:3000/sasasa -X POST
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> POST /sasasa HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< X-Content-Type-Options: nosniff
< Content-Type: text/html; charset=utf-8
< Content-Length: 20
< Date: Sat, 09 Jul 2016 11:20:49 GMT
< Connection: keep-alive
<
Cannot POST /sasasa
* Connection #0 to host localhost left intact
C:\work\node>curl -v "http://localhost:3000/sasasa?foo=100&bar=200" -X PUT
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> PUT /sasasa?foo=100&bar=200 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< X-Content-Type-Options: nosniff
< Content-Type: text/html; charset=utf-8
< Content-Length: 39
< Date: Sat, 09 Jul 2016 11:21:16 GMT
< Connection: keep-alive
<
Cannot PUT /sasasa?foo=100&amp;bar=200
* Connection #0 to host localhost left intact
C:\work\node>curl -v http://localhost:3000/ --header "Content-Type: text/plain; charset=utf-8" --data-binary "hello"
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> POST / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
> Content-Type: text/plain; charset=utf-8
> Content-Length: 5
>
* upload completely sent off: 5 out of 5 bytes
< HTTP/1.1 404 Not Found
< X-Content-Type-Options: nosniff
< Content-Type: text/html; charset=utf-8
< Content-Length: 14
< Date: Wed, 28 Sep 2016 22:09:52 GMT
< Connection: keep-alive
<
Cannot POST /
* Connection #0 to host localhost left intact

HTTPリクエストの内容が正しく取得できていることが分かります。

C:\work\node>node express-server-request-info.js
http server is running...press enter key to exit.
requested.
hostname: localhost
subdomains:
protocol: http
secure: false
method: GET
originalUrl: /
baseUrl:
path: /
query: {}
user agent: curl/7.46.0
is text: null
requested.
hostname: localhost
subdomains:
protocol: http
secure: false
method: POST
originalUrl: /sasasa
baseUrl:
path: /sasasa
query: {}
user agent: curl/7.46.0
is text: null
requested.
hostname: localhost
subdomains:
protocol: http
secure: false
method: PUT
originalUrl: /sasasa?foo=100&bar=200
baseUrl:
path: /sasasa
query: {"foo":"100","bar":"200"}
user agent: curl/7.46.0
is text: null
requested.
hostname: localhost
subdomains:
protocol: http
secure: false
method: POST
originalUrl: /
baseUrl:
path: /
query: {}
user agent: curl/7.46.0
is text: text/plain

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

関連

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

-express, Node.js