<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Emor.in Software Development</title>
	<atom:link href="http://emor.in/dev/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://emor.in/dev</link>
	<description></description>
	<lastBuildDate>Wed, 17 Apr 2013 13:19:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>YesodでのFunctional Test</title>
		<link>http://emor.in/dev/?p=1540</link>
		<comments>http://emor.in/dev/?p=1540#comments</comments>
		<pubDate>Thu, 01 Mar 2012 10:58:19 +0000</pubDate>
		<dc:creator>Emor.in Software Development</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://emor.in/dev/?p=1540</guid>
		<description><![CDATA[追記:2012/04/05: yesod-testがリリースされた。http://hackage.haskell.org/package/yesod-test
YesodはWai上に実装されているので、機能テストにはwai-testが使用できる。で、Yesod自身のテストコードはどうなってるのかなと見たところ、どうやらHspecと併用して要件を満たしているようで、同じテスト構成で構築したので備忘録がわりにメモ。
Yesodのやり方に従ったのでHspecという選択肢にしたが、別にdoctestでもQuickCheckでもなんでもいい。
├── Application.hs
├── Foundation.hs
├── Handler
│   ├── Api
│   │   └── User.hs
│   └── Root.hs
├── Import.hs
├── LICENSE
├── Sample.cabal
├── Settings
│   └── StaticFiles.hs
├── Settings.hs
├── Tests
│   ├── SampleTest
│   │   └── Handler
│   │       └── Api
│   │           └── User.hs
│   ├── SampleTest.hs
│   └── test.hs
&#60;以下省略&#62;
.cabalの編集。extra-source-filesにTestsディレクトリ以下のファイルを追加。Flag testの追加。testフラグが立っている場合はwai-testを使用。
&#60;省略&#62;
cabal-version:     &#62;= 1.6
build-type:  [...]]]></description>
			<content:encoded><![CDATA[<p>追記:2012/04/05: yesod-testがリリースされた。<a href="http://hackage.haskell.org/package/yesod-test">http://hackage.haskell.org/package/yesod-test</a></p>
<p>YesodはWai上に実装されているので、機能テストにはwai-testが使用できる。で、Yesod自身のテストコードはどうなってるのかなと見たところ、どうやらHspecと併用して要件を満たしているようで、同じテスト構成で構築したので備忘録がわりにメモ。</p>
<p>Yesodのやり方に従ったのでHspecという選択肢にしたが、別にdoctestでもQuickCheckでもなんでもいい。</p>
<pre><code>├── Application.hs
├── Foundation.hs
├── Handler
│   ├── Api
│   │   └── User.hs
│   └── Root.hs
├── Import.hs
├── LICENSE
├── Sample.cabal
├── Settings
│   └── StaticFiles.hs
├── Settings.hs
├── Tests
│   ├── SampleTest
│   │   └── Handler
│   │       └── Api
│   │           └── User.hs
│   ├── SampleTest.hs
│   └── test.hs
&lt;以下省略&gt;</code></pre>
<p>.cabalの編集。extra-source-filesにTestsディレクトリ以下のファイルを追加。Flag testの追加。testフラグが立っている場合はwai-testを使用。</p>
<pre><code>&lt;省略&gt;
cabal-version:     &gt;= 1.6
build-type:        Simple
homepage:          http://Sample.yesodweb.com/
extra-source-files:
    Tests/SampleTest/Handler/Api/User.hs
    Tests/SampleTest.hs
    Tests/test.hs

Flag test
  description: Build the executable to run unit tests
  default: False

Flag dev
    Description:   Turn on development settings, like auto-reload templates.
    Default:       False

Flag library-only
    Description:   Build for use with "yesod devel"
    Default:       False

library
    if flag(library-only)
        Buildable: True
    else
        Buildable: False

    if flag(test)
        build-depends: wai-test
&lt;省略&gt;
</code></pre>
<p>.cabalにtest-suiteを追加。</p>
<pre><code>test-suite tests
    type: exitcode-stdio-1.0
    main-is: Tests/test.hs
    cpp-options: -DTEST
    extensions: TemplateHaskell
                QuasiQuotes
                OverloadedStrings
                NoImplicitPrelude
                CPP
                OverloadedStrings
                MultiParamTypeClasses
                TypeFamilies
    build-depends: base                          &gt;= 4          &amp;&amp; &lt; 5                  , yesod                         &gt;= 0.10.1     &amp;&amp; &lt; 0.11                  , yesod-core                    &gt;= 0.10       &amp;&amp; &lt; 0.11                  , yesod-static                  &gt;= 0.10       &amp;&amp; &lt; 0.11                  , yesod-default                 &gt;= 0.6        &amp;&amp; &lt; 0.7                  , clientsession                 &gt;= 0.7.3      &amp;&amp; &lt; 0.8                  , bytestring                    &gt;= 0.9        &amp;&amp; &lt; 0.10                  , text                          &gt;= 0.11       &amp;&amp; &lt; 0.12                  , template-haskell                  , hamlet                        &gt;= 0.10       &amp;&amp; &lt; 0.11                  , shakespeare-text              &gt;= 0.10       &amp;&amp; &lt; 0.11                  , shakespeare-css               &gt;= 0.10.7.1   &amp;&amp; &lt; 0.11                  , shakespeare-js                &gt;= 0.11.1     &amp;&amp; &lt; 0.12                  , wai                           &gt;= 1.1        &amp;&amp; &lt; 1.2                  , wai-extra                     &gt;= 1.1        &amp;&amp; &lt; 1.2                  , transformers                  &gt;= 0.2        &amp;&amp; &lt; 0.3                  , monad-control                 &gt;= 0.3        &amp;&amp; &lt; 0.4                  , yaml                          &gt;= 0.5        &amp;&amp; &lt; 0.6                  , blaze-html                    &gt;=0.4.3.1     &amp;&amp; &lt; 0.5                  , SHA                           &gt;=1.5.0.0     &amp;&amp; &lt; 1.6.0.0                  , utf8-string                   &gt;=0.3.7       &amp;&amp; &lt; 0.4                  , old-time                      &gt;=1.1.0.0     &amp;&amp; &lt; 1.2                  , QuickCheck                    &gt;=2.4.2       &amp;&amp; &lt; 3.0                  , random                        &gt;=1.0.1.1     &amp;&amp; &lt; 1.1                  , test-framework                &gt;=0.5         &amp;&amp; &lt; 0.6                  , test-framework-hunit          &gt;=0.2.7       &amp;&amp; &lt; 0.3                  , test-framework-quickcheck2    &gt;=0.2.12      &amp;&amp; &lt; 0.3                  , HUnit                  , hspec                         &gt;=0.9.1.1      &amp;&amp; &lt; 1.0                  , wai-test                      &gt;=1.1.1        &amp;&amp; &lt; 2.0                  , wai                  , wai-extra                     &gt;=1.1.0.1      &amp;&amp; &lt; 1.2                  , cookie                        &gt;=0.4.0        &amp;&amp; &lt; 0.5                  , http-conduit                  &gt;=1.2.6        &amp;&amp; &lt; 1.3                  , clientsession                 &gt;=0.7.4        &amp;&amp; &lt; 0.8                  , aeson                         &gt;= 0.5
    ghc-options: -Wall</code></pre>
<p>Tests/test.hs にエントリポイントを記述。</p>
<pre><code>import Import
import Test.Hspec
import Tests.SampleTest

main :: IO ()
main = hspecX $ descriptions $ specs</code></pre>
<p>Tests/SampleTest.hs で[Specs]を作成。</p>
<pre><code>module Tests.SampleTest (specs) where

import Tests.SampleTest.Handler.Api.User
import Test.Hspec

specs :: [Specs]
specs =
    [ userTest
    ]</code></pre>
<p>Tests/SampleTest/Handler/Api/User.hs</p>
<pre><code>module Tests.SampleTest.Handler.Api.User (userTest) where

import Prelude
import Yesod
import Application
import Test.Hspec
import Test.Hspec.HUnit ()
import Network.Wai
import Network.Wai.Test

userTest :: [Spec]
userTest = describe "SampleTest"
    [ it "check request is valid" case_request_valid
    ]

getApp :: IO Application
getApp = do
    (_,app) &lt;- getApplicationDev     return app runner :: Session () -&gt; IO ()
runner f = getApp &gt;&gt;= runSession f

case_request_valid :: IO ()
case_request_valid = runner $ do
      res &lt;- request defaultRequest
        {
          pathInfo = ["api", "user"],
          requestHeaders = [("Accept-Language", "es")]
        }
      assertBody "aaa" res</code></pre>
<p>getApplicationDevからApplicationを取ってきてrunSessionに投げる関数を作り、テストケース内でリクエストを投げてテストを実行していく。</p>
<p>実行。</p>
<pre><code>cabal configure -ftest --enable-tests
cabal build
cabal test</code></pre>
<p></a></p>
]]></content:encoded>
			<wfw:commentRss>http://emor.in/dev/?feed=rss2&amp;p=1540</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GHC 7.4.1のコンパイルエラー</title>
		<link>http://emor.in/dev/?p=1535</link>
		<comments>http://emor.in/dev/?p=1535#comments</comments>
		<pubDate>Wed, 29 Feb 2012 04:51:39 +0000</pubDate>
		<dc:creator>Emor.in Software Development</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://emor.in/dev/?p=1535</guid>
		<description><![CDATA[追記:2012/05/27:どうやらMilestoneの設定が間違っていたようで、再度チケットを確認すると7.4.2に変更されていた。ということで、7.4.2が出るまではMac OSX Lionでコンパイルするともれなくこける。
haddock: internal error: divide by zero
 make[1]: *** [libraries/base/dist-install/doc/html/base/base.haddock] Error 1
 make: *** [all] Error 2
すでにチケットはfixedになっているがhttp://www.haskell.org/ghc/にあるソースコードはまだ修正されていないので、そのままコンパイルすると普通に上記のエラーでこける
#5810 (OSX Lion building 7.4 head causes Haddock Divide By Zero) – GHC:
http://hackage.haskell.org/trac/ghc/ticket/5810
commit 552504663774d4ad2528d466f08841b5b78c7518で修正されているので、gitから対象の差分をmergeすればコンパイルは成功する。
Milestoneが7.4.1になっているので修正分が入ってないとおかしいのだが、なぜか入ってない。
]]></description>
			<content:encoded><![CDATA[<p>追記:2012/05/27:どうやらMilestoneの設定が間違っていたようで、再度チケットを確認すると7.4.2に変更されていた。ということで、7.4.2が出るまではMac OSX Lionでコンパイルするともれなくこける。</p>
<pre><code>haddock: internal error: divide by zero
 make[1]: *** [libraries/base/dist-install/doc/html/base/base.haddock] Error 1
 make: *** [all] Error 2</code></pre>
<p>すでにチケットはfixedになっているが<a href="http://www.haskell.org/ghc/">http://www.haskell.org/ghc/</a>にあるソースコードはまだ修正されていないので、そのままコンパイルすると普通に上記のエラーでこける</p>
<p>#5810 (OSX Lion building 7.4 head causes Haddock Divide By Zero) – GHC:<br />
<a href="http://hackage.haskell.org/trac/ghc/ticket/5810">http://hackage.haskell.org/trac/ghc/ticket/5810</a></p>
<p>commit <a href="https://github.com/ghc/packages-integer-gmp/commit/552504663774d4ad2528d466f08841b5b78c7518">552504663774d4ad2528d466f08841b5b78c7518</a>で修正されているので、gitから対象の差分をmergeすればコンパイルは成功する。</p>
<p>Milestoneが7.4.1になっているので修正分が入ってないとおかしいのだが、なぜか入ってない。</p>
]]></content:encoded>
			<wfw:commentRss>http://emor.in/dev/?feed=rss2&amp;p=1535</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>というわけでデコレータを分離した</title>
		<link>http://emor.in/dev/?p=1527</link>
		<comments>http://emor.in/dev/?p=1527#comments</comments>
		<pubDate>Tue, 06 Dec 2011 06:02:12 +0000</pubDate>
		<dc:creator>Emor.in Software Development</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://emor.in/dev/?p=1527</guid>
		<description><![CDATA[login_urlにリダイレクトせずに普通に403を返したいという需要は絶対にあるはずなので、login_urlにリダイレクトしてくれるデコレータと403をそのまま返すデコレータを分離した。
     @functools.wraps(method)
     def wrapper(self, *args, **kwargs):
         if not self.current_user:
-            if self.request.method in ("GET", "HEAD"):
-               [...]]]></description>
			<content:encoded><![CDATA[<p>login_urlにリダイレクトせずに普通に403を返したいという需要は絶対にあるはずなので、login_urlにリダイレクトしてくれるデコレータと403をそのまま返すデコレータを分離した。</p>
<pre><code>     @functools.wraps(method)
     def wrapper(self, *args, **kwargs):
         if not self.current_user:
-            if self.request.method in ("GET", "HEAD"):
-                url = self.get_login_url()
-                if "?" not in url:
-                    if urlparse.urlsplit(url).scheme:
-                        # if login url is absolute, make next absolute too
-                        next_url = self.request.full_url()
-                    else:
-                        next_url = self.request.uri
-                    url += "?" + urllib.urlencode(dict(next=next_url))
-                self.redirect(url)
-                return
             raise HTTPError(403)
         return method(self, *args, **kwargs)
     return wrapper

+def authenticated_to_login(method):
+    """Decorate methods with this to require that the user be logged in."""
+    @functools.wraps(method)
+    def wrapper(self, *args, **kwargs):
+        if not self.current_user:
+            url = self.get_login_url()
+            if "?" not in url:
+                if urlparse.urlsplit(url).scheme:
+                    # if login url is absolute, make next absolute too
+                    next_url = self.request.full_url()
+                else:
+                    next_url = self.request.uri
+                url += "?" + urllib.urlencode(dict(next=next_url))
+            self.redirect(url)
+            return
+        return method(self, *args, **kwargs)
+    return wrapper
+

 class UIModule(object):
     """A UI re-usable, modular unit on a page.</code></pre>
<p>Commit 3e14e9b46ff0b469847575e9ff0159863dceb984 to emorins/tornado &#8211; GitHub:<br />
<a href="https://github.com/emorins/tornado/commit/3e14e9b46ff0b469847575e9ff0159863dceb984">https://github.com/emorins/tornado/commit/3e14e9b46ff0b469847575e9ff0159863dceb984</a></p>
<p>一応Pull Requestしておいたが、いまいち綺麗なネーミングじゃないし、他に方法があるかもしれないので取り込まれないかもしれないが、どちらにしろこの辺りもう少し柔軟性をもたせてほしいところ。便利なんだけど。</p>
]]></content:encoded>
			<wfw:commentRss>http://emor.in/dev/?feed=rss2&amp;p=1527</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tornadoでlogin_urlが邪魔という話</title>
		<link>http://emor.in/dev/?p=1516</link>
		<comments>http://emor.in/dev/?p=1516#comments</comments>
		<pubDate>Sun, 04 Dec 2011 15:36:16 +0000</pubDate>
		<dc:creator>Emor.in Software Development</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://emor.in/dev/?p=1516</guid>
		<description><![CDATA[login_urlが邪魔。
class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/", app.handler.main.MainHandler),
            (r"/login", app.handler.login.LoginHandler),
            (r"/api", [...]]]></description>
			<content:encoded><![CDATA[<p>login_urlが邪魔。</p>
<pre><code>class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/", app.handler.main.MainHandler),
            (r"/login", app.handler.login.LoginHandler),
            (r"/api", app.handler.api.ApiHandler),
        ]
        settings = dict(
            cookie_secret="61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=",
            login_url="/login",
            debug=True,
        )
        tornado.web.Application.__init__(self, handlers, **settings)</code></pre>
<p>例えばこんなtornado.web.Applicationを継承したApplicationがあったとする。ここでsettingsで指定してあるlogin_urlは、@tornado.web.authenticatedデコレータを使ってユーザー認証行ったときに、もし認証が不正ならそのパスに302で自動リダイレクトしてくれるのだけれども、これが使えない。</p>
<div class="quote">
<blockquote cite="http://www.tornadoweb.org/documentation/overview.html?highlight=login_url" title="Overview — Tornado v2.1.1 documentation">
<p>
			You can require that the user be logged in using the Python decorator tornado.web.authenticated. If a request goes to a method with this decorator, and the user is not logged in, they will be redirected to login_url (another application setting).
		</p>
</blockquote>
<p>	<cite><a href="http://www.tornadoweb.org/documentation/overview.html?highlight=login_url">Overview — Tornado v2.1.1 documentation</a> から2011年12月5日0時42分に引用</cite>
</div>
<p>例えばAPIのようなリダイレクトせずに普通に403を返したいアプリケーションを書きたいときに邪魔になる。login_urlを定義しておかないとTornado自身が例外を吐くので指定しないこともできない。Noneも駄目。</p>
<p>さらにこの自動リダイレクトが効くのがGETメソッドなアクションに対してのみで、その他POSTやPUTなどは普通に403をクライアントに返す。</p>
<div class="quote">
<blockquote cite="http://www.tornadoweb.org/documentation/overview.html?highlight=login_url" title="Overview — Tornado v2.1.1 documentation">
<p>
			If you decorate post() methods with the authenticated decorator, and the user is not logged in, the server will send a 403 response.
		</p>
</blockquote>
<p>	<cite><a href="http://www.tornadoweb.org/documentation/overview.html?highlight=login_url">Overview — Tornado v2.1.1 documentation</a> から2011年12月5日0時42分に引用</cite>
</div>
<p>なんでこんな風になってるんだろうと疑問に感じる。Tornadoの作者自身がそういう使い方を想定していないだけだろうか。</p>
]]></content:encoded>
			<wfw:commentRss>http://emor.in/dev/?feed=rss2&amp;p=1516</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iOS5.0のUIViewControllerの木構造</title>
		<link>http://emor.in/dev/?p=1512</link>
		<comments>http://emor.in/dev/?p=1512#comments</comments>
		<pubDate>Mon, 17 Oct 2011 10:52:15 +0000</pubDate>
		<dc:creator>Emor.in Software Development</dc:creator>
				<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[iPhone/iPad]]></category>

		<guid isPermaLink="false">http://emor.in/dev/?p=1512</guid>
		<description><![CDATA[コントローラが木構造になるのは気持ち悪い気がするが、UIViewのデータ構造と合わせたことで、UIViewControllerとそのメンバであるviewを別々の構造として管理する必要がなくなった。



Implementing a Container View Controller


In iOS 5.0 and later, custom UIViewController subclasses can now act as container view controllers. The UINavigationController and UITabBarController classes are examples of container view controllers provided by UIKit. The idea behind a container view controller is that it manages the presentation of the content from its contained view controllers, also [...]]]></description>
			<content:encoded><![CDATA[<p>コントローラが木構造になるのは気持ち悪い気がするが、UIViewのデータ構造と合わせたことで、UIViewControllerとそのメンバであるviewを別々の構造として管理する必要がなくなった。</p>
<div class="quote">
<blockquote cite="http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html" title="UIViewController Class Reference">
<p>
Implementing a Container View Controller
</p>
<p>
In iOS 5.0 and later, custom UIViewController subclasses can now act as container view controllers. The UINavigationController and UITabBarController classes are examples of container view controllers provided by UIKit. The idea behind a container view controller is that it manages the presentation of the content from its contained view controllers, also known as its child view controllers. The child content can be presented as-is or in conjunction with other other custom views managed by the container view controller.
</p>
<p>
To implement a container view controller, make a custom UIViewController subclass that calls the view containment methods as appropriate for your containment model:
</p>
<ul>
<li>addChildViewController:</li>
<li>removeFromParentViewController</li>
<li>transitionFromViewController:toViewController:duration:options:animations:completion:</li>
<li>willMoveToParentViewController:</li>
<li>didMoveToParentViewController:</li>
<ul>
</blockquote>
<p>	<cite><a href="http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html">UIViewController Class Reference</a> から2011年10月17日19時25分に引用</cite>
</div>
<p>でもこれ、childViewControllersってメンバの通り、単一ノードじゃないのね。UIKit的には開発者がviewメンバ以外に色々なUIViewを追加するだろうから、そのコントローラもchildViewControllersで管理してねってことなんだろうか。</p>
<p>それとは別にUINavigationControllerがスタックのデータ構造を持っているのもかなりややこしい。</p>
]]></content:encoded>
			<wfw:commentRss>http://emor.in/dev/?feed=rss2&amp;p=1512</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>draft-ietf-hybi-thewebsocketprotocol-14</title>
		<link>http://emor.in/dev/?p=1494</link>
		<comments>http://emor.in/dev/?p=1494#comments</comments>
		<pubDate>Sat, 10 Sep 2011 15:44:34 +0000</pubDate>
		<dc:creator>Emor.in Software Development</dc:creator>
				<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://emor.in/dev/?p=1494</guid>
		<description><![CDATA[websocketのdrafut14が出ていた。一番大きな変更点はSec-WebSocket-Versionフィールドに複数のバージョンを指定できるようになったことだろう。



4.4. Supporting multiple versions of WebSocket protocol


   This section provides some guidance on supporting multiple versions
   of the WebSocket protocol in clients and servers.


   Using the WebSocket version advertisement capability (the &#8220;Sec-
   WebSocket-Version&#8221; header field) client can initially request the
   version of the WebSocket protocol [...]]]></description>
			<content:encoded><![CDATA[<p>websocketのdrafut14が出ていた。一番大きな変更点はSec-WebSocket-Versionフィールドに複数のバージョンを指定できるようになったことだろう。</p>
<div class="quote">
<blockquote cite="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-14" title="draft-ietf-hybi-thewebsocketprotocol-14 - The WebSocket protocol">
<p>
4.4. Supporting multiple versions of WebSocket protocol
</p>
<p>
   This section provides some guidance on supporting multiple versions<br />
   of the WebSocket protocol in clients and servers.
</p>
<p>
   Using the WebSocket version advertisement capability (the &#8220;Sec-<br />
   WebSocket-Version&#8221; header field) client can initially request the<br />
   version of the WebSocket protocol that it prefers (which doesn&#8217;t<br />
   necessarily have to be the latest supported by the client).  If the<br />
   server supports the requested version and the handshake message is<br />
   otherwise valid, the server will accept that version.  If the server<br />
   doesn&#8217;t support the requested version, it will respond with a Sec-<br />
   WebSocket-Version header field (or multiple Sec-WebSocket-Version<br />
   header fields) containing all versions it is willing to use.  At this<br />
   point, if the client supports one of the advertised versions, it can<br />
   repeat the WebSocket handshake using a new version value.
		</p>
</blockquote>
<p>	<cite><a href="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-14">draft-ietf-hybi-thewebsocketprotocol-14 &#8211; The WebSocket protocol</a> から2011年9月11日0時43分に引用</cite>
</div>
<p>ブラウザやサーバによってサポートしているwebsocketのバージョンがまちまちなのでDraft 76でSec-WebSocket-Versionフィールドがサポートされたが、さらに複数のバージョンを指定できるようになった。</p>
<p>例えばクライアントが</p>
<pre><code>GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
...
Sec-WebSocket-Version: 25</code></pre>
<p>のようなハンドシェイクを試みると、</p>
<pre><code>HTTP/1.1 400 Bad Request
...
Sec-WebSocket-Version: 13
Sec-WebSocket-Version: 8, 7</code></pre>
<p>のようなハンドシェイクをサーバが返すことができる。この場合サーバはバージョン25のwebsocketプロトコルをサポートしておらず、バージョン8と7をサポートしていることが分かる。</p>
]]></content:encoded>
			<wfw:commentRss>http://emor.in/dev/?feed=rss2&amp;p=1494</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>前エントリのバグレポートの返事</title>
		<link>http://emor.in/dev/?p=1491</link>
		<comments>http://emor.in/dev/?p=1491#comments</comments>
		<pubDate>Sun, 21 Aug 2011 16:19:05 +0000</pubDate>
		<dc:creator>Emor.in Software Development</dc:creator>
				<category><![CDATA[iPhone/iPad]]></category>

		<guid isPermaLink="false">http://emor.in/dev/?p=1491</guid>
		<description><![CDATA[が帰って来た。Duplicateらしい。
オリジナルのバグレポートを参照したいのだが、過去のレポートはどこで見ればいいんだろう。Appleのサイト見てもレポートを参照したい場合はメールを送れとしか書いてない。不便だなあ。
]]></description>
			<content:encoded><![CDATA[<p>が帰って来た。Duplicateらしい。</p>
<p>オリジナルのバグレポートを参照したいのだが、過去のレポートはどこで見ればいいんだろう。Appleのサイト見てもレポートを参照したい場合はメールを送れとしか書いてない。不便だなあ。</p>
]]></content:encoded>
			<wfw:commentRss>http://emor.in/dev/?feed=rss2&amp;p=1491</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NS_BLOCK_ASSERTIONSが有効のとき可変長引数のNSAssertが未定義になる</title>
		<link>http://emor.in/dev/?p=1486</link>
		<comments>http://emor.in/dev/?p=1486#comments</comments>
		<pubDate>Mon, 25 Jul 2011 16:52:17 +0000</pubDate>
		<dc:creator>Emor.in Software Development</dc:creator>
				<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[iPhone/iPad]]></category>

		<guid isPermaLink="false">http://emor.in/dev/?p=1486</guid>
		<description><![CDATA[NSCAssertも同様。これは一体どういう意図があるんだろう。それとも単なるバグなのか。
NS_BLOCK_ASSERTIONSが無効のとき
#if !defined(NS_BLOCK_ASSERTIONS) &#038;&#038; defined(__STDC_VERSION__) &#038;&#038; (199901L ]]></description>
			<content:encoded><![CDATA[<p>NSCAssertも同様。これは一体どういう意図があるんだろう。それとも単なるバグなのか。</p>
<p>NS_BLOCK_ASSERTIONSが無効のとき</p>
<pre><code>#if !defined(NS_BLOCK_ASSERTIONS) &#038;&#038; defined(__STDC_VERSION__) &#038;&#038; (199901L <= __STDC_VERSION__) &#038;&#038; (defined(__GNUC__) || 0)

#if !defined(_NSAssertBody)

#define NSAssert(condition, desc, ...) \
    do {			\
	if (!(condition)) {	\
	    [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd \
		object:self file:[NSString stringWithUTF8String:__FILE__] \
	    	lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; \
	}			\
    } while(0)

#define NSAssert1(condition, desc, arg1) NSAssert((condition), (desc), (arg1))
#define NSAssert2(condition, desc, arg1, arg2) NSAssert((condition), (desc), (arg1), (arg2))
#define NSAssert3(condition, desc, arg1, arg2, arg3) NSAssert((condition), (desc), (arg1), (arg2), (arg3))
#define NSAssert4(condition, desc, arg1, arg2, arg3, arg4) NSAssert((condition), (desc), (arg1), (arg2), (arg3), (arg4))
#define NSAssert5(condition, desc, arg1, arg2, arg3, arg4, arg5) NSAssert((condition), (desc), (arg1), (arg2), (arg3), (arg4), (arg5))

#define NSParameterAssert(condition) NSAssert((condition), @"Invalid parameter not satisfying: %s", #condition)

#endif</code></pre>
<p>NS_BLOCK_ASSERTIONSが有効のとき</p>
<pre><code>#if !defined(NSAssert)
#define NSAssert5(condition, desc, arg1, arg2, arg3, arg4, arg5)	\
    _NSAssertBody((condition), (desc), (arg1), (arg2), (arg3), (arg4), (arg5))

#define NSAssert4(condition, desc, arg1, arg2, arg3, arg4)	\
    _NSAssertBody((condition), (desc), (arg1), (arg2), (arg3), (arg4), 0)

#define NSAssert3(condition, desc, arg1, arg2, arg3)	\
    _NSAssertBody((condition), (desc), (arg1), (arg2), (arg3), 0, 0)

#define NSAssert2(condition, desc, arg1, arg2)		\
    _NSAssertBody((condition), (desc), (arg1), (arg2), 0, 0, 0)

#define NSAssert1(condition, desc, arg1)		\
    _NSAssertBody((condition), (desc), (arg1), 0, 0, 0, 0)

#define NSAssert(condition, desc)			\
    _NSAssertBody((condition), (desc), 0, 0, 0, 0, 0)
#endif</code></pre>
<p>意図的にやってるとしてもメリットが分からない。油断してNSAssert(condition, desc, ...)を開発時に使いまくって、いざNS_BLOCK_ASSERTIONS付きでreleaseビルドすると悲惨なことになる。</p>
]]></content:encoded>
			<wfw:commentRss>http://emor.in/dev/?feed=rss2&amp;p=1486</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>『第2回JVMソースコードリーディングの会』に参加してきた</title>
		<link>http://emor.in/dev/?p=1481</link>
		<comments>http://emor.in/dev/?p=1481#comments</comments>
		<pubDate>Sun, 17 Jul 2011 13:25:58 +0000</pubDate>
		<dc:creator>Emor.in Software Development</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://emor.in/dev/?p=1481</guid>
		<description><![CDATA[第2回JVMソースコードリーディングの会(OpenJDK6) &#8211; [PARTAKE]:
http://partake.in/events/9d3d48b4-43a0-4417-a214-03ad22f6ef1a
読んだ範囲

クラスファイルベリファイア
java.util.concurrent

まあこの辺は割と読めば分かるところなので。後半は寝てた。
]]></description>
			<content:encoded><![CDATA[<p>第2回JVMソースコードリーディングの会(OpenJDK6) &#8211; [PARTAKE]:<br />
<a href="http://partake.in/events/9d3d48b4-43a0-4417-a214-03ad22f6ef1a">http://partake.in/events/9d3d48b4-43a0-4417-a214-03ad22f6ef1a</a></p>
<p>読んだ範囲</p>
<ul>
<li>クラスファイルベリファイア</li>
<li>java.util.concurrent</li>
</ul>
<p>まあこの辺は割と読めば分かるところなので。後半は寝てた。</p>
]]></content:encoded>
			<wfw:commentRss>http://emor.in/dev/?feed=rss2&amp;p=1481</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JPEGのAPP0マーカーのセグメント長が0のときの挙動</title>
		<link>http://emor.in/dev/?p=1478</link>
		<comments>http://emor.in/dev/?p=1478#comments</comments>
		<pubDate>Sun, 03 Apr 2011 04:53:33 +0000</pubDate>
		<dc:creator>Emor.in Software Development</dc:creator>
				<category><![CDATA[Binary]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://emor.in/dev/?p=1478</guid>
		<description><![CDATA[JPEGのマーカーをパースするコードなんか書くとき、例えばセグメント長が0なんかだったりした場合は、そのまま愚直に0を信じて次のバイト列からマーカー識別子を特定するなんていうコード書きそうだけど、Mac OS X(10.6.4)のプレビューはそうじゃなかったのでメモ。
Mac OS X(10.6.4)のプレビューだとJPEGのAPP0マーカーのセグメント長が0で、でも実は0じゃないような不正なバイトデータでもちゃんと正常に表示されていた。
FFD8FFE000104A46494600010100000100010000FFDB008400090606131210151412141515151518151A171718171818
APP0マーカーのセグメント長をあり得ない値に変更したJPEG。
FFD8FFE000004A46494600010100000100010000FFDB008400090606131210151412141515151518151A171718171818
どうしてるんだろう。単純に0を信じてみたけど、次の2バイトでマーカー識別子を特定できないからマーカーが出るまでインクリメントしていって調べてるのか。
]]></description>
			<content:encoded><![CDATA[<p>JPEGのマーカーをパースするコードなんか書くとき、例えばセグメント長が0なんかだったりした場合は、そのまま愚直に0を信じて次のバイト列からマーカー識別子を特定するなんていうコード書きそうだけど、Mac OS X(10.6.4)のプレビューはそうじゃなかったのでメモ。</p>
<p>Mac OS X(10.6.4)のプレビューだとJPEGのAPP0マーカーのセグメント長が0で、でも実は0じゃないような不正なバイトデータでもちゃんと正常に表示されていた。</p>
<pre><code>FFD8FFE000104A46494600010100000100010000FFDB008400090606131210151412141515151518151A171718171818</code></pre>
<p>APP0マーカーのセグメント長をあり得ない値に変更したJPEG。</p>
<pre><code>FFD8FFE000004A46494600010100000100010000FFDB008400090606131210151412141515151518151A171718171818</code></pre>
<p>どうしてるんだろう。単純に0を信じてみたけど、次の2バイトでマーカー識別子を特定できないからマーカーが出るまでインクリメントしていって調べてるのか。</p>
]]></content:encoded>
			<wfw:commentRss>http://emor.in/dev/?feed=rss2&amp;p=1478</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
