まだ重たいCMSをお使いですか?
毎秒1000リクエスト を捌く超高速CMS「adiary

2019/01/20(日)Net::SMTPでSMTP AUTHのDIGEST-MD5に失敗する問題

さくらインターネットのメールサービスを使用して、SMTP AUTHのDIGEST-MD5認証を使うと送信に失敗する問題を調べてみました。

問題の詳細

PerlのNet::SMTPモジュール等を使用して、さくらインターネットのメールサービスを使い、SMTP Authでメールを送信する失敗します。

ネットで検索するとPerlのNet::SMTPの問題と書かれていたりもしますが、実際にはさくらインターネット側の問題のようです

SMTPのログを取ってみるとこんな感じになります。

> 220 www1234.sakura.ne.jp ESMTP Sendmail 8.15.2/8.15.2; Sun, 20 Jan 2019 21:25:22 +0900 (JST)
EHLO localhost.localdomain
> 250-www1234.sakura.ne.jp Hello xxxx [192.168.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE 209715200
250-DSN
250-AUTH CRAM-MD5 DIGEST-MD5 LOGIN PLAIN
250-STARTTLS
250-DELIVERBY
250 HELP
> AUTH DIGEST-MD5
(decoded) nonce="UOM8WDtDO5/ZOCm+tpQaxjRbHOCM5Y5CKekiBEVlmU8=",
		realm="www1234.sakura.ne.jp",
		qop="auth,auth-int,auth-conf",
		cipher="c4-40,rc4-56,rc4,des,3des",
		maxbuf=8192,charset=utf-8,algorithm=md5-sess
>(decoded) authzid="smtp@example.jp",charset=utf-8,cipher=rc4,
>		cnonce="eedacf2b08dc6c60a2a799ee59188455",
>		digest-uri="smtp/XXXXXXXX.sakra.ne.jp",
>		nc=00000001,nonce="UOM8WDtDO5/ZOCm+tpQaxjRbHOCM5Y5CKekiBEVlmU8=",
>		qop=auth-conf,realm="www1236.sakura.ne.jp",
>		response=c54d120c415a6e3d5cd5469b36faa7e1
>		username="smtp@example.jp"
(decoded) rspauth=fc45f7aa080db4dfb73d1b65a1f48d50
>
235 2.0.0 OK Authenticated
> MAIL FROM:<test@example.jp>
Net::SMTP: Net::Cmd::getline(): unexpected EOF on command channel:

ソースに手を入れていろいろ調べてみたところ、

235 2.0.0 OK Authenticated

を受け取ったあと、どんなコマンドを送っても切断されているようです。コマンドを送るまでソケットは生きているのですが、改行してコマンドを確定した瞬間にソケットの強制切断を喰らいます。これを回避するために、なにか特殊な暗号をしゃべるべきなのかもしれませんが皆目検討が付きません。

問題の切り分け

問題を切り分けるために、自前でSMTP AUTH / DIGEST-MD5認証対応のpostfixサーバを構築して実験してみたところ、問題なく送信できました。これにより、さくらインターネット側の不具合の可能性がかなり濃厚になってきました。

なぜ問題が放置されているのか?

ほとんどのメーラー(メールクライアント)は、SMTP AUTHの認証方法を細かく指定することができません。内部で良きにはからってくれるので、仮にDIGEST-MD5認証に挑戦して失敗しても、CRAM-MD5等の他の認証方法を試します。

PerlのNet::SMTPモジュールではなぜ問題が起こるのか?

Net::SMTPモジュールは「EHLO」で返された「AUTH」の中で、最初に対応しているものを認証手段として選択します。失敗しても次の認証方法を試したりはしません。結果として、さくらインターネットのメールサービスと組み合わせて使用すると、SMTP Authに失敗します。

ひとこと

さくらインターネットちゃんとしてください(笑)*1

2018/12/26(水)Twitterウイジェットの仕様と構造メモ (2018/12)

Twitter-widgetの仕様がまた変わっていたのでメモ。

また仕様が変わったようです 2022/08/26

iframe内の要素を以下のようなURLから読み込むようになったので、クロスドメイン制約からデザイン変更はほぼ不可能です。

https://syndication.twitter.com/srv/timeline-profile/screen-name/nabe_abk

変わったこと

  • widget-idが不要になりました。
  • https://publish.twitter.com/ にTwitter URLを入れると埋め込みコードを取得できます。

タイムライン埋め込みコードの例

<a class="twitter-timeline" href="https://twitter.com/nabe_abk" data-chrome="[options]">Tweets by nabe_abk</a>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

シンプルになりました。

aタグのオプション

  • data-width="600" 表示の横幅
  • data-height="600" 表示の縦幅
  • data-theme="dark" ダークテーマ(デフォルトは light)
  • tweet-limit="10" ツイート数
  • data-dnt="true" Do not track
  • data-chrome(いくつか無効な模様)
    • noheader ヘッダ非表示
    • nofooter フッタ非表示
    • noborders 境界線非表示
    • noscrollbar スクロールバー非表示
    • transparent 背景透過

Twitterの公式情報

展開されるHTML

iframeに展開されます。

<iframe id="twitter-widget-0"
	scrolling="no" allowtransparency="true" allowfullscreen="true"
	class="twitter-timeline twitter-timeline-rendered"
	style="position: static; visibility: visible; display: inline-block; width: 100%; height: 600px; padding: 0px; border: medium none; min-width: 180px; max-width: 100%; margin-top: 0px; margin-bottom: 0px; min-height: 200px;"
	data-widget-id="profile:nabe_abk" title="Twitterタイムライン"
	frameborder="0"></iframe>

iframeの中身

<div class="timeline-Widget" data-iframe-title="Twitterタイムライン" lang="ja">

<div class="timeline-Header timeline-InformationCircle-widgetParent">
	<div class="timeline-InformationCircle">
		<a href="" class="Icon Icon--informationCircleWhite js-inViewportScribingTarget"
			<span class="u-hiddenVisually">Twitter広告の情報とプライバシー</span>
		</a>
	</div>
	<h1 class="timeline-Header-title u-inlineBlock">
		<span><a href="">‎@nabe_abk</a>さんの</span>ツイート
	</h1>
</div>

<div class="timeline-Body customisable-border">
	<div class="timeline-Body-notification timeline-NewTweetsNotification new-tweets-bar">
		<button class="timeline-ShowMoreButton">新しいツイートを読み込む</button>
	</div>

	<div class="timeline-Viewport">
		<ol class="timeline-TweetList">
		<li class="timeline-TweetList-tweet customisable-border">
			※1つのツイート(以下)
		</li></ol>

		<div class="timeline-LoadMore">
			<button class="timeline-LoadMore-prompt timeline-ShowMoreButton customisable">
				ツイートをさらに表示
			</button>
			<p class="timeline-LoadMore-endOfTimelineMessage no-more-pane">
				このタイムラインのツイートは以上です。
			</p>
		</div>
	</div>
</div>

<footer class="timeline-Footer u-cf">
	<a class="u-floatLeft"  href="">埋め込む</a>
	<a class="u-floatRight" href="">Twitterで表示</a>
</footer>

</div>

1つのツイート詳細。

<div class="timeline-Tweet  u-cf js-tweetIdInfo js-clickToOpenTarget">
	<div class="timeline-Tweet-brand u-floatRight">
		<div class="Icon Icon--twitter " title="Twitterで表示">
	</div>

	<!-- リツイート時のみ -->
	<div class="timeline-Tweet-retweetCredit">
		<div class="timeline-Tweet-retweetCreditIcon">
			<div class="Icon Icon--retweetBadge "></div>
		</div>
		XXXXさんがリツイートしました
	</div>

	<div class="timeline-Tweet-author js-inViewportScribingTarget">
		<a class="TweetAuthor-avatar Identity-avatar u-linkBlend" href="">
			<img class="Avatar" src="***.jpg">
		</a>
		<div class="TweetAuthor js-inViewportScribingTarget">
			<a class="TweetAuthor-link Identity u-linkBlend" href="">
			  <div class="TweetAuthor-nameScreenNameContainer">
			    <span class="TweetAuthor-decoratedName">
			        <span class="TweetAuthor-name Identity-name customisable-highlight">nabe@abk</span>
			    </span>
			    <span class="TweetAuthor-screenName Identity-screenName">@nabe_abk</span>
			  </div>
			</a>
		</div>
	</div>

	<p class="timeline-Tweet-text" lang="ja">(ツイート内容)</p>

	<div class="timeline-Tweet-metadata">
		<a href="" class="timeline-Tweet-timestamp">
			<time datetime="2018-12-22T00:00:00+0000">
				2018年12月22日
			</time>
		</a>
	</div>

	<ul class="timeline-Tweet-actions" aria-label="ツイートアクション">
		略
	</ul>
</div>

2018/08/24(金)[RFC]WebPush実装まとめ(Chrome/Firefox/Android/Edge)

2013/06/12(水)twitter埋め込みタイムラインのデザイン変更方法

※新しい記事に移動しました


API1.0の廃止と共にTwitterウイジェットが使えなくなってしまいました。新しい埋め込みタイムラインは通常の方法では細かいデザイン(配色)を変更することができないので、小細工してデザイン変更したまとめ。

続きを読む

2012/08/30(木)Twitter Cardsの仕様メモ(ドキュメントの適当日本語訳)

Twitter公式webタイムライン中にコンテンツを埋め込めるTwitter Cardsについての自分用メモ。あとで実装する用。

Twitter Cardsとは?

twitter_cards.png

TwitterをWebサイトから見ているときに、クリックするとTwitpicの画像やYoutubeの動画がそのままタイムライン上で表示されたりするあの機能のことです。

このTwitter Cardsは誰でも対応サービスを作ることができます。

大まかな流れ

  1. 公式のドキュメントをよく読んで
  2. 3種類のTwitter Cardsのどれを実装するか決めて
    • summary: デフォルト。タイトルと説明とサムネイルを表示。
    • photo: 写真を表示。
    • player: 動画や音のメディアを表示
  3. サイトに必要なmetaタグを実装して
  4. apply to participateからTwitterにCardsを申請。
  5. Twitterに認可されればカードが表示されるようになる。

申請結果は申請フォームに入力したメールアドレスに送られてきますので、忘れず確認してください。

メタタグ要素

<meta name="twitter:card" content="summary">

以上のようなデータを、そのページの<HEAD>内に出力する。

プロパティ必須要素か説明
su-ph-pl-
twitter:cardYesYesカードのタイプ。「summary」か「photo」か「player」*1
twitter:urlYesYesYesコンテンツのCanonical URL
twitter:titleYesコンテンツのタイトル。最大70文字(70 characters)
twitter:descriptionYesコンテンツの説明。最大200文字(200 characters)
twitter:image:srcYesYesコンテンツを象徴する画像のURL。*2
twitter:image:width画像の横px(アスペクト比を保持してリサイズするために必要)
twitter:image:height画像の縦px(アスペクト比を保持してリサイズするために必要)
twitter:player--YesiframeプレイヤーのURL。コンテンツが混ざってないこと。
twitter:player:width--Yesiframeの横px
twitter:player:height--Yesiframeの縦px
twitter:player:stream--生ストリームのURL。Twitterのモバイル・アプリケーション等でダイレクト再生時に使用する。「MPEG-4 コンテナ format (拡張子.mp4)」でなければならない。
twitter:player
:stream:content_type
--*3生ストリームの「MIME type/subtype」を指定(RFC 6381)。現在サポートしているのはRFC4337(MP4のMIME type)のみ。
twitter:site「@username」形式。WebサイトオーナーのTwiter ID
twitter:site:id上と一緒だが、Twitter user IDの代わりに記述する文字列。
twitter:creator「@username」形式。コンテンツ製作者のTwiter ID
twitter:creator:id上と一緒だが、Twitter user IDの代わりに記述する文字列。

補足

  • twitter:siteやtwitter:creatorはCardコンテンツのフッタに表示される。ここにTwitter IDを指定することで、そのIDのツイートに直接アクセスしたりフォローすることができる。

*1 : 省略時は「summary」を指定したとみなされる

*2 : player指定時はプラットフォームがiframesやインラインプレイヤーをサポートしてない時に表示する画像。画像はプレイヤーと同じサイズであり、縦px×横pxの値が68,600pxを超えないこと。

*3 : twitter:player:stream指定時は必須

Summary Card

  • 画像のサイズが120px×120pxを超える場合はリサイズないしはクロッピングされます。

カードのサンプル。

<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@nytimes">
<meta name="twitter:creator" content="@SarahMaslinNir">
<meta name="twitter:url" content="http://www.nytimes.com/2012/02/19/arts/music/amid-police-presence-fans-congregate-for-whitney-houstons-funeral-in-newark.html">
<meta name="twitter:title" content="Parade of Fans for Houston’s Funeral">
<meta name="twitter:description" content="NEWARK - The guest list and parade of limousines with celebrities emerging from them seemed more suited to a red carpet event in Hollywood or New York than than a gritty stretch of Sussex Avenue near the former site of the James M. Baxter Terrace public housing project here.">
<meta name="twitter:image:src" content="http://graphics8.nytimes.com/images/2012/02/19/us/19whitney-span/19whitney-span-articleLarge.jpg">

Photo Card

Twitterで表示される際、画像は次のようにリサイズされます。

媒体最大サイズ
Web横435px×縦375px
モバイル横280px×縦375px
モバイル(retina displays)横560px×縦750px

カードのサンプル。

<meta name="twitter:card" content="photo">
<meta name="twitter:site" content="@examplephotosite">
<meta name="twitter:creator" content="@sippey">
<meta name="twitter:url" content="http://example.com/photo/a/">
<meta name="twitter:title" content="Good Morning, San Francisco">
<meta name="twitter:description" content="Great view this morning">
<meta name="twitter:image:src" content="http://example.com/photo/a/image.jpg">
<meta name="twitter:image:width" content="610">
<meta name="twitter:image:height" content="610">

Player Card

生ストリーム再生時のMPEG-4でサポートするコーデックは以下のとおり。

  • Video: H.264, Baseline Profile (BP), Level 3.0。最大640x480ピクセルの30fpsまで。
  • Audio: AAC, Low Complexity Profile (LC)

カードのサンプル。

<meta name="twitter:card" content="player">
<meta name="twitter:site" content="@foobar">
<meta name="twitter:url" content="http://example.com/watch/a">
<meta name="twitter:title" content="Example Video">
<meta name="twitter:description" content="This is a sample video from example.com">
<meta name="twitter:image:src" content="http://example.com/keyframe/a.jpg">
<meta name="twitter:player" content="https://example.com/embed/a">
<meta name="twitter:player:width" content="435">
<meta name="twitter:player:height" content="251">
<meta name="twitter:player:stream" content="https://example.com/raw-stream/a.mp4">
<meta name="twitter:player:stream:content_type" content="video/mp4; codecs=&quot;avc1.42E01E1, mpa.40.2&quot;">

Twitterクローラー

Twitterはカードの情報を拾いに行く際、robots.txt を参照します。適切に許可がされていないと、Cardsは表示されません。TwitterクローラーのUser-Agentは「Twitterbot/1.0」です。

Twitterにのみ許可を出す場合の robots.txtの記述例。

User-agent: Twitterbot
Disallow:

User-agent: *
Disallow: /

正しく設定できているか確認する 2020/2/24

正しく設置できているか、実際どのように表示されるかは、以下のURLから確認することができます。申請する前に一度表示確認をしておくほうが問題が少ないでしょう。*4

*4 : これを知らず、申請したけどタグが間違ってて登録されなかったことがありました(汗)

まとめ

ドキュメントをみながら適当にまとめたメモです。実装の際には、一次情報として必ず公式ドキュメントを参照してください。またOpen Graphに関する仕様は省略しました。

記述ミス(勘違い)など発見しましたら、コメントもしくはリプライください。

adiaryなら設定不要でTwitter Cards/Facebook OGPに対応しています。

メモ

TwitterがアクセスするときのUIとIP。

199.59.148.209 - "GET /robots.txt HTTP/1.1" 200 4000 "-" "Twitterbot/1.0"

$ whois 199.59.148.209
NetRange:       199.59.148.0 - 199.59.151.255
CIDR:           199.59.148.0/22
NetName:        TWITTER-NETWORK