未分類

事件

今日何気なく記事を編集して、「ああ、そういや過去記事で似たような画像作ったな…作った画像どこだっけ?」って過去記事を探していたところ、どこを探しても見つかりません。

この画像には alt 属性が指定されておらず、ファイル名は image-27-1024x188.png です

あれれ?それもそのはず消えているのです。そう言えばアップロードしたときも↓な感じでメッセージが出てました。

プレビューとかでは見えていたので、「警告かなぁ…まあいいや」と気にしていなかったのですが、実際にアップロードには失敗していた模様。そしてこのファイルこそがsvgだったのです。

なぜ拒否られてたのか?

アップロードできるファイル・タイプがWordPress側で決められているからです。

Uploading Files « WordPress Codex

これはメッセージに出ていたようにセキュリティ上の理由です。

どうすればいいのか?

メッセージから調べたところ、対応方法の記事が以下に見つかりました。

大きく分けて、プラグインを使う方法とそうでない方法があるようです。遅くなりそうだからプラグインを使いたくなくて、

3. Use the Upload_Mimes Filter by Editing Your Theme’s functions.php File

の方法にしようと考えました。テーマのファイルをいじるようですが、テーマと言えばLuxeritas、誰かやってないかなぁとググって↓の記事を見つけました。

ピッタリですね。読んで見ると、今までインストールはしたものの、面倒だったので使ってこなかった「子テーマ」を使うのがいいようです。

子テーマの適用

よく分からないけどポチっと変えてみたら、、、

『設定が共通化されてない!』

直後からカスタマイズした設定の全てがデフォルトに戻っています。親テーマに戻すと戻るのですが、子テーマに変えるとまたデフォルトに…。どうやら設定が共通化されてないようなのです。ここを分ける意味はあったんでしょうか…。どこかに相互にコピーする機能があるのかもしれませんが、まあいうてそんな変えてないので、ポチポチ再設定して復元しました。凝った設定をしてる方、お気をつけください

functions.phpの編集

どうやら子テーマとは、親テーマを直接いじることなく、テーマのphpファイルを書き換えるなどヘビーな操作をWebから行えるようにした、カスタマイズの申し子のようです。どおりでアップデートの頻度が少ないわけです。↓な感じでサクっと編集できます!

でも、これ書き間違えたら二度と直せないような…要るのかな?…この画面…

ちなみに修正は↓のみ。参考文書ではいろいろ他にも処理していましたが、本家のコードにないことはしたくなかったので…

function my_custom_mime_types( $mimes ) {
	$mimes['svg'] = 'image/svg+xml';
	$mimes['svgz'] = 'image/svg+xml';
	return $mimes;
}
add_filter( 'upload_mimes', 'my_custom_mime_types' );

無事アップロード出来たので問題なし、です。ちなみに↓が投稿した記事内のsvg画像のレスポンスヘッダ。

HTTP/1.1 200 OK
Date: Tue, 04 Feb 2020 22:21:33 GMT
Server: Apache
Last-Modified: Tue, 04 Feb 2020 22:16:33 GMT
ETag: "a3c0204-10b0b-59dc7647855c6"
Accept-Ranges: bytes
Content-Length: 68363
Vary: User-Agent
Connection: close
Content-Type: image/svg+xml

普通に返されてるので、少なくとも私のアップロード操作で、別のファイルタイプと勘違いしているような問題は起きてないように見えます。

未分類

概要

前回gitリポジトリを公開したけど、gitコマンドでclone/pull/push出来るだけで、httpsなのにブラウザから直接見ることが出来なかった。

今回はリポジトリに格納されてるソースをWebで直に見れるようにしてみる。

Web UIの選択

最大手は

  • Gitea
  • GitLab

の2つ。この辺になるともう見た目GitHubと遜色がないし、とても多機能。しかし、VALUE-SERVERのCGIでは動かない。そこで今回はVALUE-SERVERで最も力を入れてそうな「PHP」でgitのWeb UIを選んでみた。その結果…

GitList

を入れてみることにしました。

https://gitlist.org/

インストール

先のリンクからダウンロードは出来るものの、インストール方法はこちらの方が詳しい

https://github.com/klaussilveira/gitlist#installation

ダウンロード

最初のリンク先からダウンロード

展開

$ cd $HOME/public_html/(ドメイン)/
$ tar xvfz ダウンロードしたファイルのフルパス

キャッシュディレクトリの作成

$ cd gitlist
$ mkdir cache

設定ファイルの編集

$ cp -p config.ini-example config.ini

config.iniを以下のように編集

--- config.ini-example  2019-04-26 02:51:27.000000000 +0900
+++ config.ini  2020-01-31 10:15:55.815297245 +0900
@@ -1,7 +1,7 @@
 [git]
 client = '/usr/bin/git' ; Your git executable path
 default_branch = 'master' ; Default branch when HEAD is detached
-repositories[] = '/home/git/repositories/' ; Path to your repositories
+repositories[] = '(ホーム)/(リポジトリの場所)/' ; Path to your repositories
                                            ; If you wish to add more repositories, just add a new line
 
 ; WINDOWS USERS
@@ -28,10 +28,10 @@
 ssh_user_dynamic = false ; when enabled, ssh_user is set to $_SERVER['PHP_AUTH_USER']
 
 ; http remote
-show_http_remote = false ; display remote URL for HTTP
+show_http_remote = true ; display remote URL for HTTP
 http_host = '' ; host to use for cloning via HTTP (default: none => uses gitlist web host)
 use_https = true ; generate URL with https://
-http_url_subdir = 'git/' ; if cloning via HTTP is triggered using virtual dir (e.g. https://example.com/git/repo.git)
+http_url_subdir = 'gitrepos/git-http-backend.cgi/' ; if cloning via HTTP is triggered using virtual dir (e.g. https://example.com/git/repo.git)
                     ; has to end with trailing slash
 http_user = '' ; user to use for cloning via HTTP (default: none)
 http_user_dynamic = false ; when enabled, http_user is set to $_SERVER['PHP_AUTH_USER']

確認

以下に設置されたことになる。

https://elephantcat.work/gitlist/

動いてるみたい。

未分類

前回HTML内でJavaScriptを書いてみたらハイライトされなくて、おかしいな〜と調べてたら3件不具合を見つけた。

不具合

HTML内のJavaScriptなどをハイライトできない場合がある

現象

記事内にシンタックスハイライターを単独で置き、HTML内にJavaScriptを記述した上で言語をHTML/XHTMLにしておくと、JavaScriptがハイライトされない。

原因

HTMLのハイライトを行う(prism-)markup.jsとJavaScriptのハイライトを行う(prism-)javascript.jsの読み込み順序が逆であるため。依存されているjsが後に読み込まれる必要がある。

JavaScriptなのにJava用のハイライタまで読み込まれる

現象

読み込みがごくごく僅かに遅くなるだけだが、わざわざ言語別に必要ハイライタだけ読み込んでるからもったいない

原因

言語指定の先頭4文字がjavaかで判断しているため、javascriptまでjavaと勘違いされた

JavaScriptのハイライタが2回読み込まれる場合がある

現象

読み込みがごくごく僅かに遅くなるだけだが、わざわざ言語別に必要ハイライタだけ読み込んでるからもったいない

原因

JavaScript単体で言語指定された場合と、依存言語として他の言語指定から読み込まれる場合に、別の言語指定文字列が使われているため(highlight-javascriptとjavascript)、重複して読み込まれる

対策

パッチを作成した。

diff --git a/inc/load-inline.php b/inc/load-inline.php
index cc707c5..3374c70 100644
--- a/inc/load-inline.php
+++ b/inc/load-inline.php
@@ -51,10 +51,14 @@ function thk_highlighter_load( $loads, $list, $active ) {
 
 		// Javascript
 		foreach( $list as $key => $val ) {
-			if( strpos( $post->post_content, '<code class="language-' . str_replace( 'highlight_', '', $key ) ) !== false ) {
+			if( strpos( $post->post_content, '<code class="language-' . str_replace( 'highlight_', '', $key ) . '"' ) !== false ) {
 				$lang = str_replace( 'highlight_', '', $key );
 
-				if( !isset( $loads[1][$key] ) ) {
+				if( !isset( $loads[1][$lang] ) ) {
+					// 言語ごとの読み込み
+					$loads[0] .= thk_fgc( $jsdir . $lang . '.js' );
+					$loads[1][$lang] = true;
+
 					/*
 					 * 他言語の依存チェック
 					*/
@@ -114,10 +118,6 @@ function thk_highlighter_load( $loads, $list, $active ) {
 						$loads[0] .= thk_fgc( $jsdir . 'sql.js' );
 						$loads[1]['sql'] = true;
 					}
-
-					// 言語ごとの読み込み
-					$loads[0] .= thk_fgc( $jsdir . $lang . '.js' );
-					$loads[1][$key] = true;
 				}
 			}
 		}

保管場所は以下。


Luxeritas作者様に報告させて頂きました。次バージョンで対応して頂けるとのお話なので、個々にパッチを当てる必要はないと思います。


2020年2月2日にリリースされたLuxeritas3.7.8本体で、対応されたことを確認しました。なので以降本件のパッチリリースはありません。


2020年2月3日本パッチには、ほとんどの言語でハイライトできなくなるという重大な不具合が発見されました😱。
同日にリリースされたLuxeritas3.7.8.2で作者様が対応してくれております。詳細は↓で。

未分類

背景

最近Dockerを使った記事を書くにあたり、シンタックスハイライターの対応言語が足りてないことに気付きました。シンタックスハイライターを実装しているのは、WordPressテーマのLuxeritasなのですが、このシンタックスハイライターに使われているprism.jsではもっと大量の言語に対応しています。そこで、今回必要になった、YAMLファイル(docker-compose.yml)、Dockerfile、 iniファイル(php.iniで欲しくなる)の3つの言語に簡単に対応してみました。

Luxeritasのコード解析

簡単とはいえ、説明書があるわけではないので、Luxeritasのコード解析をしないと、どこを修正していいか分かりません。調べてみたところ、大まかにいかの流れでシンタックスハイライターが動いています。

  1. シンタックスハイライターが扱える言語とその言語を表す文字列のリスト(wpfunc.php)を元にシンタックスハイライターの言語選択画面でリストアップする
  2. 記事のDB保存時にユーザーが選んだ言語を表す文字列を個々のコードブロックに紐づけて保存する
  3. 記事の表示時は、シンタックスハイライターを以下のように表示する
    1. コードブロックに紐付けられた言語を表す文字列と、先のリスト (wpfunc.php) を照合して、言語を確認(loadinline.php)
    2. その言語が複数の言語で構成されていればそれらを追加し、記事内で必要な言語のリストを作る(loadinline.php)
    3. 必要な言語のリストを元に、必要なprism.jsのファイルを特定し、最小限の組み合わせでJavaScriptファイルを合成(minify)してクライアントに返す
    4. クライアント側ではprism.jsの機能により、自動的に各言語はparseされてハイライトされていく

言語の追加

今回追加する言語は、複数の言語で構成される言語ではないので(例えばHTMLの中にJavaScriptが入るとか)、 シンタックスハイライターが扱える言語とその言語を表す文字列のリストに必要な言語を追加し、その言語に必要なprism.jsの部品を追加すれば完成です。

シンタックスハイライターが扱える言語の追加

wpfunc.php

diff --git a/inc/wpfunc.php b/inc/wpfunc.php
index fac76e8..7039e66 100644
--- a/inc/wpfunc.php
+++ b/inc/wpfunc.php
@@ -1970,6 +1970,9 @@ function thk_syntax_highlighter_list() {
                'highlight_sql'         => 'SQL',
                'highlight_vbnet'       => 'VB.NET',
                'highlight_vim'         => 'Vim',
+               'highlight_yaml'        => 'YAML',
+               'highlight_docker'      => 'Docker',
+               'highlight_ini'         => 'Ini',
        );
 }
 endif;

必要なprism.jsの部品を追加

今回は現在の最新リリースである、prism.js v1.16.0を取得し、その中からcomponents/prism-言語名.min.jsとなっているファイルを抽出し、必要な言語をLuxeritasパッケージ内にjs/prism/言語名.jsというファイルで配置しました。

パッチ

以下にまとめてあります。

未分類

前提

  • dockerが使える
  • Visual Studio codeが使える
  • x-debugを使用する

docker

docker-compose.yml

version: "3.1"
services:
  wordpress:
    build: .
    restart: always
    ports:
      - 80:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - ./wordpress:/var/www/html
      - ./php.ini:/usr/local/etc/php/php.ini

  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - ./db:/var/lib/mysql

volumes:
  wordpress:
  db:

Dockerfile

FROM wordpress:php7.3
RUN pecl install xdebug \
  && docker-php-ext-enable xdebug
WORKDIR /var/www

ビルド時に以下のようなメッセージ(タイミングや環境によって異なる)が出るはずなので、これをphp.iniに追加する。

zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so

php.ini

post_max_size = 50M
upload_max_filesize = 50M
memory_limit = 256M
[xdebug]
xdebug.remote_enable=1
xdebug.remote_autostart=1
; ホスト側のIP
; host.docker.internalはdockerのhostマシンのIPを解決してくれます。
; hostマシン以外のIP/WindowとMAC以外の場合は適宜IPを調べて設定してください。
xdebug.remote_host=host.docker.internal
; 空いているport番号
xdebug.remote_port=9000
; xdebugの出力するログの場所。今回は適当に/tmp配下に。
xdebug.remote_log=/tmp/xdebug.log
; Dockerイメージビルド時のメッセージをコピペして追記
zend_extension=?

Visual Studio code

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9000,
            "pathMappings": {
                // {docker上のdocument root}:{ローカルのdocument root}
                "/var/www/html":"/path/to/wordpress"
            }
        }
    ]
}

参考サイト

未分類

前回3~4倍遅くなるということは分かっていたのですが、

PHPのリリース日とサポート期限 – Qiita

などを見てしまうと、こうせざるをえませんでした。

共有レンタルサーバの限界を見た気がします。

Herokuであればapacheなどを共有する必要もなく、コンテナごとにいくらでも選べるわけです。常駐プロセス問題も30分ルールで解決してるし最強です。

VPSなら管理権限も与えられて全部自由です。

まあVPSを借りるのが勿体ないと感じたから共有サーバなんですけどね。Herokuも考えたけど、DB容量が不足してました。PHP7でLaravelも出来る!前向きに捉えます。

未分類

さて、VALUE-SERVERでは、

  • mod_phpだけどphp5という構成
  • CGI版だけどphp7という構成

がある。

普通に考えると言語固有モジュール版であるmod_phpの方が早い。しかし、バージョンアップにより何倍も早くなるというphpではどちらが速いのかよく分からない。

幸いにもサブドメインのwww.elephantcat.workでは別のphpを設定できるので、こちらにCGI+php7を設定し、前回同様の測定をやってみた。

結果

PatternTime[s]Effective Time[s]
static HTML4.85
mod_php5 + PHP5.66.121.27
mod_cgi + PHP7.39.184.33

Effective TimeはTimeからstatic HTMLパターンの時間を引いた時間です。こうすることにより、純粋にPHPに関連する時間だけが残ります。

CGI php7ではmod_php5の約3~4倍程度の時間に収まっています。が、やはりCGIの方が遅いようです。

未分類

前書き

前回はCGIのbottleとdjangoを50回取得した時間を比較しました。

では、WordPressを推してるVALUE-SERVERが力を入れてそうなPHPだと、どれくらいの時間なのでしょうか?

ただの静的なHTMLページも加えて比較してみました。

加えたもの

<?php echo "Hello, World"; ?>
Hello, World!

比較用のシェルはこうなります。

for url in django.cgi/polls/ hello.cgi/ hello.php hello.html;do
        time bash -c "for i in {0..99};do wget -q -O - https://elephantcat.work/cgi-bin/$url >/dev/null;done"
done

結果

Patterntime[s]
CGI Python + bottle 22.22
CGI Python + django 66.00
mod_php PHP56.12
static HTML4.85

これがCGI及びPythonインタプリタの起動の遅さということです。

なお、計測器からelephantcat.workへのping100回の平均値は6.421msでした。