Skip to content

Commit

Permalink
UrlFetchTitle: リファクタリング
Browse files Browse the repository at this point in the history
refs #5

* 自己署名証明書許可が引き継がれないよう、agent を毎回作るようにした
* メッセージ生成を複数のメソッドに分割した
  • Loading branch information
ochaochaocha3 committed Mar 15, 2015
1 parent 84af1a8 commit c6ff111
Showing 1 changed file with 64 additions and 39 deletions.
103 changes: 64 additions & 39 deletions lib/rgrb/plugin/url_fetch_title/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ module UrlFetchTitle
class Generator
include ConfigurableGenerator

# HTTP ステータスコード
# HTTP ステータスの Reason-Phrase
# @see https://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv
# @see http://tools.ietf.org/html/rfc7231#section-6
HTTP_STATUS_CODES = {
HTTP_STATUS_REASON_PHRASE = {
100 => 'Continue',
101 => 'Switching Protocols',
102 => 'Processing',
Expand Down Expand Up @@ -80,62 +80,87 @@ class Generator
511 => 'Network Authentication Required'
}

def initialize(*args)
super

@agent = Mechanize.new
@agent.user_agent = "RGRB/#{RGRB::VERSION} (Creator's Network IRC bot)"
end

def configure(config_data)
@no_ssl_verify = config_data['NoSSLVerify'] || []
@agent.open_timeout = config_data['OpenTimeout']
@agent.read_timeout = config_data['ReadTimeout']
@open_timeout = config_data['OpenTimeout']
@read_timeout = config_data['ReadTimeout']
@reply_prefix = config_data['ReplyPrefix'] || 'Fetch title: '
@reply_suffix = config_data['ReplySuffix'] || ''
end

# 誰かが発言した URL にアクセスし、ページの title タグを取得する
# @param [String] タイトルを取得するページのURL
# @param [String] url タイトルを取得するページのURL
# @return [String] 取得したタイトル
def fetch_title(url)
if no_ssl_verify?(url)
@agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
agent = new_agent(url)
body =
begin
page = agent.get(url)

begin
page = @agent.get(url)
body =
if page.respond_to?(:title)
page.title
else
response = page.response
contents = [
response['Content-Type'],
response['Content-Length'].to_i.to_s(:human_size)
]
"(#{contents.join('; ')})"
http_header_to_body(page.response)
end
rescue SocketError
body = '(サーバーに接続できませんでした)'
rescue Net::HTTP::Persistent::Error
body = '(タイムアウト)'
rescue Mechanize::ResponseCodeError => response_code_error
response_code = response_code_error.response_code.to_i
reason_phrase =
if HTTP_STATUS_CODES.has_key?(response_code)
HTTP_STATUS_CODES[response_code]
else
'不明なエラー'
end
body = "(#{response_code} #{reason_phrase})"
end
rescue SocketError
'(サーバーに接続できませんでした)'
rescue Net::HTTP::Persistent::Error
'(タイムアウト)'
rescue Mechanize::ResponseCodeError => response_code_error
response_code_to_body(response_code_error.response_code.to_i)
end

"#{@reply_prefix}#{body}#{@reply_suffix}"
end

# HTTP ヘッダをメッセージに変換する
# @param [Mechanize::Headers] header HTTP ヘッダ
# @return [String]
def http_header_to_body(header)
contents = [
header['Content-Type'],
header['Content-Length'].to_i.to_s(:human_size)
]

"(#{contents.join('; ')})"
end
private :http_header_to_body

# HTTP ステータスコードをメッセージに変換する
# @param [Fixnum] response_code HTTP ステータスコード
# @return [String]
def response_code_to_body(response_code)
reason_phrase =
if HTTP_STATUS_REASON_PHRASE.key?(response_code)
HTTP_STATUS_REASON_PHRASE[response_code]
else
'不明なエラー'
end

"(#{response_code} #{reason_phrase})"
end
private :response_code_to_body

# 新しいエージェントを作り、設定して返す
# @param [String] url タイトル取得元の URL
# @return [Mechanize]
def new_agent(url)
agent = Mechanize.new
agent.user_agent =
"RGRB/#{RGRB::VERSION} (Creators Network IRC bot)"
agent.open_timeout = @open_timeout
agent.read_timeout = @read_timeout

if no_ssl_verify?(url)
agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
end

agent
end
private :new_agent

# 与えられた URL が、自己署名証明書を許可するドメインか調べる
# @param [String] 調べる URL
# @param [String] url 調べる URL
# @return [Boolean]
def no_ssl_verify?(url)
hostname = URI.parse(url).hostname
Expand Down

0 comments on commit c6ff111

Please sign in to comment.