helen's blog

ずっとおもしろいことしてたいな。

cakePHPでapacheでリダイレクトさせようとしたけどだめだったよ

諦めたというオチです

やったこと
RewriteRule ^/helen https://www.google.co.jp/ [R=302,L]

こんな感じでapacheで /helen -> google にリダイレクトさせようとしてたのですがだめでした。

原因
AllowOverride All

これのせいで.htaccessのほうが強くなり、親に設定したリダイレクトが効いてませんでした。

オチ

apacheでリダイレクトできないけど

header('Location: https://www.google.co.jp/');

はしたくなかったのでapp/Config/routes.phpに下記設定。
ref) ルーティング

// 内部遷移
Router::redirect(
    '/helen/index/', 
    array('controller' => 'hoge', 'action' => 'fuga'), 
    array('status' => 301)
);

// もちろん/helen/だけでも外部サイトでも行ける
Router::redirect(
    '/helen/*', 
    'https://www.google.co.jp/', 
    array('status' => 301)
);
おまけ

cakePHPに入っているラスボスはこんな.htaccessです
app/.htaccess at master · cakephp/app · GitHub

ログを見るとこんな感じ。多いのでちょっと整形しました。
DocumentRootは/home/vagrant/webRoot/です

[rid#7f8af0cdc7f8/initial] (3) [perdir /home/vagrant/webRoot/] strip per-dir prefix: /home/vagrant/webRoot/helen -> helen
[rid#7f8af0cdc7f8/initial] (3) [perdir /home/vagrant/webRoot/] applying pattern '^' to uri 'helen'
[rid#7f8af0cdc7f8/initial] (4) [perdir /home/vagrant/webRoot/] RewriteCond: input='/home/vagrant/webRoot/helen' pattern='!-d' => matched
[rid#7f8af0cdc7f8/initial] (4) [perdir /home/vagrant/webRoot/] RewriteCond: input='/home/vagrant/webRoot/helen' pattern='!-f' => matched
[rid#7f8af0cdc7f8/initial] (2) [perdir /home/vagrant/webRoot/] rewrite 'helen' -> 'index.php'
[rid#7f8af0cdc7f8/initial] (3) [perdir /home/vagrant/webRoot/] add per-dir prefix: index.php -> /home/vagrant/webRoot/index.php
[rid#7f8af0cdc7f8/initial] (2) [perdir /home/vagrant/webRoot/] strip document_root prefix: /home/vagrant/webRoot/index.php -> /index.php
[rid#7f8af0cdc7f8/initial] (1) [perdir /home/vagrant/webRoot/] internal redirect with /index.php [INTERNAL REDIRECT]
[rid#7f8af0cee110/initial/redir#1] (3) [perdir /home/vagrant/webRoot/] strip per-dir prefix: /home/vagrant/webRoot/index.php -> index.php
[rid#7f8af0cee110/initial/redir#1] (3) [perdir /home/vagrant/webRoot/] applying pattern '^' to uri 'index.php'
[rid#7f8af0cee110/initial/redir#1] (4) [perdir /home/vagrant/webRoot/] RewriteCond: input='/home/vagrant/webRoot/index.php' pattern='!-d' => matched
[rid#7f8af0cee110/initial/redir#1] (4) [perdir /home/vagrant/webRoot/] RewriteCond: input='/home/vagrant/webRoot/index.php' pattern='!-f' => not-matched
[rid#7f8af0cee110/initial/redir#1] (1) [perdir /home/vagrant/webRoot/] pass through /home/vagrant/webRoot/index.php

分解すると

# /helenのアクセスのDocumentRootをはずす
[rid#7f8af0cdc7f8/initial] (3) [perdir /home/vagrant/webRoot/] strip per-dir prefix: /home/vagrant/webRoot/helen -> helen

# RewriteRuleの ^ をhelenに適応できるか?
[rid#7f8af0cdc7f8/initial] (3) [perdir /home/vagrant/webRoot/] applying pattern '^' to uri 'helen'

# RewriteCondそれぞれ確認
[rid#7f8af0cdc7f8/initial] (4) [perdir /home/vagrant/webRoot/] RewriteCond: input='/home/vagrant/webRoot/helen' pattern='!-d' => matched
[rid#7f8af0cdc7f8/initial] (4) [perdir /home/vagrant/webRoot/] RewriteCond: input='/home/vagrant/webRoot/helen' pattern='!-f' => matched

# matchedなのでhelen -> index.phpへ書き換え
[rid#7f8af0cdc7f8/initial] (2) [perdir /home/vagrant/webRoot/] rewrite 'helen' -> 'index.php'

# DocumentRootをつける
[rid#7f8af0cdc7f8/initial] (3) [perdir /home/vagrant/webRoot/] add per-dir prefix: index.php -> /home/vagrant/webRoot/index.php

# はずす
[rid#7f8af0cdc7f8/initial] (2) [perdir /home/vagrant/webRoot/] strip document_root prefix: /home/vagrant/webRoot/index.php -> /index.php

# /index.phpへリダイレクト
[rid#7f8af0cdc7f8/initial] (1) [perdir /home/vagrant/webRoot/] internal redirect with /index.php [INTERNAL REDIRECT]

ここでridが変わる

# またDocumentRootを外す
[rid#7f8af0cee110/initial/redir#1] (3) [perdir /home/vagrant/webRoot/] strip per-dir prefix: /home/vagrant/webRoot/index.php -> index.php

# 条件にマッチするか確認するよ
[rid#7f8af0cee110/initial/redir#1] (3) [perdir /home/vagrant/webRoot/] applying pattern '^' to uri 'index.php'

# 条件だよ
[rid#7f8af0cee110/initial/redir#1] (4) [perdir /home/vagrant/webRoot/] RewriteCond: input='/home/vagrant/webRoot/index.php' pattern='!-d' => matched
[rid#7f8af0cee110/initial/redir#1] (4) [perdir /home/vagrant/webRoot/] RewriteCond: input='/home/vagrant/webRoot/index.php' pattern='!-f' => not-matched

# これを表示するよ
[rid#7f8af0cee110/initial/redir#1] (1) [perdir /home/vagrant/webRoot/] pass through /home/vagrant/webRoot/index.php

.htaccessしか効いてないのに親をいじってapache再起動しまくってたのが虚しい

apacheのRewriteCondをサブネットマスクで許可する

192.168.33.0/25みたいなのを許可したい時

RewriteCond %{REMOTE_ADDR} !^(192\.168\.33\.0/25$)

じゃだめで

RewriteCond %{REMOTE_ADDR} !^(192\.168\.33\.([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-6])$)

こうする

100からどっかまでの指定

126までにしたかったので

  • 1[0-1][0-9] → 100〜119
  • 12[0-6] → 120〜126

で指定

ひやっとしたね!

サブネットマスク計算(IPv4)/サブネット一覧(早見表)

detached状態でmasterに-fプッシュした人がいるらしいよ

masterが突然ちぎれた対応をしたときのメモです

壊れちゃった!とヘルプを求められ、確認すると、
gitホスティングサービス上では不思議な事態が起こっていました。

f:id:heleeen:20161230202919p:plain

こんな感じでmasterがちぎれていました

何をした結果なのか詳細は確認してないのですが、
なんらかの作業をした結果detached状態になり、
-fをつけてmasterプッシュしたのかな?という気がしています

目標は、masterを可能な限り復元することです

リポジトリの運用ルールに100%準拠していることを前提に、
そのリポジトリ利用者に、最後にmasterへマージしたdevelopを教えていただき
そこをmasterとして修正しました

手順
  1. (ローカルが死んでしまったため)リポジトリを新規クローン
  2. 最後にmasterへマージしたdevelopをcheckout
  3. detached状態のmasterを削除(ウワーッ)
  4. そのまま最後にmasterへマージしたdevelopからmasterを生やします
  5. 最後にmasterへマージしたdevelopと作成したmasterの最新コミットが一致することを一応確認
  6. -fプッシュ!
作業ログ
~/repo ❯❯❯ git branch
* master
 
~/repo ❯❯❯ git log -1
commit !!!!!!!!FakeLastMasterCommit!!!!!!!!
Author: XXXXXXXXXXXXXXXXXXX
 
    detachedしちゃったぜ!
 
~/repo ❯❯❯ git checkout last-develop
Checking out files: 100% (6341/6341), done.
Branch last-develop set up to track remote branch last-develop from origin.
Switched to a new branch 'last-develop'
  
~/repo ❯❯❯ git log -1
commit !!!!!!!!RealLastCommit!!!!!!!!
Merge: piyyoyo honyanya
Author: YYYYYYYYYYYYYYYYYYYYYY

    最後にmasterマージしたdevelopの最新コミットだよ

~/repo ❯❯❯ git branch -d master                                              
warning: deleting branch 'master' that has been merged to
         'refs/remotes/origin/master', but not yet merged to HEAD.
Deleted branch master (was hogege).
  
~/2/repo ❯❯❯ git checkout -b master
Switched to a new branch 'master'
  
~/repo ❯❯❯ git log -1
commit !!!!!!!!RealLastCommit!!!!!!!!
Merge: piyyoyo honyanya
Author: YYYYYYYYYYYYYYYYYYYYYY

    最後にmasterマージしたdevelopの最新コミットだよ
  
~/repo ❯❯❯ git push origin -f
Total 0 (delta 0), reused 0 (delta 0)
To ZZZZZZZZZZZZZZZZZZZ
 + hogege...fugaga master -> master (forced update)

お前も-fプッシュかい!
という感じですが、そうでもしないと修正できなかったのです...

master削除とmasterへの-fプッシュは気持ち的にやりたくないです
リポジトリをforkして1回検証するくらいやりたくないです

自分がそのリポジトリの最新を落としたらローカルが死んでしまったため
旧masterの最新コミットを拾うことができず...
とはいえ、
今思えばそのリポジトリの作業者を当たれば本物のコミットを救出できた可能性はあったんだろうなー
.git/refs/heads/masterが本物のコミットだったよねー
あーやっちゃった

運用ルールに準拠していることを前提に修正したのですが
ルールがあるってありがたいね!準拠してるって信じてる!!

deployerのprepareでこけるとき

deployerのprepareが実行されるとき

  [RuntimeException]
  Unable to login with the provided credentials.

が出てるけどそのuser,PW,鍵でSSHログインできる謎にはまったのでめも

原因

あとphpseclibがDSAに対応していない

Add support for DSA · Issue #216 · phpseclib/phpseclib · GitHub

ぷぇー
こんなんドキュメントのどこに書いてあるんだー( ´_ゝ`)

GulpとEJSで設定をできるだけ減らしてみた

設定ファイルを手で書くとミスるし
ストレスマッハなのでがんばって減らしてみました

ファイル構成

ページの中身をcontentsとしてURLに合わせてディレクトリを切り、
それぞれのjndex.ejsの上下にheadやらfooterやらをくっつけて使います

.
├── contents # ページの中身
│   ├── index.ejs
│   └── hoge
│       └── fuga
│           └── piyo
│               └── index.ejs
└── layouts
    ├── common # front、mypageから使う共通系パーツ
    │   ├── _navi.ejs
    │   ├── _localNavi.ejs
    │   ├── _logged.ejs
    │   └── _notLogin.ejs
    ├── front # フロントで使用するパーツ
    │   ├── _footer.ejs
    │   └── _headTag.ejs
    ├── frontAfterContent.ejs # フロントの要素の後につけるパーツ
    ├── frontBeforeContent.ejs  # フロントの要素の前につけるパーツ
    ├── mypage # ログイン後に使用するパーツ
    │   ├── _footer.ejs
    │   ├── _headTag.ejs
    │   └── _header.ejs
    ├── mypageAfterContent.ejs # ログイン後の要素の後につけるパーツ
    └── mypageBeforeContent.ejs # ログイン後の要素の前につけるパーツ

headerやfooterの間をクルクル回すのをよく見るけど
for文書くとどこで何が動いてるのかわからなくなるので、
各contentsで何を呼ぶか明示します

gulpfile

ここでfor文で回すのをよく見るけどやらず、コンパイルして拡張子をhtmlにしてるだけ
contents/**/*.ejsな感じにすると
ディレクトリ階層を維持したままコンパイルしてくれるので設定書かなくて済む

const gulp = require('gulp');
const ejs = require('gulp-ejs');
const jsonData = require('./settings.json');

gulp.task('default', ['main']);
gulp.task('main', ['ejs']);

gulp.task('ejs', function(){
    return gulp.src(
        ['contents/**/*.ejs', '!' + 'contents/**/_*.ejs']
    )
        .pipe(ejs({jsonData:jsonData}, {'ext': '.html'}))
        .pipe(gulp.dest('../'));
});

setting.json

設定をまとめて名前をつけて呼び出せるようにして

{
    "default":{
        "title":"title",
        "description":"description"
    },
    "hogefugapiyo":{
        "title":"fugaaaa",
        "isLogin":true
    }
}

こんな感じで呼び出す

<% data = jsonData.default; %>

特に個別の指定がなければdefaultとか書いとく感じ
CakePHPだとcontrollerでtitle、descriptionを決めれるから(こうあるべきかは別の話)
URLのコントローラーまでの設定を作っとけば
同じコントローラーのアクションどうしはその設定を使いまわせるっていう幸せ

呼び出し

使いたい設定の名前を変えるだけ

<% data = jsonData.default; %>
<%- include('../layouts/frontBeforeContent', data); %>
<!-- 要素 -->
<%- include('../layouts/frontAfterContent'); %>
<!-- frontAfterContentは渡すデータがないから書いてないけどdataあると今後幸せになれそう -->

で、上下のパーツは

$ cat layouts/frontBeforeContent.ejs
<!DOCTYPE html>
<html>
  <%- include('../layouts/front/_headTag', data) %>
  <body class="lo1 skin-blue">
    <%- include('../layouts/common/_gnavi') %>
    <%- include('../layouts/common/_makeNavi') %>
    <%- include('../layouts/common/_akibaNavi', data) %>
$ cat layouts/frontAfterContent.ejs
    <%- include('../layouts/front/_footer') %>
  </body>
</html>

各小パーツを呼び出すだけにして、
1箇所いじれば全部に反映されるようになってる

ログイン判定

ログイン前ログイン後で表示が変わるものは設定ファイルで管理

ログイン済みにしたいページのみsettingにこれを追加して

"isLogin":true

パーツはこんな感じにする

<% if(data.isLogins){ %>
    <%- include('../common/_logged'); %>
<% } else { %>
    <%- include('../common/_notLogin'); %>
<% } %>

まあほんとはtrue,falseで管理されてるのかわかんないけどねー
isLoginがtureってイメージしやすいからそう書いてます

json書きたくねーymlにする!って言ってたけど
最終的にymlにするのがめんどうになりました