2009/08/19


だいたいに10分くらいだと思う。
まずtinytinyhttpd(tthttpd)とmercurialは既に入っている事として

1. リポジトリを作る

# cd /path/to/repo
# hg init

2. hgwebdir.cgiを用意する

mercurialに含まれるhgwebdir.cgiを配置する。
# cd /path/to/web
# cp /path/to/hgwebdir.cgi .
mercurialのソースパッケージに入ってる

3. hgweb.configを用意する

hgwebdir.cgi用の設定ファイルを書く。
[paths]
repo = /path/to/repo

4. hgrcを作る

.hg/hgrcを作る(もしくは修正する)。 [web]
name = repo
description = my private repo
contact = mattn@example.com
push_ssl = false
allow_push = mattn iratqq hasegawa
allow_pull = *
allow_read = *
allow_archive = bz2, gz, zip
encoding = utf-8

5. パスワードファイルを書く

mattn:ggrks
iratqq:kkrkr
hasegawa:xss
プレインテキストなので要注意

6. tthttpdの設定ファイルを書く

Windowsならば [global]
port=8080
root=c:/path/to/repo
indexpages=hgwebdir.cgi

[mime/types]
cgi=@c:/python26/python.exe

[authentication]
/=POST,Admin!,c:/path/to/passwd
Unixならば [global]
port=8080
root=/path/to/repo
indexpages=hgwebdir.cgi
spawn_executable=on

[authentication]
/=POST,Admin!,/path/to/passwd
こんな感じ。

7. tthttpdを起動する

設定ファイルを指定して起動
# tthttpd -vvv -c repo.conf
tthttpd-hgweb1
うごいた。

8. clone/pushしてみる

# hg clone http://localhost:8080/hgwebdir.cgi/repo
destination directory: repo
no changes found
updating working directory
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
# cat > README

^D

# hg add README
# hg commit -m "first import"
# hg push
pushing to http://localhost:8080/hgwebdir.cgi/repo
searching for changes
http authorization required
realm: Admin!
user: mattn
password:
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files

tthttpd-hgweb2
うごいた。
最新版のtinytinyhttpdでしか動きません。

tthttpd.exeを含んだリポジトリフォルダごと持って歩けば、どこでもmercurialサーバになるね。
Posted at by



2009/08/18


色々と修正を施して、sinatraのdispatch.cgiも動くようになっています。またBASIC認証をサポートしましたので、tDiaryのupdate.rbだけに認証をかけられる様になっています。実際には、ターゲットURL、メソッド(GET/POSTなど)、ユーザ・パスワード一覧という設定が可能になったので、複数ユーザを扱う事も出来ます。
ただ現状、プレインテキストのみ対応ですので、これについては今後なんとかして行きたいと思っています。

本当ならば.htaccessを読み込ませたいのですが、.htaccessはcrypt/md5を使って暗号化されており、libcryptを使うとなれば依存が増えると同時に、ライセンス的にもグレーになってきますので、少し悩んでいます。どこかにPublic Domainで書かれたlibcrypt知りませんか?
Posted at by



2009/08/17


ずいぶん前からXMLRPCをC++で扱うのに小さいライブラリないかなーと思ってました。


書いたといっても結構前からあったのですが、いらん所を削ぎ落として簡素なXMLRPCライブラリとして仕立て上げました。
簡素とは言えど、一般的な物ならば色々動きます。
例えば、ブログに一気に、しかも機械的にポストしたい場合とか

おれは今すぐXMLRPCしたいんだ!そしてどうしてもC++でXMLRPCしたいんだー!

って事ないですか?MovablebTypeをインストールしたけど、XMLRPCするのにC++コンパイラは入ってるけど、PerlやRubyやPythonは入ってない...とか悲しすぎます。
今回紹介する"tinyxmlrpc"はそんな、小さい様で大きな問題を解決出来るかもしれないライブラリです。
mattn's tinyxmlrpc at master - GitHub

tiny xmlrpc library written in C++

http://github.com/mattn/tinyxmlrpc/tree/master
今githubが不調でpushが反映されていません。リポジトリからのcloneは出来る様です。
ソースはC++で書いてます。WindowsとUNIX(Linuxでだけ動作確認)で動作します。

機能としては、STLのvectorとかmapとかに親和性高くなる様になっています。内部ではlibxmlでパースしていてcurlで通信しています。
小ささをウリにしていますが、libxmlとcurlのリンクは必須です。
サンプルコードを以下に示します。
#include "tinyxmlrpc.h"
#include <iostream>

class vargs {
private:
    tinyxmlrpc::value::Array args_;
public:
    vargs& operator <<(tinyxmlrpc::value arg) {
        args_.push_back(arg);
        return *this;
    }
    tinyxmlrpc::value::Array& list() {
        return this->args_;
    }
    vargs& first() {
        this->args_.clear();
        return *this;
    }
};

int main(int argc, char* argv[]) {
#ifdef _WIN32
    WSAData wsadata;
    WSAStartup(MAKEWORD(2,0), &wsadata);
#endif

    if (argc != 4) return -1;

    std::string endpoint = argv[1];
    std::string user = argv[2];
    std::string pass = argv[3];

    try {
        tinyxmlrpc::value::Array req;
        tinyxmlrpc::value res;
        tinyxmlrpc::value::Struct entry;
        vargs args;

        res = tinyxmlrpc::call(endpoint,
                "metaWeblog.getRecentPosts",
                (args.first() << "1" << user << pass << 3 << true).list());
        if (!tinyxmlrpc::failed(res)) {
            for(int n = 0; n < res.size(); n++) {
                std::vector<std::string> members = res[n].listMembers();
                std::vector<std::string>::const_iterator it;
                std::cout << "{" << std::endl;
                for(it = members.begin(); it != members.end(); it++) {
                    std::string val = res[n][*it].to_str();
                    std::cout << "  " << it->c_str() << "=" << val.c_str() << std::endl;
                }
                std::cout << "}" << std::endl;
            }
        } else {
            std::cerr << res << std::endl;
        }

        entry["title"] = "hasegawaにいじめられた";
        entry["description"] = "今日は、wassrでhasegawaにいじめられた。悲しかった。";
        entry["dateCreated"] = "";
        res = tinyxmlrpc::call(
                endpoint,
                "metaWeblog.newPost",
                (args.first() << "1" << user << pass << entry << 1).list());
        if (!tinyxmlrpc::failed(res)) {
            std::cout << "result:" << res << std::endl;
        } else 
            std::cerr << res << std::endl;
    } catch(tinyxmlrpc::value::Exception& e) {
        std::cerr << e.message << std::endl;
    }

    return 0;
}

これを使ってコマンドラインから引数として、MetaWeblogをサポートしているブログのエンドポイントURLユーザパスワードを指定すると、「hasegawaにいじめられた」というエントリがポストされます。
タイトルや本文に、特に意味はありません。すごいですね!


ライセンスはまだ決めてませんが、今のところBSDを予定しています。使ってみて下さい。
コードはgithubにあるので、patchウェルカムです。
今後は、この記事の為だけに仕上げた疑いのある汚いコードを綺麗にしていくつもりです。

参考文献:C++で軽量Webサーバ書いた。
Posted at by