ホーム ブログ ページ 40

Vimでメモ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

序論

サーバ作業をしたり、リモートから接続したりすることを考えると、メモは、CUIで開ける形式で残しておくとイザというときに役に立つ。

私が愛用しているのは、howm(Hitori Otegaru Wiki Modoki)というパーソナルで使うWikiのようなメモ環境。

howmについて

howmには、以下の特徴がある。

  • 特徴1:メモの作成時に、今日の日付及び現在の時間がファイル名に指定される。
  • 特徴2:所定のディレクトリ配下を再帰的に全文検索することができる。

howmは、元々、Emacsのpluginとして公開されていたが、vimでもpluginを作成してくれた方がいる。

私も最初は、EmacsやMeadowでhowmを使用していたが、段々vimで全てを完結するようになり、howmもvimのpluginのものに置きかえるようになった。

使用しているpluginは、QFixHowmである。

QFixとは、vimの検索機能のquickfixのことだと思われる。

設定などは、上記サイトを確認して頂ければよいが、私は、カスタマイズしてちょっとだけ異なる使い方をしている。

カスタマイズ

それは、所定のディレクトリを用途に応じて切り替えて使っている点である。

これは、以下の用途でディレクトリを分けたいときに便利である。

  • 所謂メモのディレクトリ
  • 日報用のディレクトリ

日報には、比較的同じような内容の記録が残ることが多い。
例えば、複数日にわたるタスクや、定例作業などである。

このため、全文検索をするときに、日報が検索対象になってしまうと本当に欲しいメモに辿り着けないことがしばしば出て来て困った経験から、通常は日報を検索対象にしないようにすることにした。

以下にQFixHowmにおけるディレクトリ切り替えの設定を記す。

  • 通常のメモに切り替える場合は、Prefixキーの後に「,1」を押下する。
  • 日報用メモに切り替える場合は、Prefixキーの後に「,2」を押下する。

なお、最後に「QFixHowmEnvMain()」をコールすることで、vim起動時に通常のメモが選択されるようにしている。

exe "nnoremap <silent> " . QFixHowm_Key . ",1 :call QFixHowmEnvMain()<cr>"
exe "nnoremap <silent> " . QFixHowm_Key . ",2 :call QFixHowmEnvDailyReport()<cr>"

function! QFixHowmEnvMain()
    let g:howm_dir            = '~/memo'
    let g:howm_filename     = '%Y/%m/%Y-%m-%d-%H%M%S.howm'

    " 設定関数呼び出し
    silent! call QFixHowmSetup()
    echo g:howm_dir
endfunction

function! QFixHowmEnvDailyReport()
    let g:howm_dir            = '~/daily_report'
    let g:howm_filename     = '%Y/%m/%Y-%m-%d_daily_report.howm'

    " 設定関数呼び出し
    silent! call QFixHowmSetup()
    echo g:howm_dir
endfunction

silent! call QFixHowmEnvMain()

リニューアルをしたDoRubyの3つの目的

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

お久しぶりです。何年ぶりの投稿になるでしょうか。。。 さて、Rubyエンジニアによる技術情報配信を目的に運営しておりました「DoRuby」ですが、老朽化や内部SEO対策などが薄れなど諸々の課題をクリアするため社内有志を募ってリニューアルいたしました。

Rubyの技術情報配信を目的にしておりましたが、途中からRubyだけではなくJava、PHP、Apache、JMeter、GAなどコンテンツの枠を広げて運営してまいりました。2008年くらいから公開し、紆余曲折あり運営を続けてまいりましたが、諸々の課題をクリアするためにリニューアルを行いました。

「DoRuby」は新しく以下の3つの目的を持ち、生まれ変わりました。

●「DoRuby」の新しい3つの目的

  1. 記事を役立ててもらい、社会に貢献すること
  2. アピリッツ社員が自身が保有するノウハウを自由に発信できるようにすること
  3. 社員にも一般利用者にもアピリッツという会社をもっと知ってもらうこと

今後もRubyをはじめとした技術情報やマーケティング関連情報など枠を広げて情報を発信できればと考えておりますので、どうぞよろしくお願いいたします。

WEBrickのURI長上限を拡張する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

WEBrickのURI長上限を拡張する

WEBrickで扱うことが出来るURI長の上限は2048バイトに制限されています。

上限を超えた場合は

Request-URI Too Large
WEBrick::HTTPStatus::RequestURITooLarge

というようなエラーメッセージが表示されます。

しかし、ローカルで開発している場合に、どうしてもその上限を緩和したくなる場合があると思います。

そんな場合はWEBrickのソースコードに記載されている制限値を直接変更することで、好きな値に変更することができます。

rbenvを利用してruby 2.3.1をインストールしている場合、

~/.rbenv/versions/2.3.1/lib/ruby/2.3.0/webrick/httprequest.rb の 415行目に記載されている

MAX_URI_LENGTH = 2083 # :notoc:

の数値を変更します。

Apacheのrestartやgraceful、stopなどの違い

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

apachectlのrestartやgraceful、
httpdのrestartやgraceful、
/etc/init.d/httpdのrestart…、
それぞれの微妙な違いをまとめました。

apachectl graceful
httpd -k graceful※どちらも同じ。
apachectl gracefulを実行すると、内部でhttpd -k gracefulが呼ばれる(後述)
子プロセスは現在のリクエストを処理した後、終了する。親プロセスは設定ファイルを再読み込みし、ログファイルを開き直す。子プロセスが徐々になくなり、替わりに新しい子プロセスが起動する。【注意点】
設定ファイルに誤りがあったり等で親プロセスが再起動せず終了した場合、 子プロセスが放置されたりする場合がある(→再起動時に問題となる可能性がある)
ので、再起動前にhttpd -tで構文チェックをした方がよい。
apachectl restart
httpd -k restart※どちらも同じ。
apachectl restartを実行すると、内部でhttpd -k restartが呼ばれる(後述)
子プロセスを即座にkill。親プロセスは終了しない。親プロセスは設定ファイルを再読み込みし、ログファイルを開き直す。その後新しい子プロセスを起動。→ログを見るとHUPシグナルが渡されたことが確認できます。
/etc/init.d/httpd restart※httpd -k restartとは別もの。
起動スクリプト内で定義されたstop→startが実行される。
子プロセスを即座にkillし、全て終了後、親プロセスも終了。(stop)その後起動。(start)→ログを見るとTERMシグナルが渡されたことが確認できます。※Apacheのインストールディレクトリがデフォルトと違う場合は、
/etc/init.d/httpd 内でhttpd実行ファイルの場所を修正する必要があります。

「apachectl restart」と「httpd -k restart」は同じ

apachectlに特定の引数を渡すと、内部で「httpd -k 引数」が実行されます。

特定の引数とは、
start | stop | restart | graceful | graceful-stop
です。

# less apachectl
-------------
  ・
  ・
case $ARGV in
start|stop|restart|graceful|graceful-stop)
    $HTTPD -k $ARGV
    ERROR=$?
    ;;
startssl|sslstart|start-SSL)
    echo The startssl option is no longer supported.
    echo Please edit httpd.conf to include the SSL configuration settings
    echo and then use "apachectl start".
    ERROR=2
    ;;
configtest)
    $HTTPD -t
    ERROR=$?
    ;;
status)
    $LYNX $STATUSURL | awk ' /process$/ { print; exit } { print } '
    ;;
fullstatus)
    $LYNX $STATUSURL
    ;;
*)
    $HTTPD $ARGV
    ERROR=$?
esac

exit $ERROR
-------------

これらの引数が渡された場合は、 httpdにそのまま引数が渡され
挙動は上記表のとおりとなります。

また、「apachectl restart」と「apachectl -k restart」も同じです。

「httpd -k restart」と「/etc/init.d/httpd restart」は別もの

どちらもhttpdを再起動しますが、処理プロセス(手続き)が異なるため挙動も異なります。

「httpd -k restart」は、httpdバイナリ(実行ファイル)内の処理によって、
「/etc/init.d/httpd restart」は、/etc/init.d/httpd(起動スクリプト)内の処理によって
再起動されます。

それぞれの処理内でkillの仕方が違う(渡されるシグナルが違う)ようで、

httpd -k restartSIGHUP
/etc/init.d/httpd restartSIGTERM
/etc/init.d/httpd reloadSIGHUP

となっているようです。

/etc/init.d/httpd は、httpd実行ファイルを起動するためのスクリプトファイルです。
手動インストール等でインストール場所が異なる場合は/etc/init.d/httpdを編集して
httpd実行ファイルの場所を修正する必要があります。

詳細は公式のドキュメントに記載されています。
https://httpd.apache.org/docs/2.2/ja/stopping.html

CentOSサーバ構築〜初期設定〜

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rickNo41です。 サーバを構築する時にする初期に設定した方がいいことを少し紹介します。

環境

CentOS7
※以下設定は全てrootで実施

時刻設定

yum install -y chrony
systemctl start chronyd.service
// しばらくすると時刻が正しくなります。

コマンド履歴保存期間変更・日時付与・vim

vim /etc/bashrc
—–
// 一番下に追加
export HISTSIZE=100000
export HISTTIMEFORMAT=’%Y-%m-%d %T ‘;
export EDITOR=/usr/bin/vim
—–
source ./bashrc
// 日時が表示されている
// 日付設定前のコマンドの日時は全て日付設定時になる
history

sar監視間隔変更

vim /etc/cron.d/sysstat
—–
// 変更
#*/10 * * * * root /usr/lib64/sa/sa1 1 1
* * * * * root /usr/lib64/sa/sa1 1 1
—–

sar監視保持日数変更

vim /etc/sysconfig/sysstat
—–
// 変更
#HISTORY=28
HISTORY=30
—–

SElinuxm無効化(変更後再起動必用)

vim /etc/sysconfig/selinux
—–
// 変更
#SELINUX=enforcing
SELINUX=disabled
—–
// Disabledでok
getenforce

ローカル開発環境でGoogleアナリティクスを動作確認する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ローカル開発環境でGoogleアナリティクスの動作確認をしたいが、

Googleアナリティクスのプロパティを作成する際、ウェブサイトのURLが必須となっていたので、どう設定すればいいのか色々試してみました。

【環境】

Vagrant + VirtualBox

CentOS 7

Ruby on Rails 4.2

ホストOS windows10

 前提

Googleアカウントを作成済みであること

 操作手順

Google Analyticsのページを開き、

https://www.google.com/intl/ja_jp/analytics/

・アカウントの作成を選択

・アカウント名に適当な名前を入力する

・ウェブサイトの名前に開発中のシステム名等を入力する

この後、ウェブサイトのURL入力が必須なのですが、ドメインは発行していないし、何を入力すればよいのだろう、ということで

①localhost

②VagrantのプライベートIP

③hostsに設定したドメイン名(test.v1.dev)

hosts側の設定:(VagrantのプライベートIP) test.v1.dev

をそれぞれ試してみました。

 検証

①「URL の最後のトップレベル ドメイン名が無効です」エラーとなり、登録不可

②登録OKとなり、下記のようなトラッキングコードが払い出されるので、サイトに埋め込みます。

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-XXXXXXXX-Y', 'auto');
  ga('send', 'pageview');

</script>

http://(VagrantのプライベートIP)のサイトにアクセスした後、Googleアナリティクスのレポートを開き、リアルタイム>サマリーを確認します。

アクティブユーザー数が1になっています。データの計測に成功したようです。

③②と同様に登録OKとなるのでトラッキングコードを埋め込んだ後、http://test.v1.devにアクセスします。

レポートを確認すると、アクティブユーザー数が増えています。こちらも成功したようです。

 さらに検証

ウェブサイトのURLって結局何でも良いのでは?と思ったので、

④適当なドメイン名(hoge.com)

も試してみました。

トラッキングコードを埋め込んだ後、http://(VagrantのプライベートIP)にアクセスし、レポートを確認すると、アクティブユーザー数が増えています。

つまり、計測に使用されるのはトラッキングコードのみで、ウェブサイトのURLは結局何でも良いようです。

 追記

Googleのドキュメントにこのような記述がありましたが、設定しなくてもアクセスされていること自体は確認できました。(細かい分析のためには必要なのかもしれません)

ローカルホストでのテスト

https://developers.google.com/analytics/devguides/collection/analyticsjs/advanced?hl=ja#localhost

apxsのオプション

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

OpenSSLをソースから入れ直した時に
Apacheのmod_ssl.soを更新しても
ライブラリ参照先が変わらない事象があったので
オプションなどをメモ。

環境

  • CentOS 5系
  • Apache 2系
  • OpenSSL 1.0.1系

前提

  • yumで入っていたOpenSSL0.9.8系を、
    ソースから入れたOpenSSL1.0.1系にバージョンアップする
  • Apache自体は再コンパイルせず、
    apxsでモジュールのみ再コンパイルする

OpenSSLをソースからインストールしましたが、
Apacheはyumで入れたOpenSSLを参照したままなので
手動で入れた方を参照するよう更新する必要があります。

今回はApache自体はそのままで、モジュールだけapxsでコンパイルし直します。

apxsとは

「APache eXtenSion tool」
Apacheの拡張モジュールをビルドしてインストールするためのツールです。
後から拡張モジュールを組み込んだり、
モジュールだけ再コンパイルして入れ直したりすることができます。
DSOサポートが有効になっている必要があります。

有効になっているかの確認方法↓

# httpd -l
Compiled in modules:
  core.c
  prefork.c
  http_core.c
  mod_so.c

→core.c、mod_so.cがあればOK

有効になっていない場合はApacheをオプションつけて再コンパイル。
yumの場合はhttpd-develパッケージに入ってます。

mod_ssl更新

今回はmod_sslを再コンパイルしたいので、
mod_ssl.cファイルを探して、apxsコマンドを実行します。

# locate mod_ssl.c

mod_ssl.cのあるディレクトリに移動後、

# apxs -c -i *.c -lssl -lcrypto -ldl -lz

-c オプション: コンパイルする
-i オプション: インストールする
-l オプション: 共有ライブラリを指定

共有ライブラリの参照先を確認。

# ldd mod_ssl.so

libssl.so、libcrypto.soが手動で入れたOpenSSLの場所を参照していればOKなのですが、
結果はyumで入れたOpenSSLが参照されたままです。

その場合は-Lオプションでライブラリパスを指定できます。

※OpenSSLが/opt/opensslにインストールされている場合

# apxs -c -i *.c -lssl -lcrypto -ldl -lz -L/opt/openssl/lib

-L オプション: ライブラリパスを指定

これで手動で入れたOpenSSLの方にリンクしてくれるようになりました。

apxsコマンドのオプション

共通オプション
-n modnameモジュール名を明示的に指定。-i, -gオプションと共にに使用。
-gオプションを指定する場合は必須。
-iオプション指定時にこのオプションの指定がない場合はファイル名から推測される。
クエリオプション
-q設定(構成)情報を取得する。パラメータで取得情報を指定できる。
設定オプション
-S name=value設定を変更する
テンプレート生成オプション
-gモジュールのテンプレート(雛形)を生成する。
-nオプションの指定によってmod_○○.cというソースファイル、Mikefile等が生成される。
DSOコンパイルオプション
-cコンパイルする。
-oオプションがない場合は、通常ファイル名から推測されたmod_○○.soというモジュールが出力される。
-o dsofile作成されるモジュールのファイル名を明示的に指定
-D name=value設定オプションをコンパイル時に直接指定
-I incdirコンパイル時に直接指定したいインクルードディレクトリがあれば指定
-L libdirコンパイル時に直接指定したいライブラリパスがあれば指定
-l libnameコンパイル時に直接指定したいライブラリがあれば指定
-Wc, compiler-flagsコンパイラフラグを指定
-Wl, linker-flagsリンカフラグを指定
DSOのインストールと設定オプション
-iインストールする
-ahttpd.confにLoadModule行を追加して有効化する
-A-aオプション同様、httpd.confにLoadModule行を追加するが
有効化はしない(コメントアウトした状態で追加される)
-eモジュールはインストールせず、httpd.confのみ編集する

-aオプションは、
対象モジュールのLoadModule行が既にある場合に指定すると、
重複してしまい、apachectl configtestは通っても
エラーでApacheが起動しないので注意が必要です。

かなりざっくり略したので、詳細はman apsxで確認を。

Google APIの使い方について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

GoogleのAPIを使用する方法について

 Projectの作成

Project作成

Google Developers Console(https://code.google.com/apis/console/)で新しいプロジェクトを作成します。

APIの有効化

API一覧から使用するAPIを選択し有効化(statusをEnable)します。

 トークンの取得

メールアドレス登録

Credentials(サイドメニュー) → OAuth consent screen(メイン画面タブ) から、Eメールアドレス(Email address)とProduct name shown to users(適当な文字列を入力)を登録します。

クライアントIDの発行

Credentials(サイドメニュー) → Credentials(メイン画面タブ)の

Create credentialsから「OAuth Client ID」を選択後、アプリケーションの種類を選択(Other)してクライアントIDを発行します。

登録が完了すると、画面にClient ID, Client Secretが表示されます(2016/07現在、Redirect URIsは表示されなくなった: http://localhost)

Authorization Codeを取得

ブラウザ上で以下のURLを入力します。リダイレクトURIとクライアントIDは上記で取得したものを入力します。

https://accounts.google.com/o/oauth2/auth?
scope=https://www.googleapis.com/auth/androidpublisher
&response_type=code
&access_type=offline
&redirect_uri=<redirect uri>
&client_id=<client id>

「<product name shown to usersで入力した文字列>が次の許可をリクエストしています」

と画面に表示されるので、「許可」ボタン(以前は承認するだったので名前は変わる可能性あり)を押下します。

ボタンを押した後リダイレクト先で、ブラウザのアドレスバーを確認します。

code=以降にAuthorization Code が入っています。

http://localhost/?code=<authorizationcode>

アクセストークンの取得

アクセストークンを取得するために、Authorization Code, Client ID, Client Secret, Redirect URI をPOST でリクエストを送ります。

curl -v -X POST 'https://accounts.google.com/o/oauth2/token' 
-d 'grant_type=authorization_code
&code=< Authorization Code >
&client_id=< Client ID >
&client_secret=< Client Secret >
&redirect_uri=< Redirect URI >'

レスポンスとして、アクセストークンとリフレッシュトークンが帰ってきます。

{
"access_token" : " アクセストークン",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "リフレッシュトークン"
}

 サーバ側設定

Gem

google API Client のGemを使用

https://github.com/google/google-api-ruby-client

使い方

require 'google/api_client'

# 初期化
client = Google::APIClient.new(
  auto_refresh_token:  true,
  application_name:    xxx,   # アプリケーション名やバージョン名を
  application_version: xxx    # 指定する場合は初期化時に入力
)

# 認証情報設定
client.authorization.client_id      = <取得したクライアントID>
client.authorization.client_secret  = <取得したクライアントシークレット>
# リフレッシュトークンにより, アクセストークンは都度取得する
client.authorization.refresh_token  = <取得したリフレッシュトークン>

# 使用するAPIとバージョンを指定
api_publisher = client.discovered_api("hogeAPI", "v1.1")

# API呼び出し
client.authorization.fetch_access_token!

response = client.execute(
  api_method: <api のメソッドを指定>,
  # パラメータを渡す場合はhashで指定
  parameters: {
    "xxx" => xxx,
    "yyy" => xxx,
    "zzz" => xxx
  }
)

responseにAPIのレスポンスが格納されます。

実行すると自分の内容を出力するシェルスクリプト

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

bash 上で自分自身の内容を出力するスクリプトの作成です。 cat コマンドの応用が面白いと思ったので紹介します。

 動機

パスワードのヒントやそこそこ頻繁に使う長めのコマンドをメモしておいてターミナル上で簡単に表示できるようにしておきたい。

echo "Qu'est-ce que c'est?"

 cat (基本)

テキストファイルの出力には cat コマンドを使用します。

echo "Je suis japonais." > sample.txt
	cat sample.txt

試しに自分を出力するシェルスクリプト

cat << EOF > sample.sh
	#!/bin/bash
	
	cat \$0
	
	# Nach dem Sinn von Sein soll die Frage gestellt werden.
	EOF
	chmod u+x sample.sh
	./sample.sh

 cat (応用)

# を不要にしたり、短くしたりできないか

例えば shebang に cat を使うとか。

cat << EOF > .1
	#!/bin/cat
	
	Veni, vidi, vici.
	
	γνῶθι σεαυτόν
	
	北 冥 有 魚 其 名 為 鯤
	
	EOF
	chmod u+x .1
	./.1

できた。PATHを追加すればファイル名だけで表示可能。名付けて猫スクリプト

curl でファイルを送る

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

http アクセスを行うコマンドラインツールは telnet, wget, lynx, w3m などあるがリクエスト結果をそのまま標準出力したい場合は curl コマンドが便利かと思っている。ファイルを POST するのも簡単だったので備忘の為、記載する。

 通常の使い方(bash上)

curl http://host/path/file.ext

※ ポストパラメータを渡すときは -F オプションを使う

e.g.
 のようなフォームで送るパラメータ。 
curl -F "param_name=param_value" curl http://host/path/file.ext

 ファイルを送るとき

e.g.
 のようなフォームで送るパラメータ。
curl -F "param_file=@file_path" curl http://host/path/file.ext

簡単でした。@マークをつけてファイルパスを指定するだけ。

 Appendix

get パラメータを送るときの注意

? や & は bash 上で特殊文字として処理されてしまうので URL ごと引用符で囲んでしまいましょう。

curl "http://host/path/file.ext?a=1&b=2&c=3"

よく使うオプション

  • -H ヘッダーを設定する。下記では名前解決できないけれど名前バーチャルホストを使用しているサーバへアクセスするときの確認に便利
  • -b 送信するクッキーファイルを指定
  • -c 受信するキッキーを保存するファイルを指定
  • -A ユーザエージェントの書き換え:iphoneやandroidやその他で出力が異なる場合の確認に便利
  • -v リクエストヘッダやレスポンスヘッダを表示
curl -v -H Host:virtual_host_name http://127.0.0.1/ -b ck0.txt -c ck1.txt -A "oreore_ua"

datetimepickerでの、あり得ない日付の入力制御の覚え書き

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

railsのビューで、フォームを使って日付を入力させたい時、

datetimepickerを使っていました。

datetimepickerはJSでテキストフィールドに付加する事で、カレンダー表示で日付・時間を選択させる事のできる便利なプラグインです。

ただ、テキストエリアに追加するので、ユーザーがテキストフィールドに直接日付を入力する事も出来てしまいます。

それ自体は別に問題ない事ですが、日付じゃないテキストや、あり得ない日付を入力されてしまう場合もあります。

日付じゃないテキストについては、datetimepickerが勝手に判断してテキストフィールドの中を空に置き換えてくれるのですが、

あり得ない日付に関しては、

「2000-04-31」-> 「2000-05-01」に変換してくれる

「2000-05-32」-> 変換してくれない!

となるので、フォームでもらった値を、

モデルインスタンスのDateTime型のカラムに代入しようとするとエラーを吐きます。

@model = Model.new(date: param[:model][:date])
 -> ArgumentError

どうやら31日までは,datetimepicker側で勝手に判断して変換してくれるようですが、

32日を超えると「ありえない日付」となり、変換はしてくれないようです。

これでは困るので、色々と解消しようとした顛末です。

 1. validationで弾けないか?

モデルにvalidateを設置して、フォームを送ったら「不正な値です」などのアラートを表示させたいと思いましたが、

よくよく考えると、validate発火前の、インスタンスへの代入時点でエラーになっているので、ちょっと厳しそうです。

コントローラの方でチェックするのも考えましたが、フォームを使うコントローラ全てにチェックを入れないといけなかったりするので、

あまり良くなさそうです。

 2. JSで弾く(onBlur編)

そもそもそのような入力が出来なければ良い話なので、JSで入力制御を入れる事にしました。

ちなみに、datetimepicker導入部のJSはこんな感じ。

$('.date_text_field').datetimepicker({
  format: 'YYYY-MM-DD',
  language: 'ja'
});

今回は日付だけ取りたいので、時間までは取らないようにしています。

このままだと入力制御がかかってないので、onBlurのイベントハンドラを使ってみます。

$('.date_text_field').datetimepicker({
  format: 'YYYY-MM-DD',
  language: 'ja'
});

$('.date_text_field').onBlur = function(){
  if ($(this).val() != '') {
	  var inputDate = new Date($(this).val());
	  if (isNaN(inputDate.getTime())) {
	    $(this).val('');
	  }
  }	
}

「isNaN(inputDate.getTime())」でテキストフィールドに入力された値が日付として正当か判断しています。

これでテキストフィールドに「2000-03-34」のようなおかしい日付を入力して、フォーム送信ボタンを押すと・・・・

テキストフィールドの中身が空になりました!

・・・しかし、onBlurを使っているので、テキストフィールドからフォーカスが外れれば空になってくれるのですが、

テキストフィールドに入力した状態で、エンターキーを押してそのままフォーム送信したりすると、、

フォーカスは外れないので、そのまま値が送られてしまい、やはりArgumentErrorになってしまいました。

 3. JSで弾く(onsubmit編)

ならば、フォーム全体がsubmitされたタイミングで入力判定すれば良いじゃないか!

という訳で、フォーム全体のイベント監視をさせるようにしてみます。

$('.date_text_field').datetimepicker({
  format: 'YYYY-MM-DD',
  language: 'ja'
});

$('form').on('submit', function(){
  picker();
 });

function picker(){
  $('.date_text_field').each(function(){
    if ($(this).val() != '') {
      var inputDate = new Date($(this).val());
      if (isNaN(inputDate.getTime())) {
        $(this).val('');
      }
    }
  });
}

formタグを監視するようにしてみました。

フォームがsubmitされると、date_text_fieldクラスを探し出し、日付として不正の場合値を空にします。

これで再度日付入力用のテキストフィールドに「2000-03-34」を入力してフォーム送信・・・

-> 送信直前にフォームの内容が空になりました!

 4. JSで弾く(解決編)

上記の方法で良いかと思ったのですが、

一画面に複数formタグがあったときは、そもそもformにJS監視させたくないときは?などの疑問が残ります。

そんな中、とてもスマートな解決法を教えて頂きました。

$('.picker_date').datetimepicker({
  format: 'YYYY-MM-DD',
  language: 'ja'
}).on('dp.error', function(e) {
  $(e.target).val('');
});

これだけです。formに対してのイベントリスナーもいりません。

dp.errorイベントを拾うことで、入力された値に不整合があると、値を空にすることが出来ます。

フォーム送信時だけでなく、テキストフィールドからフォーカスが移ったときにも評価が走ります。

ということで無事、datetimepickerへの入力制御を入れる事が出来ました!

便利なBootstrapデザイン

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rickNo40です。
管理画面デザインをデザイナーが作ることはあまりないので、各ブラウザの調整など苦労したりします。
そこで、簡単に綺麗な管理画面が作成できるのがBootstrapです。
少々触る機会があったのでよく使ったデザインを少しだけ紹介下記全てクラス名

「col-md-?」
?部分は1~12の数字になります。
これは、1つのブロックを12分割し指定した分割分の領域を使用します。
入力フォームの幅を調整したり、
1行に幾つか要素を置くときに2,4,2,4で分割したりと便利です。

「text-left,text-center,text-right」
左寄せ・中央寄せ・右寄せですね。
使いたい時に、あぁまたcss設定しなきゃなんてならず、class名指定するだけなので楽です。

「table」
テーブルの基本デザイン
管理画面の大抵の画面がこれを使用して作ればいいです。

「table-striped」
テーブルで1行毎に色を変えてくれます。
縦結合する場合はだめですが、一覧表示するときは良い感じです。

「table-bordered」
テーブルの枠を表示します。
線があると無いとではやっぱり引き締まり具合が違います。
提供する管理画面なんかだったらborderはつけたが方がいいかと自分は思います。

「table-condensed」
テーブルの余白を縮めます
bootstarp基本的に余白多いんですよね。
1画面に収める量を増やしたい場合は、つけたほうがいいです。

「form-group,form-control」
入力フォーム系にはとりあえず付けておけばいいかと

「input-groupで囲んでinput-group-addon」
入力フォームの前や後ろに単位などをつけたりできます。
普通に書くと入力フォームと高さが微妙に違ってたりなんてことがあるので結構便利です。

と、こんな感じでルールが決まっているとそれを設定するだけなのでとても楽です。
Bootstrapでつくったからといって必ず綺麗になるわけでもありませんが、
少し試してみるのもいいかと思います。

AtomをEclipse風にカスタマイズ【パッケージ編】

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

無料のWeb開発向けテキストエディタ「Atom」を、Eclipse風にカスタマイズする方法をご紹介します。

今回はパッケージ編です。

※「設定・使い方編」と「パッケージ編」の2部構成

※注)以下はMacの設定となります。

 キーバインドをEclipse風にする

eclipse-keybindings

このパッケージはその名の通り、AtomのキーバインドをEclipseに近づけてくれます。

私はEclipseでよく以下のショートカットを使用しますが、もちろんこれらもそのまま使えます。

・全文検索:control + H

・ファイル検索:command + shift + R

 ファイルツリーに拡張子毎のアイコンを表示

file-icons

Eclipseだとデフォルトでファイルツリー上のファイル名の横に拡張子毎のアイコンが表示されていて、見栄えがよいです。

これを実現するのがこちらのパッケージ。

 メソッドツリーを表示

symbols-tree-view

サイドバーにメソッドの一覧を表示してくれるパッケージです。

コードが長いクラスを読む際に便利です。

 日本語化

japanese-menu

好みの問題ですが、Eclipse使ってる方はPleiadesで日本語化されている方が多いと思うので、こちらも入れておくとEclipseに一歩近づく(?)

 ツールバー

tool-bar

tool-bar-main

ツールバーが表示されるようにするパッケージです。

tool-barが本体ですが、本体だけだと自分でツールバーの内容を設定しないといけません。

tool-bar-mainを入れるとよく使いそうなツールバーを自動で設定してくれます。

こちらのパッケージもEclipseに近づけることがメインで実用性は低め・・。

また、デフォルトだとツールバーのアイコンが大きすぎるので、パッケージ側の設定で小さくします。

Atom->環境設定->パッケージ->tool-bar->設定(※設定が表示されていない場合はリスト自体をクリックすると表示されます)->Settings->

 icon Size:16px

 ダブルクリックした単語をハイライト

highlight-selected

Eclipseでも地味に便利なこの機能。単語をダブルクリックすると同じ名前の単語をハイライト表示してくれます。

ただ、背景が白のテーマにしている場合、どこがハイライトされているか分かり辛いため、こちらも設定を変更します。

Atom->環境設定->パッケージ->tool-bar->設定->Settings->

 ■Highlight Background

 ■Light Theme

設定・使い方編へ

http://doruby.kbmj.com/oneafter999_on_rails/20160516/Atom_Eclipse_

Docker を試してみる(2.5)〜Sentryを試す

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

今回はちょっと脱線して SentryというサービスをDocker上で実行してみます。

なお、Sentryはアプリケーションのログを収集して見やすくしてくれるサービスです。

https://getsentry.com/welcome/

SaaS型とオンプレ型が無償で提供されています。

sentry のオフィシャルイメージが用意されていますので、そちらを使います。

https://hub.docker.com/_/sentry/

基本的にこの手順に従っていくだけです。

事前準備: redisとPostgreSQLを起動

これもコンテナで起動します。

$ docker run -d --name sentry-redis redis
$ docker run -d --name sentry-postgres -e POSTGRES_PASSWORD=sentry -e POSTGRES_USER=sentry postgres

シークレットキーの作成

シークレットキーを出力します。

コンテナの起動時に使いますので覚えておいてください。

$ docker run --rm sentry generate-secret-key
hogehogesecretkey

データベースの作成

$ docker run -it --rm -e SENTRY_SECRET_KEY='hogehogesecretkey' --link sentry-postgres:postgres --link sentry-redis:redis sentry upgrade

途中で「ユーザを作るか?」ときかれますので、作っておきましょ。

linkオプションについて

docker run コマンドで –link というオプションが使われています。

これはコンテナ同士を通信させる簡単な方法です。

リンクしたコンテナの情報(IPなど)を共有して参照できるようにします。 –link コンテナ名(:エイリアス) で指定します。

sentryのコンテナ中でエイリアス(postresやredis)を使って参照(REDIS_PORT_6379_TCP_ADDRなど) しているので、上記の通りに指定しないと動きません。

サーバの起動

$ docker run -d -p 9000:9000 --name my-sentry -e SENTRY_SECRET_KEY='hogehogesecretkey' --link sentry-redis:redis --link sentry-postgres:postgres sentry

ホストの9000版アドレスにポートフォワードしてるので、http://localhost:9000 や http://192.168.33.11:9000 のようにしてブラウザから確認できます。

ワーカーの起動

デフォルトの設定で、workerのコンテナも必要なようなので起動しておきます。

$ docker run -d –name sentry-celery-beat -e SENTRY_SECRET_KEY=’hogehogesecretkey’ –link sentry-postgres:postgres –link sentry-redis:redis sentry celery beat $ docker run -d –name sentry-celery1 -e SENTRY_SECRET_KEY=’hogehogesecretkey’ –link sentry-postgres:postgres –link sentry-redis:redis sentry celery worker

Docker を試してみる(2)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Docker を試してみる(1) の続きです。

超基本ですが重要な run & exec コマンドの説明です。

 runコマンド

dockerの中で一番大事なコマンドです。コンテナを起動しコマンドを実行します。

オプションが非常にたくさんありますがリソースの設定が多いので覚えるのは少しだけ。

–nameコンテナの名前を指定する
-it標準入力を開き仮想端末を割り当てる。シェルを使うときに使う
-dバックグラウンドでコンテナを実行する。サーバとして使うときなど
-e環境変数を指定する
-pポートフォワーディングする。ホスト->コンテナ
–rm実行が終わったら コンテナを削除する
-vボリュームを割り当てる。ホストのディスクをコンテナで使いたいときに使う

実行例)

コンテナ上でシェルを実行する

対話型シェルを起動します。# のプロンプトはシェルに接続した状態です。

exitでコンテナと切断し、コンテナは終了します。終了後コンテナは削除されます。

$ docker run -it --rm ubuntu bash
root@92e455bcb613:/# 

なお、ubuntuコンテナは、コマンド省略時はbashを起動するようになっているので、

bashをつけなくても結果は同じです。

$ docker run -it --rm ubuntu
root@92e455bcb613:/# 

コマンドのみ実行する

プロセスを表示させてみます。psコマンドが実行されコンテナは終了します。終了後コンテナは削除されます。

$ docker run --rm ubuntu ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  25968  1236 ?        Rs   09:27   0:00 ps aux

サーバとして実行する

memcachedサーバとして起動します。DockerHubのmemcachedイメージを使います。

次のコマンドでは memcached というコンテナ名でサーバを起動します。

16進数のIDを出力するのみでコマンドは終了します。

$ docker run -d --name memcached memcached
b40a0f915d7ade1b6ad91c7cc9b2257da1013c21ff61821cc1a59d597b9f734b

docker ps コマンドで実行状況を確認すると実行されていることが確認できます。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
a40a0f915d7a        memcached           "/entrypoint.sh memca"   About a minute ago   Up 59 seconds       11211/tcp           memcached

コンテナを停止するには stop コマンドを使います。さらにコンテナを削除する場合は rmコマンドを使います。

$ docker stop memcached
$ docker rm memcached 

ポートフォワーディングする

ホストのアプリからmemcachedを使いたい、別のホストから接続したいときはポートフォワーディングを行います。

次のコマンドは ホストの11212ポートからコンテナの11211(memcachedのポート)に転送します。

$ docker run -d --name memcached -p 11212:11211 memcached
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                      NAMES
ec0da0dc6aba        memcached           "/entrypoint.sh memca"   5 seconds ago       Up 4 seconds        0.0.0.0:11212->11211/tcp   memcached

上記の出力の、

0.0.0.0:11212->11211/tcp 

任意の接続元からホストの11212ポートへのアクセスを許可し、コンテナの11211ポートへの転送を許可します。

ホストから memcached に接続してみます。

$ telnet localhost 11212
set foo 0 60 3
bar
STORED
get foo
VALUE foo 0 3
bar
END

 execコマンド

runコマンドと同様にコンテナ上でコマンドを実行しますが、

こちらは起動中のコンテナに対してのみ実行可能です。

$ docker exec memcached ps axu
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
memcache     1  0.0  0.2 313740  2228 ?        Ssl  09:43   0:00 memcached
memcache    14  0.0  0.1  17492  1136 ?        Rs+  09:54   0:00 ps axu

migrationファイルの記法メモ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Ruby on Rails でDBのテーブル作成・カラム編集などに使う

migrationファイル。ファイルを作っておけば「rake db:migrate」 のコマンドで色々な対応が出来ますが、

それぞれ書き方があり、今までにすこし引っかかったものを中心にまとめてみました。

 change と up/down

changeとup/downはどちらもmigration実行時・ロールバック時の処理を記述するメソッドです。

changeの場合

class AddNameToPlayers < ActiveRecord::Migration
  def change
    add_column :players, :name, :string
  end
end  

up/downの場合

class AddNameToPlayers < ActiveRecord::Migration
  def up
    add_column :players, :name, :string
  end

  def down
    remove_column :players, :name
  end
end  

up/downはそれぞれ実行時・ロールバック時の操作をかく必要がありますが、

changeは実行時だけの操作を書くと、ロールバック時に処理を反転させて実施してくれます。とっても便利です。

なので、全部changeで書いていた所、ある時エラーになりました。

class RemoveNameToPlayers < ActiveRecord::Migration
  def change
    remove_column :players, :name    <- ロールバックできない
  end
end  

カラムのremove処理などは、changeだけだと、カラムの型情報等が含まれないため、反転出来ないのが原因でした。

removeのmigrationの時はup/downを使うようにしましょう。

 定型外の型

マイグレーションで使えるデータ型には以下のようなものが用意されています。

integer
float
string
text
date
time
boolean
...  

ただある時、integer型のカラムをBIGINT型に変更したい、となったとき、

bigintはそのままmigrationファイルに記述してもダメでした。

  def change
  	change_column :bank, :money, "BIGINT UNSIGNED"
  end 

 カラム位置指定

普通にmigrationファイルでカラムを増やすと、どんどん最後尾にカラムが足されて行きます。

その際、「このカラムは、カラムAとカラムBの間に入れたい!」となった時。

afterを使いました。

  def change
    add_column :test_table, :insert_column, :string, after: "column_a"
  end

このようなmigrationファイルにすると、column_aの後にinsert_columnが追加されます。

おまけ コメント

DBが増えてくると、このカラムは何のカラムだったか、と分からなくなってきます。

migrationファイルから、コメントを付けておく事が出来ます。

  def change
    add_column :test_table, :encrypted_password, :string, comment:"パスワード"
    add_column :test_table, :name, :string, comment:"ログインアカウントネーム"
  end

このようなmigrationファイルを作り、DB構造を見てみると、

各カラムにコメントが入ります。

MySQL DATETIME型のミリ秒の扱いについて

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

MySQL DATETIME型のミリ秒の扱いについて

MySQLのDATETIME型のカラムに対して、ミリ秒付きデータを書き込む際の動作について、

バージョンによって挙動が異なるので注意が必要です。

MySQL 5.5 までは、強制的に切り捨てされて格納、MySQL 5.6 以降は四捨五入されて格納されるという動作になっています。

実行例

 [MySQL 5.5]

テーブル

mysql> show columns from hoges;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| data  | varchar(255) | YES  |     | NULL    |                |
| time  | datetime     | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+

書き込むデータ

mysql> SET @time1 = "2016-04-28 12:00:00.100";
mysql> SET @time2 = "2016-04-28 12:00:00.499";
mysql> SET @time3 = "2016-04-28 12:00:00.500";

mysql> SELECT @time1, @time2, @time3;
+-------------------------+-------------------------+-------------------------+
| @time1                  | @time2                  | @time3                  |
+-------------------------+-------------------------+-------------------------+
| 2016-04-28 12:00:00.100 | 2016-04-28 12:00:00.499 | 2016-04-28 12:00:00.500 |
+-------------------------+-------------------------+-------------------------+
1 row in set (0.00 sec)

データ格納結果

mysql> INSERT INTO hoges (data, time) VALUES (@time1, @time1);
mysql> INSERT INTO hoges (data, time) VALUES (@time2, @time2);
mysql> INSERT INTO hoges (data, time) VALUES (@time3, @time3);

mysql> select * from hoges;
+----+-------------------------+---------------------+
| id | data                    | time                |
+----+-------------------------+---------------------+
|  3 | 2016-04-28 12:00:00.100 | 2016-04-28 12:00:00 |
|  4 | 2016-04-28 12:00:00.499 | 2016-04-28 12:00:00 |
|  5 | 2016-04-28 12:00:00.500 | 2016-04-28 12:00:00 |
+----+-------------------------+---------------------+

 [MySQL 5.7]

テーブル

mysql> show columns from hoge;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | MUL | NULL    | auto_increment |
| data  | varchar(255) | YES  |     | NULL    |                |
| time  | datetime     | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

書き込むデータ

mysql> SET @time1 = "2016-04-28 12:00:00.100";
mysql> SET @time2 = "2016-04-28 12:00:00.499";
mysql> SET @time3 = "2016-04-28 12:00:00.500";

mysql> SELECT @time1, @time2, @time3;
+-------------------------+-------------------------+-------------------------+
| @time1                  | @time2                  | @time3                  |
+-------------------------+-------------------------+-------------------------+
| 2016-04-28 12:00:00.100 | 2016-04-28 12:00:00.499 | 2016-04-28 12:00:00.500 |
+-------------------------+-------------------------+-------------------------+
1 row in set (0.00 sec)

データ格納結果

mysql> INSERT INTO hoge (data, time) VALUES (@time1, @time1);
mysql> INSERT INTO hoge (data, time) VALUES (@time2, @time2);
mysql> INSERT INTO hoge (data, time) VALUES (@time3, @time3);

mysql> select * from hoge;
+----+-------------------------+---------------------+
| id | data                    | time                |
+----+-------------------------+---------------------+
|  1 | 2016-04-28 12:00:00.100 | 2016-04-28 12:00:00 |
|  2 | 2016-04-28 12:00:00.499 | 2016-04-28 12:00:00 |
|  3 | 2016-04-28 12:00:00.500 | 2016-04-28 12:00:01 |
+----+-------------------------+---------------------+
3 rows in set (0.00 sec)

上記のように、同じデータを書き込んだ場合でも、結果が異なったものになっている。

 おまけ

Railsでの動作について

RailsのActiveRecord経由で記録した場合、

Rails ~4.1だと、ミリ秒は切り捨てされて、

Rails 4.2~ だと、ミリ秒も含めてSQL文が作られる。

VirtualBox のHDDサイズ変更

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

VirtualBox のHDDサイズを変更する方法を備忘の為に記載

 環境

ホストOS: Windows 7

ゲストOS: CentOS 6

 手順

仮想マシンが起動している場合はシャットダウンする。
管理者としてコマンドプロンプトを開く。
対象のHDDのUUIDを確認しておく。
cd "c:\Program Files\Oracle\VirtualBox"
VBoxManage -nologo list hdds
サイズを変更する
VBoxManage modifyhd (UUID) --resize (サイズ(MB))

以下は50GBに変更する場合の例

VBoxManage modifyhd f7689c77-bccd-44fa-9304-3f1637aa00c2 --resize 51200

tortoiseSVNで、あるリビジョンとあるリビジョンの差分ファイルをエクスポートする

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

たまごです。

SVN上のあるリビジョンとあるリビジョンの差分ファイルを抽出したい時って、たまにありますよね。その際、自分がよく使う方法を解説したいと思います。

 tortoiseSVNでリビジョン間の差分ファイルを抽出する方法

使うのは、tortoiseSVNです。

  1. 対象ディレクトリで、show logする
  2. 任意のリビジョンを二つ選択し、Compare revisionsする
  3. ファイルを全選択し、右クリックでExport selections to…する

これでOKです。

削除ファイルがいらない場合は、手順の3で全選択せず、Actionでソートしたうえで、Deleted以外を選択するようにしましょう。

 上記方法で失敗する場合

SVNが貧弱だと、3のExport selections to…した際にエラーが出たりします。

そういう時は、仕方ないので、ファイルを選択した状態でCtr+cします。

これで表示されているパスがコピーされるので、後はコマンドプロンプト等使って、地道にコピーします。

(パスは表示されているとおりにコピーされるので、長いパスが省略されないように、なるべくFileカラムの横幅を広くして、コピーしてあげるとよいかんじです)

【JMeter】HTTPリクエストでPATCHメソッドを使用する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Apache JMeterでPATCHメソッドを使用する方法

 概要

Apache JMeterでPATCHメソッドを使用したときに、色々うまくいかなかったので、試したことを記録しておきます。

JMeterの基本的な使い方については割愛します。

【Version】

Apache JMeter Version 2.13

 はじめに

JMeterでは、HTTPプロキシサーバを使用すると、ブラウザの操作を記録することができます。

その際、PATCHメソッドを使用している画面の操作で、エラーが発生しました。

記録されたJMeterのHTTPリクエストサンプラーを見てみると、メソッドがPATCHになっており、Parametersにリクエストで送るパラメータが表示されています。

 解析

一見問題なさそうですが、このHTTPリクエストを実行して、リスナー -> 結果をツリーで表示の「リクエスト」タブを見てみると、

PATCH data:

Content-Length: 0

となっており、リクエストボディが送信されていないようです。

ちなみに、メソッドをPOSTに変更して実行すると、リクエストで送るパラメータに設定した値が送信されていることが確認できます。

 解決方法

Parametersタブの隣にあるBody Dataタブを押すと、Warningメッセージが出ます。ここで、リクエストで送るパラメータをすべて削除するとBody Dataタブに切り替えることができます。

ここに、リクエストボディの値をそのまま貼り付けます。

(筆者はChromeの検証ツールからForm Dataをコピーしました。エンコードされた値を貼り付ける必要があるので、view sourceからコピー。)

 実行

再度実行してみます。

リスナー -> 結果をツリーで表示の「リクエスト」タブを見てみると、

PATCH data:

XXXXXXX%5AAAAAAAAAAAAAA%5D=true

Content-Length: 31

リクエストボディが正常に送信できました。

結果も正常終了になっています。

 余談

本題とは直接関係ありませんが、このとき動かしていたWebアプリはRailsアプリで、Ajaxでフォームの内容を送信していたので、「X-CSRF-Token」をリクエストヘッダーに設定する必要もありました。

以上です。

PUTメソッドも同様の動きをするようなので、同じ方法で解決できます。

CVE-2016-0800のOpenSSL脆弱性「DROWN」について、SSLv2が無効かどうかすぐに確認する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。アピリッツの本多です。

2016年03月01日にOpenSSLの新たな脆弱性が発表されました。

SSLv2が有効な環境ではTLSセッションの暗号化が破られる攻撃を受ける可能性があるというものです。

詳しくは以下の資料を参照ください。

DROWN: Breaking TLS using SSLv2

https://drownattack.com/drown-attack-paper.pdf

その他重要度の低い修正も適用されているため、opensslの更新は行ったほうが良いと思いますが、取り急ぎ、SSLv2が現在有効なのかを確かめたいと思います。

今回の脆弱性の情報と合わせて、各ドメインの脆弱性をチェックするためのサイトも公開されました。

DROWN Attack

しかしながら、サブドメインごとにシステム(ないしSSL証明書)が異なる場合にチェックが上手く出来なかったため、centos上でコマンドを叩いて確認を取りたいと思います。

コンソール上で以下のコマンドを入力します

$ openssl s_client -connect (ドメイン名):443 -quiet # プロトコルを指定せずに接続確認

$ openssl s_client -ssl2 -connect (ドメイン名):443 -quiet # SSLv2で接続確認

試しに、グーグルにアクセスしてみたところ、以下の様な応答が返って来ました。

$ openssl s_client -connect www.google.com:443 -quiet

depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority

verify return:1

depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA

verify return:1

depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2

verify return:1

depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = www.google.com

verify return:1

$ openssl s_client -ssl2 -connect www.google.com:443 -quiet

139632633231176:error:1407F0E5:SSL routines:SSL2_WRITE:ssl handshake failure:s2_pkt.c:429:

SSLv2を指定した場合、接続エラーが返って来ました。

このように、グーグルでは「httpsで通信できるが、SSLv2は無効にしている」という事がわかります。

このコマンドはサブドメイン別にサーバーが分かれている場合でも確認が取れますので、もし同じ状況で上記サイトでの確認が取れない場合、今回紹介したコマンドを使って確認してみてはいかがでしょうか。

そしてSSLv2が有効になっている場合は各自対応しましょう。

もちろん、SSLv2が無効になっている場合でもopensslの更新は行ったほうが良いと思います。

最近人気な記事