Structure Wiki
Sorry, my English is too poor. by Nazo
メニュー(Menu)
概要(What is this?)
これはD言語で書かれたWikiクローンです。日本語と英語をサポートしてます。
This is wiki clone written in the D programming language. This support Japanese and English locales.
動機(Motive)
Wikiの歴史の中でたくさんのWikiクローンが生まれました。しかしpukiwikiのようなwikiクローンたちはどれも一貫した構文を持ってはいませんでした。そのためエスケープもままならない状態でした。なので構造的な構文を持ったWikiクローンを作ろうと思ったわけです。
In wiki's history, there are many wiki clones. But those(like pukiwiki) hasn't consistent syntax. How should I do if I wants to escape in the syntax? So I became to want to make structural syntax wiki clone.
スラッシュドットジャパン|Wikiの文法の標準化案を作成中も参考にしてください。
Please see also スラッシュドットジャパン|Wikiの文法の標準化案を作成中.
特徴(Features)
- シンプルで構造的な構文
Structural and Simple wiki syntax
- 高速
Speedy
- 管理者にとって安全
Safety for admin
FAQ
- Why did you write in the D Programming Language?
- Because it is easy to write, compiling is speedy, it is type-base language, it is speedy.
- Why did not use C++? It is better to use a major language.
- I don't like C++. string operation, memory management, error messages, etc...
- My server can't execute native binary. I want to rewrite by PHP,ruby,etc...
- It is troublesome.
- Executable file is too big...
- Some libraries(like phobos) are linked statically.
- How to compile?
- At first install dmd. Then `make` to compile.
- How to make plugin?
- This have no special plugin mechanism yet. But it is easy to enhance it with recompiling(like Reiser4). And I have an idea that use dynamic library for plugins.
Releases
- 0.0.4.3 is Released!(2006-08-30)
- 0.0.4.2 is Released!(2006-08-07)
- 0.0.4.1 is Released!(2006-08-05)
- 0.0.4 is Released!(2006-08-04)
- 0.0.3 is Released!(2006-04-11)
- 0.0.2.1 is Released!
- 0.0.2 is Released!(2005-11-30)
- 0.0.1 is Released!(2005-10-25)
特徴
メリット
- 動作が結構高速
- 構造型の記法
- コンパイルが高速でスクリプトっぽく開発可能
デメリット
- D言語なので拡張性が低い(拡張するなら再コンパイルが必要になる。ダイナミックリンクで何とかなるかも
- 使えるサーバーが少ない
- 実行ファイルが大きい
- 書かれてる言語がマイナー
用語集
- 一般ユーザ
- 普通の閲覧者
- 制限ユーザ
何らかの規制に引っかかってる人。具体的には
- UAにbotやslurpが含まれる
- Acceptが空だったり*/*だったりする
- BBQ、BBX、DSBLに登録されてる
- 管理人
- 管理人
技術解説
開発者向け情報。
データは全てリトルエンディアン。
- Wikiの文法
- ヘルプ参照。
- SaveList
現在は(line \n)* line?。将来は以下のようにする予定。
\01 "1.0" length(uint) ( line_size(size_t) line_data(char[line_size]) )*
最初のlengthは必要か?
- SaveData
- \00 "1.0" ( name_size(size_t) name_data(char[name_size]) value_size(size_t) value_data(char[value_size]) )*
- パスワード
- サーバー側ではmd5(pass)で保存されている。クライアント側ではクッキーにhmac_md5(md5(pass),salt)で保存されている。
- salt
- IPv4のIPを16進数の8桁の数字にしたもの。
リリース情報
- バージョン0.0.4.3をリリースしました。(2006-08-30)
- バージョン0.0.4.2をリリースしました。(2006-08-07)
- バージョン0.0.4.1をリリースしました。(2006-08-05)
- バージョン0.0.4をリリースしました。(2006-08-04)
- バージョン0.0.3をリリースしました。(2006-04-11)
- バージョン0.0.2.1をリリースしました。
- バージョン0.0.2をリリースしました。(2005-11-30)
- バージョン0.0.1をリリースしました。(2005-10-25)
ロードマップ(予定)
- 0.0.4.4
- コード整理とフォーマットの整理
- 0.0.4.5
- ユーザーアカウントの作成
- 0.0.4.6
- ブログ機能
- 0.0.5
- マルチWikiサイトに対応
- 0.0.5.1
- アップローダを一般のもの並に
- 0.0.5.2
- バグトラッキングを一般のもの並に
- 0.0.5.3
- SNS的なもの
- 0.0.6
- Ajax対応やforumとか?
コードの見直し/最適化/クリーンアップ
バグの洗い出し
- HTMLエスケープ - Done
- HTMLアンエスケープ
- hmacMd5 - In Progress(まだ最適化の余地あり)
- パーサ - Done
- Checker - Done
- 変換 - Done
- 設定 - Done(一部新しいdmd待ち。)
- HTTP - Slow Progress(全体的見直しはまだ)
- Wiki - Slow Progress(全体的見直しはまだ)
- XHTML
- Client - Done
- WikiMode - In Progress
- UploadMode
- BugTrackingMode
- BackupMode
- GoogleMode - Done
- UploadMode
- コメント周り
- datのコンパイル
- 同期
- utils - In Progress(表面の修正のみ)
- コマンド
- Mode一般。new Wikiよりも前にcontentBodyを呼び出すようにしたのでバグが入ったかもしれない。あと不要になったコードもあるのでその削除。
UIの見直し
- 衝突時(今後の予定参照) - In Progress
- 色付け(差分/ソース。今後の予定参照)
- 足りない誘導メッセージの補完(ログイン時など) - Done
- 同期時のUI
- プレビュー時にプレビューだと表示(Ubuntuの背景画像で知らせるというのは良いと思った)
- 編集可能/不可能をもっと分かりやすくする(背景の色でも変えるか?)
- 部分修正機能(別ページ/Ajax)は必須。secの階層で処理する? (1-2-1だと[sec [sec ][sec [sec これ]]])
- メニューバー - Done(xslt使って、cookie書き換えできないバグはdataスキーマを使うことで回避(ただこの挙動が正規のものなのか不明)。Opera/Safariでは未テスト。)
- ログアウト時は権限剥奪後のメニューを表示すべき - Done
- ファイルのアップロードへのリンクの再考(フォームを張り付けてアップロードするファイル/フォーム内のデータ両方を送って処理が一番。UploadModeかなんかをWiki側で派生する。)
アルゴリズム改良
- diff
ローカライズの見直し
現在は酷い状態。非Blocker。
今後の予定
- Security: 脆弱性のあるOSからのログインの禁止(クライアントの乗っ取り対策)
- Security: IPは必ずxorなどで暗号化して保存する(grep対策)
- Security: md5からsha1もしくはRSAに
- Security: バイナリ/設定ファイル改竄検知機能及びCRC(もしくは暗号化されたバックアップ)による復元機能(パーミッション的に不可能か? データだけでも?)
- Security: パーミッション確認機能
- Security: 起動しているユーザー名確認機能(初回起動時のユーザ名/uidを保存、変更されてたらログインして了承しないと使えないように)
- Security: ファイルの命名規則を分かりにくくする…あまり意味ない気がするが
- Security: ログのxor…あまり意味ない気がするが
- Security: 管理者として入ったIPのログ機能
- Security: 設定の変更履歴とIPの保存
- Security: バイナリの変更履歴。管理者でログインするとバイナリが変更された日時が目に付くように。
- Blocker: Txをポートする。
- Blocker: コマンドベースのSynchronizeの削除とversion=Synchronizeの廃止
- Blocker: make installは/var/wwwではなく/usr/lib/cgi-bin/swへインストールすべき(書き込みは? 他のcgiはどうしてる?)
- Blocker: 広告表示(自己張り付け型)の対応
- Blocker: PayPalなどの対応(webマネーの仕組みってどうなってるんだっけ?)
- Blocker: 動画サイトとの連携
- Blocker: amazonなど
- Blocker: IPv6の対応(http://[::1]/sw/でエラーになる件を直す)
- Blocker: DNSBLの取捨選択機能
- Blocker: DNSBLのローカルキャッシュ機能(必要か?)
- Blocker: Whitelist/Blacklist(address rangeの処理の追加も)
- Blocker: unittestを増やす
- Blocker: 個人モードが全体に及ぶように
- Blocker: もっとCreateMenuItemを使うようにすべき(upload:*/bugtracking:*)
- Blocker: Prefixの依存を避ける(wiki:などを直接埋め込むのではなく、ModeFactory.prefixを利用するようにするべき。あと、ModeFactory.prefixはinvariantにするべきだなぁ。)
- Blocker: 表紙をWikiから切り離す。
- Blocker: [wiki:recent]の対応
- Blocker: 最大利用サイズの制限の実装(現在表示のみ。設定も欠けてる。)
- Blocker: 書き込み時のIPの保存と著作権所持者の表示
- Blocker: ログ取りの高機能化
- Blocker: マスクによるIP拒否など
- Blocker: 情報の整理(ユーザー情報(sw.client,nazo.http)、システム情報(sw.siteconfig)、プログラム情報(nazo.appinfo,sw.cgiinfo))
- Blocker: ページの最低の長さや日本語の含まれていないページの不可など
- Blocker: SaveListとSaveDataにopApplyを追加。SaveListにopAppendを追加。必要ならばopIndexやopSliceも追加。
- Blocker: ページタイトルの長さの制限を無くす
- Blocker: ページを消す処理がおかしい
- Blocker: 最後に同期した時刻の保存及び表示
- Blocker: Update Comment File...ArrayBoundsError sw.commentlist(137)
- Blocker: フォーマットをバイナリに(エスケープ不要=安全になる。SaveList、CommentList、AllCommentList、BugDat、UploadListなど)
- Blocker: UploadListをSaveDatからSaveList、又はもっと効率の良いのに変える。
名前 -> インデックス (削除用。(name_size(size_t) index(size_t))+ \00\00\00\00 ( name_data(char[name_size]) index(size_t) )+ )と SaveList(struct{string name; ... }のシリアライズの連続) の二つを利用するのが一番だと思う。
いや、固定長の部分+と可変長の部分(投稿者名/ファイル名)+を分けて固定長の方に可変長の位置を入れるべき。削除時は削除フラグを立てる(名前へのポインタを消す?)。フラグメント化をどうするべきか。
全て固定長も意外とありかもしれない。削除したのはインデックス化しとけばおk。削除のインデックスの追加に最大O(N)かかるのは問題かもしれ(ゴミを出さない場合)。削除の削除したものもインデックス化しとけばおk。以下永遠に続く。追求する意味がほとんど無いとしてもゴミが残るのは気持ち悪いしなぁ…。
全て固定長なら、単に一番最後のデータで空きを埋めれば良いかも。
- Blocker: 同期時に更新があると問題が起きるバグの修正(更新終了後に再度更新があるかチェックし更新があれば繰り返すことで対処可能か? 具体的にどんな問題が起きるんだっけ?)。
- リンク切れ検知機能(ユーザを利用する? iframe+(onerror|代替)ではできる?)
- ページごとにライセンスが設定できる機能(標準で選択されるライセンスも指定可にする)
- FOAFの対応
- AtomPPの対応
- OWLの対応
- Turtleの対応
- バックアップへのrevertと著作権保持者の削除の実装
- ちょっとした修正ボタン(著作権保持者に追加しない)
- フォーマット変更プログラム(今のところ後方互換を残しているので不要だが)
- コメントフォーマットの変更、及び高速化。a/r pagename=other,parameters,aa,bb
- datのバイナリ化(テキストノード 0x00、要素 0x01(間が\nの場合)/0x02(間が\sの場合)。attr=(0x00 strlen str | 0x01/0x02 attrname attrlen attr ) +)
- 検索の追加(書き込み時にトークン分割など)
- アップローダーのプレビュー機能(imagemagickやらffmpegやらを使いアップロード時にプレビュー画像を作成)
- 簡易カウンタ(テキスト/画像(http://~/img_%s.pngと設定で入力可能にする。)。counter:。version(Counter)。ページ毎のカウントをする場合どうする? datが表示された回数を数えるのが良さげ? 外部のカウントはどうする? リファラのパターンチェックで良いかな。)
- 同カテゴリに属するファイルリストの作成(tag1)
- 複数ページ表示機能(tag3。/Test?mode=multiviewでTest/*の表示。ソートや件数、ページ数なども付ける。multiviewrssも。tag1に依存。)
- テンプレート機能([template "desc","bug_no","depend"]+のような感じで。フォームから簡単に追加/削除可能にする。)
- トラックバック機能
- トラックバックのRSS
- 存在しないページは編集状態ではなく404ページを表示するべき(一般ユーザ/管理人の場合mode=editへのリンクもつける)。
- mode=createで飛ばされる先はmode=editにすべき。(一般ユーザの新規ページが作成できないの対策)
- 一般ユーザが新規ページを作ることが可能かのオプション。
- リダイレクト機能
- wiki:listコマンドがlast-modifiedを考慮していない(tag1に依存させて、同属リストをattachする? 現在の実装だと色々と難しい。依存するページをページのprefに書き込むのが良さげ。)。
- wiki:includeコマンドのサポート(last-modifiedとの兼ね合いがややこしい。現在の設計だと実装は無理。現実的な実装方法としては書き込み時にパースして依存するページをページのprefに書き込むとか。)
- インポート/エクスポート機能(単純なインポート/エクスポートはtar.gz/tar.bz2/.tar.lzmaに対応させる。それとpukiwikiからのインポート/エクスポートに対応させる)
- アップローダーのzipファイルの解析とか(パス付きzip表示/禁止機能)。
- 複数ファイルの同時アップロード機能
- static thisと連想配列でplugin作成
- デコードすべき場所が間違ってるのを修正する(nazo.http側でデコードすべき。影響範囲が広いので保留)
- HDD使用量/総ファイル数の制限。
- ブログ機能(wikiのblog/*を何件かまとめて表示する機能だけ。tag3に依存。)
- ブログのRSS(ブログの分だけしか表示しないだけ。tag3に依存。)
- MenuBarの追加(実装の方法に悩んでる。mode=menuedit/menuwrite)
- 更新の衝突時のマージ機能
- 他のバージョンとの関連の追加(prefs)
- バックアップ管理ツール
- ソースの色付け
- リスト等の差分読み込みを使うようにコードの書き換え(シークをもっと積極的に使う)
- チャット機能(ircのフロントエンドをJSだかフラッシュだかJavaだかで作れば良い気ガス)
- 掲示板
- forum
- ソース管理機能
- 部分修正機能
- Ajaxを使った一時書き込み機能
- JSを使った構文チェック機能
- ページのforkとmerge(like 分散化レポジトリ)
- バックエンドにSVNかgit使うと面白げ?
- アカウント機能(tag2)
- はてな認証API対応(tag2に依存。商用は要相談らしい。)
- Flicker認証API対応(tag2に依存。条件は未確認)
- livedoor Auth対応(tag2に依存。条件は未確認)
- Google Account Authentication対応(tag2に依存。条件は未確認)
- openIDの対応と認証サイト焼き(又はwhitelist。AOLでのWhitelist)の実装(tag2に依存。HMAC-SHA1やDiffie-Hellman鍵共有の実装も必要。)
- バグトラッキングなどをLaunchpad並に(無理
- 一つ前との差分、差分を視覚的に表示(MediaWikiの差分のように)
- NG URIやNGワード(空白挟みなどの古典的なものも阻止)
- 言語一覧
- 初期設定の改良(最初にログインさせ設定させる)
- タイトルの二重HTMLエスケープの修正
- どの国の法の下にあるかの設定
- Diffie-Hellman鍵共有とLocalStrageを使った経路暗号化…ダメだ、中間者攻撃に弱いならあまり意味無い。何か回避策ないか考えてみるか。→片方が公開鍵を送ったら、別の経路でもう片方が公開鍵を相手の公開鍵で暗号をかけてから送る。サーバーの公開鍵はアカウント毎に生成。共通鍵でお互い確認。→それでもなりすまし可能。launchpadと連携してhttps上にあるユーザー/サーバー双方の公開鍵を使えば良さげ? →launchpad以外にそういうサイト無いの? →適当に考えたけど、この方法だと秘密鍵が漏れる気ガス…つーかRSAで良くね?
- エスケープバグの修正([a test,[p test]]の時とかにエラー。早すぎるエスケープ。datのコンパイルをブロックしている。)
- ベイジアンフィルタ
- シェルの実装(WIP)
- その他諸々
高速化メモ
- dmd -profileで遅い処理が分かる
- RegExpはjavascriptと違い遅いのでなるべく使わないようにする
- 多段のreplaceは遅くなるので自分で処理を書く
- メモリ関係がネックになる事が多い。Copy On Writeの精神で。
- 多く使う構造体は配列で確保する。
- 配列の追加、削除などは最小限に抑える。
- 相互参照しているとGCの開放が遅くなるのでそういう箇所では明示的にdeleteする。
- メモリに大量アクセスする所では一時的にgcを止めておいた方が良い?
- split→foreachは遅いのでnazo.string.getBeforesを使うようにする。
- foreachの引数にはなるべくinoutを付ける
- メモリの関係でclassの配列よりstruct配列の方が工夫できる分早い。
- 配列処理は思った以上に遅い。
- in式は要素へのポインタを返すのでそれを使うべき。
botのUAの特徴メモ
- bot、slurp、crawler、spiderが含まている
- snoop、winderが含まれている
- archiver、grub、crawl、downloaderが含まれている(必要かどうか未確認)
- http://やwww.が含まれている
- /が含まれていない
- @が含まれている
- Y!Jが含まれている
- Website Explorer/、Irvine/が含まれている
- curl/、Wget/、gnome-vfs/が含まれている
- MaSagool、Hatenaが含まれている
- libwww-perl/、Java/、Python-urllib/が含まれている(副作用あるかも)
- Windows 95、Windows 98、MSIE 4.、MSIE 5.が含まれている
- MSIEを含んで.NET CLRを含まない(副作用あり)
開発メモ
- なんか色々と面倒になってきたからxml+xsltにしちゃいたい気分。ただ、パフォーマンス的問題やらwebサービス親和性問題やらデバッグ的問題やらでややこしい事になること確実。
- GCや配列演算の仕様が変わったが、今までの高速化方法が有効かどうかを試す。
- バックエンドにircを使うと面白いことができそう。かなり迷惑かけそうだけど。
- 通常使用するコンパイラをdmd v2.008へ上げました。gdc0.25でのコンパイルは未テスト。
- 固定ipのproxy経由でproxy側にログ取られてるとセッションの乗っ取りが可能になる。ネカフェ/wifiでも同じ。
- ネイティブ・オブジェクト・データベースを使うとき。ようするにclassやstructをダンプするって事?
- ここの文章のライセンスはどうするか。取りあえず保留。GPL/LGPL/MPL辺りが良いけど、不適合な文章がチラホラあって難しい感じ。
- メニュー部分にAjaxを使うのはどうだろうか…
- 祝・SVN利用開始。Google CodeのProject Hostingを利用
- 何箇所かロックを入れてみた。壊れにくくなったかも知れないけど論理的に矛盾することはありそう。
- パーミッションはint chmod(char* path, mode_t mode);で変更可能。宣言はstd.c.linuxでされてる。使いかたはこの辺。 site.cfgと同じパーミッションに変更する?
- コンパイルオプションに-inline -L-O3 -L--strip-allを付加してみた。目に見える程高速化したはず。
- バグトラッキング を利用開始
- ごく簡単なBugTrackingが完成。DependsやBlocking、重複がシームレスに扱えないのが難点。
- templateを使っていると他の所がエラーしてるだけでtemplateもエラーになる(最新版では修正された? 未確認)。
- decodeComponentは+を" "に変換してくれない(最新版では修正された? 未確認)。
- gdcでビルドするとlibgcc_s.so.1に依存するらしい。
- std/date.dを覗いてみたら…何この混沌。まぁ速度を重視してるなら別にいいか。取り合えず隠しAPIを使ってISO8610への変換に適当に実装しました。ついでにunixtimeとd_timeの相互変換APIも作った。是でOSに依存してないはず。
- うわー、debug文ってid付けられるのか。是ってあり得ないぐらい便利なのだが
- nazo.hmac_md5をstd.md5へ、nazo.dateをstd.dateにマージするパッチを作って送りつけたい。但し英語が面倒臭い。
- pragma(msg,"");でコンパイル時にメッセージ出せてstatic assert文にversion文もあってMakefileイラネww←なわけねぇ
- cgi側でEtagを吐いてもApache側にバグがあってうまくいかない。
仕様メモ
- adminはかなりの安全性。でもログインにスクリプトとクッキーが必須なのがネックかも。
構想メモ
- SQL等のデータベースを使ってもいいかもしれないなぁ…。
- datのファイル名をハッシュにしてみる?ファイルのエスケープを最小限にしてみる?
- 構文が意味付けっぽくない(古いVBの記法の様な物を導入すればokだけどうーん…)
- 自動リンク(MeCabをポーティングする?)
- Thunderbirdのフィルターをインスパイアしてみたい。
- REST系の機能との連携(Google、Yahoo、はてな(キーワード/ブックマークその他)など)。
- 日付をハッシュに含ませると良さげ? (一時的対処として)
現在の安全性
- cookieが洩れても安全(但しその時に使っていたproxyサーバや経路を除く)。
- 凍結はPOST+リファラチェックを行っています。多分問題無いです。
- クロスサイトスクリプティングができてしまう状態になってしまうと危険(JSで自動submit formを作成されたり。)。徹底的にJSを使えないようにするしかない。(POSTでのsaltの照合はそれなりに無意味と判断したのでしてません。)
- 経路でパケットが改竄されると危険(こればかりはhttpsを使うしかないはず。httpsで串サイト(他のサイトの公開鍵と暗号化/復号化するjsを保持)を作ってAjax+RSAで他のhttpの安全性を確保という方法もありかもしれない)。
- パスワードの変更がそこまで安全じゃない(現在のパスと新しいパスのxorなので、経路による成り代わりによってDOS攻撃が出来る。が、どうしようもない気ガス。)。
- バックアップファイルの制限が無い(ランダム過多な攻撃によってHDが一杯になる可能性があります。古い方から消していくという方法は上書きされまくると元情報が消えるのでしてません。書き込み間隔の制限(全体)と危険IPリストを作成してしまえばいいのかもしれませんが、それでも簡単に正確に間隔を合わせて書き込むことが可能なので危険です。間隔をランダムにする方法もありますが色々面倒臭いです。大きな変更に制限を加える方法もありますがページ分割や統合といった事もありますのでなんとも言えません。)
- ファイル数の制限が無い(ランダム過多なページを作られる事によって破綻)。200ページとかに制限すると良いかもしれない。
- 長いファイル名を付けられるとあるファイルは書き込まれてあるファイルは書き込まれないという事が起きる状態です。idかhashでの管理に切り替えるときに何とかしようと思います。