non vorrei lavorare

昔はおもにプログラミングやガジェット系、今は?

ll言語でhttpsサーバを作る

先週末、奥さんの職場もブースを出している旅博に息子達と行ってきました。 数は少ないものの列車の旅を紹介するブースもあり、長男はケースに飾ってある電車を出せ!と電車好きな反応を示していました。@kjunichiです。

f:id:kjw_junichi:20170614212658j:plain

 

背景

GoogleAPIJavaScriptでお手軽に叩きたいが、httpsである必要があるので、httpではなく、httpsでローカルにサーバを立てないと、ローカルで実験できない。

追記じゃないんだけど

昔はhttpsオンリーだったはずのGoogleJavaScript APIだが、先日、ドキュメントを眺めていたら、 httpも許容している模様。この記事のように頑張ってhttpsサーバを立てなくても大丈夫みたい。。。

何は無くともオレオレ証明書

openssl genrsa -des3 -out key.pem 2048
openssl req -new -key key.pem -out cert.csr
openssl x509 -days 365 -req -signkey key.pem < cert.csr >cert.pem
openssl rsa -in key.pem -out key.pem

OSXでPostgres.appにパスを通している場合は

/usr/bin/opensslとフルパス指定が吉

Ruby

#!/usr/bin/env ruby
require 'webrick'
require 'webrick/https'

server = WEBrick::HTTPServer.new(
    :BindAddress => '127.0.0.1',
    :Port => 3000,
    :DocumentRoot => '.',
    :SSLEnable  => true,
    :SSLCertificate => OpenSSL::X509::Certificate.new(open('./cert.pem').read),
    :SSLPrivateKey => OpenSSL::PKey::RSA.new(open('./key.pem').read))
Signal.trap('INT') { server.shutdown }
server.start

自己証明書すら一行で生成することも可能!

 :SSLCertName  => [ [ 'CN', WEBrick::Utils::getservername ] ])

thinが簡単にワンラインナーで動かせそうだが、thin単体で入れること出来るのか?Rails環境ならこれで決まりみたいな感は有るが。。。

Link

Python

import BaseHTTPServer, SimpleHTTPServer
import ssl

httpd = BaseHTTPServer.HTTPServer(('localhost', 4443), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket, keyfile='key.pem',certfile='cert.pem', server_side=True)
httpd.serve_forever()

Link

Perl

HTTP::Server::Brick

Ruby由来のがありました!

use HTTP::Server::Brick;
use HTTP::Status;
use HTTP::Daemon::SSL;

my $server = HTTP::Server::Brick->new(
    port => 8889,
    daemon_class => 'HTTP::Daemon::SSL',
    daemon_args  => [
    SSL_key_file  => 'key.pem',
    SSL_cert_file => 'cert.pem',
    ],
    );

$server->mount( '/foo/bar' => {
    path => '.',
        });

$server->mount( '/test/proc' => {
    handler => sub {
    my ($req, $res) = @_;
    $res->add_content("<html><body>
                                 <p>Path info: $req->{path_info}</p>
                               </body></html>");
    1;
    },
    wildcard => 1,
        });

    $server->mount( '/test/proc/texty' => {
        handler => sub {
            my ($req, $res) = @_;
            $res->add_content("flubber");
            $res->header('Content-type', 'text/plain');
            1;
        },
        wildcard => 1,
            });

# these next two are equivalent
$server->mount( '/favicon.ico' => {
    handler => sub { RC_NOT_FOUND },
        });
$server->mount( '/favicon.ico' => {
    handler => sub {
    my ($req, $res) = @_;
    $res->code(RC_NOT_FOUND);
    1;
    },
        });

# start accepting requests (won't return unless/until process
# receives a HUP signal)
$server->start;

Node.js

var https = require('https');
var fs = require('fs');

var portNum = 4442;

https.createServer({
    key: fs.readFileSync("key.pem"),
    cert: fs.readFileSync("cert.pem")
}, function (req, res) {
    res.writeHead(200);
    res.end("Hello World!\n");
}).listen(portNum);

console.log("Started server https://localhost:" + portNum + "/");

Link

あとがき

書いている途中から、関数型の場合も書きたくなってきたので、 関数型のhttpサーバーは作ってみようかと。

関連記事

 

8年前の記事

6年前の記事