Node.jsを使って静的コンテンツを表示するHTTP/HTTPSサーバーを用意する



connectモジュールを使えば、簡単にHTTPサーバーを作成できます。
connectはNode.js 向けの拡張可能な HTTP サーバフレームワークです。ミドルウェアと呼ばれるプラグイン機構をつかって HTTP サーバを拡張することが出来ます。
これを包括する形でルーティングなどを簡単にしてくれるのがexpressですね。


カレントディレクトリをルートディレクトリとするサンプルを作ってみます。
ローカルで簡単に動作確認などテストを実施したい時に便利です。

const http = require('http');
const connect = require('connect');
const logger = require('morgan');
const serveStatic = require('serve-static');

const app = connect()
  .use(logger('dev'))
  .use(serveStatic(process.cwd()))

http.createServer(app).listen(3000);

serveStaticはローカルに存在するファイルを返すミドルウェアです。
connectのv2.xでは、staticプロパティとしてconnectに組み込まれていましたが、v3.0から分離されています。
同じくloggerもmorganと名前を変えて分離されています。

これだけで完了です。

続いてHTTPSサーバーを用意してみます。

まずはSSLに必要な鍵を生成します。

$ openssl genrsa -out localhost.key 2048
$ openssl req -new -x509 -key localhost.key -out localhost.cert -days 3650 -subj /CN=localhost

適当にapp配下にkeysディレクトリを作成し、生成されたkeyとcertを移動します。
あとはこの生成した2つのファイルを読み込んでオプションとして渡してあげるだけでHTTPS対応が完了します。

const https = require('https');
const fs = require('fs');
const connect = require('connect');
const logger = require('morgan');
const serveStatic = require('serve-static');

const options = {
  cert: fs.readFileSync('./keys/localhost.cert'),
  key: fs.readFileSync('./keys/localhost.key')
};

const app = connect()
  .use(logger('dev'))
  .use(serveStatic(process.cwd()))

https.createServer(options, app).listen(3000);

確認してみましょう

$ node server.js
$ curl 'https://localhost:3000/app/' -vk     
*   Trying localhost...
* Connected to localhost (localhost) port 3000 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: localhost
> GET /app/ HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Cache-Control: public, max-age=0
< Last-Modified: Thu, 07 Apr 2016 14:39:04 GMT
< ETag: W/"62e-153f1298740"
< Content-Type: text/html; charset=UTF-8
< Content-Length: 1582
< Date: Fri, 06 May 2016 16:17:05 GMT
< Connection: keep-alive
<
<!doctype html>
<html>
<head>
.
.

ステータスコードは200となっており、HTMLファイルの中身も表示されていることが確認できます。
もちろんブラウザで https://localhost:3000/app/ にアクセスしても表示されます。

存在しないファイルにアクセスするときちんと404を返してくれます

$ curl 'https://localhost:3000/NotFound/' -vk 
*   Trying localhost...
* Connected to localhost (localhost) port 3000 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: localhost
> GET /not_found/ HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< X-Content-Type-Options: nosniff
< Content-Type: text/html; charset=utf-8
< Content-Length: 23
< Date: Fri, 06 May 2016 16:19:35 GMT
< Connection: keep-alive
<
Cannot GET /NotFound/