アプリの単体テストなどでHTTP serverを用意したい時があるので、色々な環境、言語でHTTP serverの起動をまとめてみた。
静的コンテンツ
Amazon S3
Amazon S3 での静的ウェブサイトのホスティングを使う
Ruby
WEBrickを使う
~/document_root/index.html
<!DOCTYPE html>
<html><body><p>hello, world.</p></body></html>
httpserver.rb
# encoding: UTF-8
# !usr/bin/env ruby
require 'webrick'
include WEBrick
$server = HTTPServer.new(:Port => 8080, :DocumentRoot => "~/document_root")
trap("INT"){ $server.shutdown }
$server.start
起動
$ ruby httpserver.rb
確認
$ curl http://127.0.0.1:8081/
<!DOCTYPE html>
<html><body><p>hello, world.</p></body></html>
Python 3
HTTPServer, SimpleHTTPRequestHandlerを使う
~/document_root/index.html
<!DOCTYPE html>
<html><body><p>hello, world.</p></body></html>
httpserver.py
# ! /usr/bin/python
# -*- coding: utf-8 -*-
from http.server import HTTPServer, SimpleHTTPRequestHandler
import time
import os
hostname = '127.0.0.1'
port = 8081
document_root_dir = os.path.expanduser('~/document_root')
os.chdir(document_root_dir)
httpd = HTTPServer((hostname, port), SimpleHTTPRequestHandler)
print(time.asctime(), "Server Starts - %s:%s" % (hostname, port))
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
httpd.server_close()
print(time.asctime(), "Server Stops - %s:%s" % (hostname, port))
起動
$ python ~/httpserver.py
確認
$ curl http://127.0.0.1:8081/
<!DOCTYPE html>
<html><body><p>hello, world.</p></body></html>
Node.js
expressを使う
document_root/index.html
<!DOCTYPE html>
<html><body><p>hello, world.</p></body></html>
package.json
{
"name": "httpserver",
"version": "1.0.0",
"description": "HTTP server",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"author": "Satoshi Iwaki",
"license": "ISC",
"devDependencies": {
"express": "~4.16.3"
}
}
index.js
const express = require('express');
const app = express();
const port = 8081;
app.use('/', express.static(__dirname + '/document_root'));
app.listen(port, () => {
console.log('Server Starts - port:' + port);
})
起動
$ npm install
$ npm start
確認
$ curl http://127.0.0.1:8081/
<!DOCTYPE html>
<html><body><p>hello, world.</p></body></html>
動的コンテンツ
Ruby
WEBrickを使う
以下、POSTされたコンテンツのSHA256ハッシュを返すサンプル
httpserver.rb
# encoding: UTF-8
# !usr/bin/env ruby
require 'webrick'
include WEBrick
$server = HTTPServer.new(:Port => 8080, :DocumentRoot => "~/document_root")
load ("./httpserver_servlet.rb")
trap("INT"){ $server.shutdown }
$server.start
httpserver_servlet.rb
# encoding: UTF-8
# !usr/bin/env ruby
require 'webrick/https'
class HelloServlet < HTTPServlet::AbstractServlet
@@mutex = Mutex.new
def do_POST(req, res)
logger = WEBrick::BasicLog.new()
logger << "------------ Request --------------"
logger << req
logger << "------------------------------------"
digest = OpenSSL::Digest::SHA256.hexdigest(req.body)
res.status = 200
res.body = "{\"content\" : \"#{req.body}\", \"digest\" : \"#{digest}\"}"
res['Content-Type'] = "application/json"
logger << "------------ Response --------------"
logger << res
logger << "------------------------------------"
end
end
$server.mount("/api/digest", HelloServlet)
起動
$ ruby httpserver.rb
確認
curl -H "Content-Type: text/plain" --data "hello, world." http://127.0.0.1:8081/api/digest
{"content" : "hello, world.", "digest" : "df4f2d5707fd85996a13aab607eb3f6b19d0e99d97281d5eae68a6c16317a329"}
Python 3
HTTPServer, BaseHTTPRequestHandlerを使う
以下、POSTされたコンテンツのSHA256ハッシュを返すサンプル
httpserver.py
# ! /usr/bin/python
# -*- coding: utf-8 -*-
from http.server import HTTPServer, BaseHTTPRequestHandler
import hashlib
import time
hostname = '127.0.0.1'
port = 8081
class HelloHandler(BaseHTTPRequestHandler):
def do_POST(self):
if self.path=="/api/digest":
length = int(self.headers['Content-Length'])
content = self.rfile.read(length)
digest = hashlib.sha256(content).hexdigest();
message = '{{"content" : "{}", "digest" : "{}"}}'.format(str(content, encoding='utf-8'), digest)
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.send_header('Content-Length', str(len(message)))
self.end_headers()
self.wfile.write(bytes(message, 'utf-8'))
else:
self.send_error(404,'File Not Found: %s' % self.path)
return
httpd = HTTPServer((hostname, port), HelloHandler)
print(time.asctime(), "Server Starts - %s:%s" % (hostname, port))
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
httpd.server_close()
print(time.asctime(), "Server Stops - %s:%s" % (hostname, port))
起動
$ python httpserver.py
確認
$ curl -H "Content-Type: text/plain" --data "hello, world." http://127.0.0.1:8081/api/digest
{"content" : "hello, world.", "digest" : "df4f2d5707fd85996a13aab607eb3f6b19d0e99d97281d5eae68a6c16317a329"}
Node.js
expressを使う
以下、POSTされたコンテンツのSHA256ハッシュを返すサンプル
package.json
{
"name": "httpserver",
"version": "1.0.0",
"description": "HTTP server",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "test"
},
"author": "Satoshi Iwaki",
"license": "ISC",
"devDependencies": {
"express": "~4.16.3",
"body-parser": "~1.18.3"
}
}
index.js
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const app = express();
const port = 8081;
const shasum = crypto.createHash('sha256');
app.use(bodyParser.text());
app.post('/api/digest', (req, res) => {
shasum.update(req.body);
const digest = shasum.digest('hex');
const body = JSON.stringify({
content: req.body,
digest: digest.toString()
});
res.append('Content-Type', 'application/json');
res.send(body);
});
app.listen(port, () => {
console.log('Server Starts - port:' + port);
});
起動
$ npm install
$ npm start
確認
$ curl -H "Content-Type: text/plain" --data "hello, world." http://127.0.0.1:8081/api/digest
{"content":"hello, world.","digest":"df4f2d5707fd85996a13aab607eb3f6b19d0e99d97281d5eae68a6c16317a329"}
Objective-C
GCDWebServerを使う