<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[帐前卒专栏]]></title>
  <link href="http://chilly.github.com/atom.xml" rel="self"/>
  <link href="http://chilly.github.com/"/>
  <updated>2013-08-30T07:25:52+08:00</updated>
  <id>http://chilly.github.com/</id>
  <author>
    <name><![CDATA[chillycreator]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[微信公众平台开发中的安全问题]]></title>
    <link href="http://chilly.github.com/blog/2013/08/30/wei-xin-gong-zhong-ping-tai-kai-fa-zhong-de-an-quan-wen-ti/"/>
    <updated>2013-08-30T05:37:00+08:00</updated>
    <id>http://chilly.github.com/blog/2013/08/30/wei-xin-gong-zhong-ping-tai-kai-fa-zhong-de-an-quan-wen-ti</id>
    <content type="html"><![CDATA[<h2>0. 我在开发中</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;近期一直在利用有道云笔记API在微信上开发一款应用。因为是服务器端与服务器端的交互。所以有很多安全问题值得考虑。</p>

<h2>1. 微信的认证</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;微信的认证很简单，标准的认证是这样子的：<br/>
<img src="http://mp.weixin.qq.com/wiki/images/9/90/Callbackprofile.jpg" alt="token 授权" /><br/>
 &nbsp;&nbsp;&nbsp;&nbsp;微信这种授权模式相当的山寨，如果只是单纯的靠这种token授权，服务器很容易被攻破。这里需要填写的url必须是使用80端口，而且url中也不能有很特殊的字符。不过token中可以有特殊字符。所以开发者需要尽量将自己的token设的复杂。微信首先认证连接时会将signature,echostr,nonce,timestamp这四个URL参数以GET请求的方式发送过来。数据则以POST请求的方式发送到同样的URL上，并且URL参数变为signature,echostr,nonce。nonce是和请求中的timestamp成对的。也就是说timestamp+nonce是唯一的。所以这里可以防止重放攻击。另外server与server通信之间,timestamp的单位是秒，一般误差也就是分钟级别的。这样可以从另外一个角度防止重放攻击。所以开发者应该在GET,POST请求中都加入这些参数的校验。</p>

<!--more-->


<h2>2. Token安全</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;上面的认证建立在Token的安全基础上。另外因为微信公众平台中URL不能有特殊字符，所以这个URL很容易被破掉。而Token这个也可有通过暴力尝试来破解。大概也没有帐号设很长的密码。所以你要做的就是将Token设的超长，另外加入些特殊字符。</p>

<h2>3. TO 收信者ID</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;微信发来的是一个发信者的ID和一个收信者的ID。收信者ID一直是不变的。如果Token被破解了，那么下面一个安全的措施是收信者的ID，因为收信者ID这个对于伪造者来说，这个是不可见的。但是对于能截获微信服务器和应用服务器之间的中间者来说。这个就是可以轻易获取的。</p>

<h2>4. From 发信者ID</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;下面就不算是微信的安全了。应该是我做的应用本身的安全问题。首先我需要使用有道云笔记的授权。需要发给用户一个链接。用户点击该链接完成授权。第一版应用中，该链接值是不变化的，或者说某一部分例如from参数是不变化。这就意味着，如果用户不小心将该链接暴露出去。那么其他用户完全可以将此用户发来的消息存入到自己的笔记中。这个是个很严重的安全问题。而且对外也不应该在链接中暴露from 发信者ID。所以需要使用其他的参数来隐藏from ID，另外授权链接只能成功授权使用一次。</p>

<h2>5. 内容的XSS风险</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;这个问题，其实只要是存储内容，就一定隐含着XSS问题。所以这个微信内容需要经过XSS过滤。</p>

<h2>6. 跳转链接隐含的XSS风险</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;授权的过程中有大量的跳转操作，特别是callback参数，需要对该参数做特殊的\r\n过滤。另外如果该参数会写入到页面中，那么也应该对整个页面的内容做XSS过滤。特别要防止拼接而形成的XSS问题。</p>

<h2>7. 隐式登录问题</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;之前的有道云笔记Oauth1.0版本，一直有隐式登录授权问题。就是一旦成功授权后，就难以改用第二个帐号了。现在这这一版顺便解决了这个问题。</p>

<h2>8. 微信 Android bug</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;顺便说说Android的微信的bug。有一个很奇葩的bug是这样的。如果服务器返回<code>&lt;a href="chillyc.info"&gt;帐前卒&lt;/a&gt;</code>。如果你在微信界面中点击了“帐前卒”，那么就理所当然的跳转到了chillyc.info.然后如果服务器下次返回<code>&lt;a href="blog.csdn.net/cctt_1"&gt;帐前卒&lt;/a&gt;</code>。那么点击该链接，仍然会打开chillyc.info! F**K.</p>

<h2>总结</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;开发完在微信平台的这个功能。让我感觉到微信私有接口太多，太过诡异的技巧。视频、音频这些都是通过大客户合作的方式获取的。另外有时候微信自身的bug占用了自己太多的时间。还有一个感觉，就是有道云笔记授权，特别是1.0,真的不是很好用，存在很多未解决的问题。不过2.0也上线了。大家会更加轻松的使用。嗯嗯&#8230;&#8230;自己这边开发的还能改，别人开发的&#8230;都不知道该去哪里问&#8230;&#8230;另外微信部门明显不是合作态度。可能和它们合作的公司太多的缘故。好了，最后一点：安全基本是靠自己&#8230;公众平台的用户名密码也不要设置的太简单&#8230;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[致青春]]></title>
    <link href="http://chilly.github.com/blog/2013/08/25/zhi-qing-chun/"/>
    <updated>2013-08-25T02:10:00+08:00</updated>
    <id>http://chilly.github.com/blog/2013/08/25/zhi-qing-chun</id>
    <content type="html"><![CDATA[<p> &nbsp;&nbsp;&nbsp;&nbsp;昨日和老婆大人一起看了致青春这部电影。这个电影总体感觉挺不错的。而我个人的感觉是电影里郑微和老婆大人有几分相似。要说哪几分，应该是暴力的那几分。嗯&#8230;</p>

<p> &nbsp;&nbsp;&nbsp;&nbsp;昔日的同学也各有成绩。每个人或许都少了些过去的狂妄和稚嫩。但总有些值得记忆的往事。这或许就是导演希望告诉我们的。但是无论如何，青春不在，如何重来？所以感情的重新开始&#8230;就只能从青春的记忆和自己的臆想里继续了。</p>

<p> &nbsp;&nbsp;&nbsp;&nbsp;老婆大人说：如果不是赵薇导演的，这部影片应该是没有人去看的。而我认为：如果不是老婆大人打开这个电影，我是绝对不会看的。嗯，就是这样&#8230;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[barchart UDT(二)]]></title>
    <link href="http://chilly.github.com/blog/2013/08/20/barchart-udt-er/"/>
    <updated>2013-08-20T07:49:00+08:00</updated>
    <id>http://chilly.github.com/blog/2013/08/20/barchart-udt-er</id>
    <content type="html"><![CDATA[<h1>前言</h1>

<p> &nbsp;&nbsp;&nbsp;&nbsp;barchart UDT 最近还是做了些实验。发现在内网中，这个表现实在不怎么样。测试了一下内网<code>字节=32 时间=2ms TTL=60</code>,外网<code>字节=32 时间=27ms TTL=53</code>.这两个环境中UDT表现不好。下面给出一些结论：</p>

<h1>结论</h1>

<ol>
<li><p>内网基本不丢包的情况下， udt在15-30并发时upload表现较好。</p></li>
<li><p>在外网偶发丢包率的情况下， UDT在上传中，多并发（并发数不超过15）表现较为优异，会偶尔高于TCP.</p></li>
<li><p>TCP 在偶发丢包/不丢包 网络状态下，性能稳定，而且不会有IO异常情况。</p></li>
<li><p>UDT在偶发丢包情况下，会有连接失败/重传超时后连接断开等情况发生。需要修改代码逻辑保证完整的数据传输。</p></li>
<li><p>UDT在大多数情况下，传输率不及TCP。</p></li>
</ol>


<!--more-->


<h1>结论分析：</h1>

<ol>
<li><p>UDT 出现在2004年，TCP产生于1975年。UDT为开源项目，但是测试者较少。TCP经过大量的反复试验和OS的支持，性能稳定。TCP比UDT更为成熟。UDT可能还需要更为细致的测试。</p></li>
<li><p>UDT在UDP搭建可靠性传输。以datagram作为数据单元，一般小于等于1464(bytes)。，而TCP使用协议栈自动分包(1452 bytes),但是TCP在三次握手时可以得知最小的MSS.如果传输路径中小于MTU 1500，可能会导致UDT变慢。因为发送一个包，如果被分片，只要一个分片未被接受，则整个包被丢弃，为协商情况下的UDT,在丢包率增大的情况下，可能会有更多的重传。(3G,4G网络中MTU 没有相关规定，是由运营商自己设置, 动态调整MSS是有必要的。)</p></li>
<li><p>UDT 在偶发丢包率的情况下，其协议表现很不稳定，逻辑不能简单等同于TCP。这可能需要在编程过程中做更复杂的处理。</p></li>
</ol>


<h1>实验环境</h1>

<p>实验环境：
OS: win7(32位), linux（64位）
网卡：Marvell Yukon 88E8057 PCI-E Gigabit Ethernet Controller
主机配置：Pentium(R) Dual-Core E5500 2.8GHz, 2.8GHz， 内存4G(2.97G可用)
内网 字节=32 时间=2ms TTL=60,外网 字节=32 时间=27ms TTL=53
传送数据量为4M，15M。另外还有echo数据(少量数据情况)。
具体实验数据不再一一列举。不过基本上TCP可以打满带宽，而UDT不行。
特别注意UDT发送数据时会有下面的警告：（在有丢包率的情况下）
警告: com.barchart.udt.ExceptionUDT: UDT Error : 1001 : server does not exist : connect0:connect [id: 0x074f0e4b] UDT
com.barchart.udt.net.ExceptionSendUDT: UDT Error : -4 : user defined message : UDT send time out [id: 0x074f0e3b]</p>

<p>这些警告代表着在丢包存在的情况下。UDT和TCP比，性能不稳定，存在协议上的问题。这里的解决方法需要使用多次尝试链接和多次尝试发送。TCP在相应丢包率的情况下，并没有这些例外的情况发生。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[barchart UDT（一）]]></title>
    <link href="http://chilly.github.com/blog/2013/08/10/barchart-udt/"/>
    <updated>2013-08-10T03:27:00+08:00</updated>
    <id>http://chilly.github.com/blog/2013/08/10/barchart-udt</id>
    <content type="html"><![CDATA[<h2>UDT简单介绍</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;最近在研究UDT相关的东西。这个主要用于高带宽时延积。也就是适用于网络带宽较高，但是丢包还是比较频繁的网络。给个公式：</p>

<pre><code>    高带宽时延积（缩写）=带宽 * RTT   
</code></pre>

<p> &nbsp;&nbsp;&nbsp;&nbsp;UDT相关的可以在这里找到：<a href="http://udt.sourceforge.net">http://udt.sourceforge.net</a> 另外对于UDT原版(c++)版，这里有两个下载路径。一个是CVS的。另外一个是git的。</p>

<!-- more -->


<ul>
<li><p>&nbsp;&nbsp;&nbsp;&nbsp;这个站点里，还有一个软件barchart UDT. 这个是jni的UDT.就是底层还是C/C++的库，上层wapper了Java.现在发布的最新的版本是2.3.0.第一个可以使用，而且大规模使用的版本是1.0.2.大家可以在网上找。这几次的升级加了很多没有用的东西。最核心的东西没有怎么变化。不过1.0.2没有javaDoc,基本上要先看一下UDT C版的源码才行。另外1.0.2现在已经没有了源码，因为开源的作者没有写清楚1.0.2是从那个version发布的（也可能是我看得粗糙）。</p></li>
<li><p>&nbsp;&nbsp;&nbsp;&nbsp;这个站点里还有一款软件叫做UDT-JAVA.大家最好不要下，这个软件的网络行为和UDT原生的网络行为不太一致。另外这个软件在serverSocket.accept();这个地方开源的作者写的有bug。我使用一次UDT连接时，竟然可以获取到多个UDT socket.不管是怎么回事，最后还是弃之不用了。</p></li>
</ul>


<h2>barchart UDT  (mvn需要3.0.4以上版本)</h2>

<p>这里要着重介绍这个UDT.最好使用的版本是2.3.0。不过该版本从git上download下来。编译花了我一天的功夫。第一个问题就是贵司集群上该死的mvn环境。这个环境是默认的repository是在~/.m2/repository. 这个环境会报：<code>java.io.IOException: No locks available</code>.这个问题就是需要你在$M2_home/conf/settings.xml中加入：<code>&lt;localRepository&gt;/your-path/.m2/repository&lt;/localRepository&gt;</code> 这里的路径需要是绝对路径。第二个问题，贵司没有$M2_home这个变量!这个变量切不可自己随便写，必须找到那个安装的路径,否则mvn不能被执行。当然贵司是不可能有人知道这个路径的。所以&#8230;解决方法就是使用<code>mvn -s your-conf</code>来执行mvn.</p>

<p>下面看起来就可以直接执行mvn install了。作者说最好进入barchart-udt-archon再执行. 然后遇到这个错误：<code>Exception in thread "main" java.lang.NoSuchMethodError: org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.getReadTimeout()I</code> 这个错误是mvn的，不过更加可气。这个解决方法就是在pom.xml中加入：</p>

<pre><code>    &lt;extensions&gt;
      &lt;!-- Whysoever version 2.2 has issues with Maven 3.0.3:
           java.lang.NoSuchMethodError: org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.getReadTimeout()I
      --&gt;
      &lt;extension&gt;
        &lt;groupId&gt;org.apache.maven.wagon&lt;/groupId&gt;
        &lt;artifactId&gt;wagon-ssh&lt;/artifactId&gt;
        &lt;version&gt;2.1&lt;/version&gt;
      &lt;/extension&gt;
      &lt;extension&gt;
        &lt;groupId&gt;org.apache.maven.wagon&lt;/groupId&gt;
        &lt;artifactId&gt;wagon-http&lt;/artifactId&gt;
        &lt;version&gt;2.1&lt;/version&gt;
      &lt;/extension&gt;
      &lt;extension&gt;
        &lt;groupId&gt;org.apache.maven.wagon&lt;/groupId&gt;
        &lt;artifactId&gt;wagon-file&lt;/artifactId&gt;
        &lt;version&gt;2.1&lt;/version&gt;
      &lt;/extension&gt;
    &lt;/extensions&gt;   
</code></pre>

<p>上面这块代码必须放在 <code>&lt;project&gt;&lt;build&gt;放在这里&lt;/build&gt;&lt;/project&gt;</code>, 否则mvn会报no Tags错误。</p>

<p>看起来可以正常运行了。结果&#8230;&#8230;更加悲剧的事情是mvn需要3.0.4版本。只好在官网上download一个高版本的maven.然后在集群上解压。执行ant命令。这里需要首先设置$M2_HOME这个变量。然后看官网的文档安装。不过这还不算完，最后编译barchart-udt后，bundle那个项目一直不能正常的编译。不过如果你只是为了替换某些不能运行的libxxx.so文件，只要编译完了core项目。就可以从core项目中找到相应的.so文件。然后下载一个2.3.0的jar包。解压后，把相应的文件替换掉。然后再打成jar包。打jar包命令：<code>jar c [jarfile] -m [MANIFEST file]  [other files]</code></p>

<p>然后放在你的程序中运行即可。barchart-udt的那个Jar可以自动解压出来so文件，然后放在相应的地方。之后就可以使用jni调用了。和正常的使用java socket一样。下一篇会讲如何使用barchart-udt进行编程。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[upgrade to octopress 2.0]]></title>
    <link href="http://chilly.github.com/blog/2013/07/30/upgrade-to-octopress-2-dot-0/"/>
    <updated>2013-07-30T15:03:00+08:00</updated>
    <id>http://chilly.github.com/blog/2013/07/30/upgrade-to-octopress-2-dot-0</id>
    <content type="html"><![CDATA[<h2>0. 前言</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;最近在看Octopress的代码，然后想想可能Octopress要更新了。于是手贱了一下，把整个Octopress重新更新了一下。然后整个blog乱成一团了。所以说千万别更新，更新之前一定要git push保存一下进度。如果真的更新挂了，就再rollback.</p>

<!-- more -->


<h2>1. fix bugs</h2>

<ul>
<li>Could not find fast-stemmer-1.0.1 in any of the sources</li>
</ul>


<p> &nbsp;&nbsp;首先将 rubygems中的https://rubygems.org修改为 http://rubygems.org/， 这样就可以下载到fast-stemmer-1.0.1.</p>

<ul>
<li>Could not find sass-3.2.9 in any of the sources</li>
</ul>


<p> &nbsp;&nbsp;再将http://rubygems.org修改为 https://rubygems.org/ 发现这个东西被封了。所以需要使用代理：</p>

<pre><code>    $ export http_proxy=http://username:password@your-proxy-site.com:[your_proxy_port]
</code></pre>

<ul>
<li><em>Let&#8217;s Go on.</em> An error occured while installing rdiscount (2.0.7.3), and Bundler cannot continue. Make sure that <code>gem install rdiscount -v '2.0.7.3'</code> succeeds before bundling.</li>
</ul>


<p>  &nbsp;&nbsp;这个要用ruby 1.9.3来解决。那么来安装ruby 1.9.3吧。</p>

<pre><code>    rvm install 1.9.3
    修改.rvmrc
    修改.rvmrc使用的ruby版本。 rvm use 1.9.3
    当然可以退出该目录重新进入一遍。  
</code></pre>

<ul>
<li><p>继续走&#8230;发现ruby中的问题</p>

<pre><code> /home/chico/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/uri/common.rb:304:in `escape': undefined method `gsub' for 2012:Fixnum (NoMethodError)
 from /home/chico/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/uri/common.rb:623:in `escape'
</code></pre></li>
</ul>


<p>  &nbsp;&nbsp;这个问题是之前的markdown脚本，现在解析的有问题。有些不兼容了。解决方法是在plugins/sitemap_generator.rb中把post.name打印出来，然后看最后是在哪个文件中卡死了。然后就修改那个文件的markdown文件。</p>

<ul>
<li><p>然后终于把Octopress启动起来了。内牛满面呀！然后就发现页面全乱了&#8230;&#8230;&#8230;. <br/>
&nbsp;&nbsp;然后借小Y之力修改了css.然后就好了。当然你们没有小Y. 下面是那段修改的css. 修改sass/base/_layout.scss</p>

<pre><code>    #content {
       @extend .group;
  -    overflow: visible;
  -    margin-right: $sidebar-width-medium;
  +    overflow: hidden;
  +    margin-right: 0px!important;
  +    padding-right: 240px;
       position: relative;
      .no-sidebar &amp; { margin-right: 0; border-right: 0; }
</code></pre></li>
</ul>


<h2>2. 最终页面</h2>

<p> 新的页面是长这样子的：
<img src="http://note.youdao.com/yws/public/resource/8a55ddd27d075e71ac8a8d14e6f58a41/FD5A902AD9D743F6BC2AEA01498DD160" alt="新页面" />
 旧的页面是这样子的：
<img src="http://note.youdao.com/yws/public/resource/8a55ddd27d075e71ac8a8d14e6f58a41/34849B1E634C41C9AFB779AF43F0A946" alt="旧页面" />
 因为那个收缩的tab是关联js的。所以该起来还是很困难。</p>

<h2>3. 结论</h2>

<p>  &nbsp;&nbsp;&nbsp;&nbsp;不要因为出了新版本就手贱去更新。否则修改更新问题时，贱手就废掉了。<br/>
  &nbsp;&nbsp;&nbsp;&nbsp;<em>最后一句话: F**K Octopress 2.0 !!</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Modify octopress blog]]></title>
    <link href="http://chilly.github.com/blog/2013/07/21/modify-octopress-blog/"/>
    <updated>2013-07-21T02:41:00+08:00</updated>
    <id>http://chilly.github.com/blog/2013/07/21/modify-octopress-blog</id>
    <content type="html"><![CDATA[<p> &nbsp;&nbsp;&nbsp;&nbsp;这几天一直在捣鼓blog.因为很久没有用<strong>Octopress</strong>写blog.另外也没有碰HTML相关。所以写markdown或者改Octopress都手生。这里把各种修改方法一一记下。要学习的是<strong>ruby</strong>, <strong>Liquid</strong>.</p>

<!-- more -->


<h2>0.开始学习</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp;学习ruby推荐以下这几个网站：</p>

<ul>
<li><a href="http://ruby-doc.org/" title="http://ruby-doc.org/">ruby doc</a></li>
<li><a href="http://www.ruby-lang.org/zh_cn/documentation/">ruby中文的官方文档</a></li>
<li><a href="http://www.compileonline.com/execute_ruby_online.php">ruby 在线运行环境</a> 使用这个可以在线运行ruby. 查看执行结果。对于机器没有装ruby,这个是极好的平台。</li>
</ul>


<p> &nbsp;&nbsp;&nbsp;&nbsp;然后是学习Liquid. <strong>Liquid</strong>这个本身是用ruby写的。所以只需要会用就行了。语法很像JSP. <br/>
<img src="http://note.youdao.com/yws/public/resource/8a55ddd27d075e71ac8a8d14e6f58a41/671FD472DEC849C3B7B9F94A6A67DD6B" alt="Liquid语法example" /></p>

<p> &nbsp;&nbsp;&nbsp;&nbsp;YAML. 这个全称是&#8217;<strong>YAML Ain&#8217;t Markup Language。</strong>&#8216;。定义看起来和GNU很想。这个鬼东西不希望采用XML的方式。基本是做配置文件使用的。如果想细细学习。<a href="http://zh.wikipedia.org/zh-cn/YAML">猛击这里</a>。在Octopress中基本上也就是定义了一下全局的某些量的true,false.其他基本上没有用。</p>

<h2>1. 开始修改Octopress blog</h2>

<h3>1.1 Octopress 简单介绍</h3>

<p> &nbsp;&nbsp;&nbsp;&nbsp;Octopress. 这个是继承了Liquid.然后加了一些plugins.最主要的plugin是plugins/octopress_filters.rb. Octopress的工作原理就是使用Liquid对各种文档进行渲染生成html. 只不过比原始的Liquid的功能更多。另外使用Rake对各种命令打包。Octopress最重要的几个目录是: source, plugin. Octopress会先进行渲染，然后将渲染后的文件放入到public目录中，之后再将public目录中的文件移动到_deploy目录下。然后通过git上传_deploy目录完成发布。所以如果你想加入什么自己新写的html不要放到public或者_deploy目录下。要放在source目录完成发布。所以如果你想加入什么自己新写的html不要放到public或者_deploy目录下。要放在source目录下。比如我为自己的blog自定义了一个404.html.那么就要放入到source目录下。或者放入其他目录下并且改写Rakefile, 改写 “<strong>multitask :push</strong>”中的命令。</p>

<h3>1.2 Octopress source的文件目录结构。</h3>

<ul>
<li>首先是_posts这个目录。这个是用来存放你用markdown写的blog的。使用rake new_post[&#8216;xxxx&#8217;] 就可有创建一篇名为xxxx.markdown的文件。</li>
<li>_includes这个目录。这个目录是引用各种模板html的。例如我的jiathis脚本和google ads脚本.我个人一般会将这些第三方存放在_includes/post目录下。引用的时候使用{&#37; include post/xxx.html &#37;}. 如果是在_include下的article.html,引用则为{&#37; include article.html &#37;}. 其中最重要的是article.html文件。这个每篇文章的显示。并且对于首页和具体blog都是引用的article.html. article.html中有 <strong>{&#37; if index &#37;}</strong>，如果index为true,则是首页。</li>
<li>_layouts这个目录，这个目录是对应着每篇文章的样式(当点进某篇文章后，这个目录下的文件就开始其作用)。其中最重要是post.html这个文件。修改也主要是修改这个。</li>
<li>index.html. 这个就是首页了。页面的排版都在这里。</li>
</ul>


<h2>2. 实战</h2>

<h3>2.1 jiathis 添加</h3>

<p> &nbsp;&nbsp;&nbsp;&nbsp; 下面以jiathis的添加为例。<br/>
<img src="http://note.youdao.com/yws/public/resource/8a55ddd27d075e71ac8a8d14e6f58a41/412D2139E39C487BAA77D2E43A2A442C" alt="jiathis 图标" /> <br/>
 &nbsp;&nbsp;&nbsp;&nbsp; 加入jiathis需要修改以下这些文件：</p>

<ul>
<li><p>添加 source/_include/post/jiathis.html （不用照抄，直接在jiathis.com中找找同样的html即可。）<br/>
<img src="http://note.youdao.com/yws/public/resource/8a55ddd27d075e71ac8a8d14e6f58a41/4182C91E8C5F4F7C833C251570D109E4" alt="jiathis.html" /></p></li>
<li><p>source/_include/article.html 修改为： <br/>
<img src="http://note.youdao.com/yws/public/resource/8a55ddd27d075e71ac8a8d14e6f58a41/25EE2B2EE60D49D5868663E6BD80C2F4" alt="jiathis 放入article.html的位置" />
图中修改的位置是点击到详细页面后，jiathis出现。如果希望在首页就出现，一种可以修改 else之前的，或者直接修改source/index.html文件</p></li>
</ul>


<h3>2.2 修改侧边栏</h3>

<p>  &nbsp;&nbsp;&nbsp;&nbsp; 如果你的blog有侧边栏的需求的话。那么需要改两个地方：一个是post.html,另外一个是index.html. Octopress的页面控制基本就是由这两个文件组成。index.html是控制首页。而post.html是控制详细页。</p>

<ul>
<li><p>source/_layouts/post.html 修改最下方，例如下图(不要照抄)：<br/>
<img src="http://note.youdao.com/yws/public/resource/8a55ddd27d075e71ac8a8d14e6f58a41/A5AB8C677BCB45D09CA2ED0D43A359B8" alt="sidebar" /></p></li>
<li><p>source/index.html 也是修改最下方。</p></li>
</ul>


<p><img src="http://note.youdao.com/yws/public/resource/8a55ddd27d075e71ac8a8d14e6f58a41/B49102887AFD49238793A6D57F3365A6" alt="index sidebar" /></p>

<h2>4. 添加404页面。</h2>

<p> &nbsp;&nbsp;&nbsp;&nbsp; github上的404页面可以定制。只需要在index.html那个目录中加入一个404.html即可。例如我的： <br/>
<img src="http://note.youdao.com/yws/public/resource/8a55ddd27d075e71ac8a8d14e6f58a41/9518399117EE4D2BB4BD81B1548DC979" alt="404.html" /></p>

<h2>3. 总结</h2>

<p>  &nbsp;&nbsp;&nbsp;&nbsp; 之前觉得这个Octopress很cool,后来才发现上了贼船。这东西定制起来还是比较费劲。另外最费劲的就是Octopress升级。下一章讲如何升级。不过还是劝大家暂时不要升级，下个版本感觉不稳定，有很多诡异的问题产生，而且它的兼容性也没有做好。还有就是在markdown里写Liquid脚本。这才是个渣。因为有时候希望这些脚本被显示的展示给用户，那么就需要将这些脚本转为16进制，否则Liquid就会解析该代码。所以用16进制写{&#37;&#37;}，或者直接使用截图的方法。另外Octopress的双引号解析更渣，都解析反了&#8230;所以推荐使用单引号。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[借助有道云笔记写blog]]></title>
    <link href="http://chilly.github.com/blog/2013/07/15/jie-zhu-you-dao-yun-bi-ji-xie-blog/"/>
    <updated>2013-07-15T22:12:00+08:00</updated>
    <id>http://chilly.github.com/blog/2013/07/15/jie-zhu-you-dao-yun-bi-ji-xie-blog</id>
    <content type="html"><![CDATA[<h2>0. 前言</h2>

<p> &nbsp; &nbsp; &nbsp; &nbsp;下面这个blog介绍一下如何借助有道云笔记来写blog. 这里的blog当然是公开的非私密的。帐前卒 的 blog是借助Octopress搭建在github上，使用的markdown写成。由于github对于免费的成员只提供400MB的空间。对于图文并茂的blog来说，这点空间有点相形见绌。所以急需找到一个能提供图片分享的地方。图片分享的地方很多：</p>

<ol>
<li>当然很多图床网站可以提供的(当然也有可能不小心被封了)</li>
<li>小bbs站(游客身份也可以查看，同时这个小站提供上传图片功能)可以试试<a href="http://notebbs.youdao.com" title="有道云笔记论坛">有道云笔记官方论坛</a></li>
<li>网易云相册啥的</li>
<li>各种其他的blog站点，写一篇blog上传，里面加入图片。然后把图片地址放入markdown中</li>
<li>本文重点要介绍<strong>使用有道云笔记 分享</strong>方式添加图片。不过这一种不如前面几种简单实用。但是可以分享25M以下的任意图片，并且没有数量限制，空间还在不断增长。</li>
</ol>


<h2>1. 分享你的图片</h2>

<p>  &nbsp; &nbsp; &nbsp; &nbsp;首先打开有道云笔记的客户端，然后创建一篇新的笔记，然后点击<strong>&#8216;分享链接&#8217;</strong>
<img src="http://note.youdao.com/yws/public/resource/d54e01fec212f37df16b5bcd032a83dd/25FBFC3EADAD4EDEB46F9AD6F147C0D9" alt="分享链接 图片" /></p>

<h2>2. 获取图片地址</h2>

<p>  &nbsp; &nbsp; &nbsp; &nbsp;打开浏览器(chrome, 火狐,IE均可) 这里只介绍firefox. 点击<a href="http://note.youdao.com/share/?id=d54e01fec212f37df16b5bcd032a83dd&amp;type=note">分享链接</a>。然后在调出firebug. 使用它，选中你要获取的图片。然后就可以看到下面这段html. 注意其中的src属性。没错，这就是你的图片url了。</p>

<pre><code>&lt;img data-inited="true" src="http://note.youdao.com/yws/public/resource/d54e01fec212f37df16b5bcd032a83dd/25FBFC3EADAD4EDEB46F9AD6F147C0D9" data-media-type="image"&gt;
</code></pre>

<p><img src="http://note.youdao.com/yws/public/resource/d54e01fec212f37df16b5bcd032a83dd/AB825A2093E648FC8210B144318EDDFA" alt="firebug界面" /></p>

<h2>3. 在markdown中编辑</h2>

<p> &nbsp; &nbsp; &nbsp; &nbsp; 接下来要做的就是在markdown中插入图片.</p>

<pre><code>![图片名] (刚才从有道云笔记分享获取的url)
</code></pre>

<h2>4. 发布</h2>

<p> &nbsp; &nbsp; &nbsp; &nbsp; 这里就没有什么好说的了。<strong>Deploy it!</strong><br/>
 另外编写markdown需要注意的:</p>

<ol>
<li>段首空格需要加 &amp;nbsp; 另外如果需要多个空格，那么每个&amp;nbsp之间都要有空格。</li>
<li>如果写为段落列表那么需要在每个列表后加入一个空行</li>
</ol>


<blockquote><pre><code>  [空行]
  1.  aaa
  1.  bbb 
</code></pre></blockquote>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[圣诞玫瑰]]></title>
    <link href="http://chilly.github.com/blog/2013/04/05/sheng-dan-mei-gui/"/>
    <updated>2013-04-05T01:42:00+08:00</updated>
    <id>http://chilly.github.com/blog/2013/04/05/sheng-dan-mei-gui</id>
    <content type="html"><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;做影评前，先做下功课：圣诞玫瑰(Christmas Rose) 是1月21日和1月25日的生日花，也是一种草药。别名秋红、圣诞红。花语为‘<strong>犹豫</strong>’。<br/>
<img src="http://chilly.github.com/images/christmas_rose.jpg" title="圣诞玫瑰" alt="圣诞玫瑰的图片" /> <br/>
&nbsp;&nbsp;&nbsp;&nbsp;个人评论：这个花和普通的玫瑰看起来没有什么区别，可能是粉色的.所以情人节那天还是只能送<strong>大红色的玫瑰</strong>  <br/>
&nbsp;&nbsp;&nbsp;&nbsp;这部影片延续了郭富城近几年的风格：压抑的侦探式剧情，虽然他在该剧中饰演律师。在这部影片一直在讲故事，中间有能预料到的转折。所以我个人认为导演怕各位观众智商低看不懂，所以各个转折之前都有铺垫。这样故事转折不是那么突兀，但是丧失意外的悬疑影片讲述的一个很压抑的故事。这样的感觉好像是妈妈对小朋友讲故事，而结局就是皆大欢喜。当然对于没有听过故事的小朋友，估计是引人入胜。而听过一遍的，基本上不想再听第二遍。故事本身的叙事还是不错，一个半小时也没有觉得多长。转折起伏不多，基本上也不费脑细胞，没有大场面，没有意外的结局。<br/>
&nbsp;&nbsp;&nbsp;&nbsp;从整个表面上把这个影片分析完了。再来看看导演究竟想说什么主题。我和LP的分歧在于该影片在宣扬人间公义，定义律师心中的准则；还是关爱他人，给他们希望和机会；还是其实影片啥也没有说，只是讲述社会的缩影。<strong>公义</strong>这个词在这个影片中多次出现，另外还有一副不知名的油画(导演杨采妮说那叫众生相)，混沌并且表情不一。在混沌中，公义或者说正义是什么？无论如何帮助弱者，因为弱者已经很弱；还是维护所谓的事实公正？这真是两难的抉择。让我想到无责撞人的司机，还有搀扶非自己撞倒的老太，这两者都要赔偿一定的损失。所谓两难，从关系人两面分析，就能知道大概。<strong>给机会和希望</strong>这个主题应该是最后一点时间郭富城所说的那几句话引发的。“假如人人都充满爱”，就没有这样的悲剧发生了。但可惜的是，就是因为当事者都太有爱了，所以才有这件事。另外一个观点：<strong>社会缩影</strong>。这个倒是有点意思，因为该影片反映的太多的是是非非。律师不是侦探。如果心有公正，就不会说星期天一根本就没有罪。而有公正之心的早就推辞不接活了。所以总结为：</p>

<pre><code>  不念父母情，小三想上位，
  世俗偏弱势，舆论贬强人，
  做人心不悔，是非谁人罪。 
</code></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;影片好坏自在人心。都是在讲故事，最主要是要抓住人心，留一丝牵挂之想。或喜悦，或兴奋，或压抑，或悲伤，千言万语总汇成心底的回忆。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[long weibo长微博]]></title>
    <link href="http://chilly.github.com/blog/2013/01/08/long-weibochang-wei-bo/"/>
    <updated>2013-01-08T21:15:00+08:00</updated>
    <id>http://chilly.github.com/blog/2013/01/08/long-weibochang-wei-bo</id>
    <content type="html"><![CDATA[<p>今天有人提议在贵公司举行的“黑客马拉松”中搞一个项目&#8221;长微博生成工具&#8221;。开始假设都挺好的，说只需要一个文本，就能重用以前的服务，然后做一个这样工具出来。开始大家真心觉得不错。好做又能功能复用。就在大家热情高涨的时候，我说：“这样的工具已经有了。”</p>

<p>长微博源自于一般微博只有140字，如果希望字数更多，那么就要将这样的文字转换为图片，然后以图片的形式发布出去。这样看到这条微博的人就能看到更多的信息。其实将文字转图片不难，但是将html转图片，就需要考虑展示了。java的能做，c++的也能做到，大家可以调研一下。长微博的站点现在有：</p>

<ol>
<li><p><a href="www.changweibo.com">长微博，站点名就叫这个</a>  这个网站支持富文本编辑，并且支持图片和表格插入。该网站开始的编辑区就是和微博最终图片展示的大小相同，所以不必担心超宽度。</p></li>
<li><p><a href="http://www.taichangle.com/">太长了</a> 这个网站比前一个简陋了很多，只是支持简单的图片插入(头/尾)， 不过支持自己的logo和版权。相比第一个这点好很多。但是实在是太简陋了。</p></li>
<li><p><a href="http://www.cwbgj.com/">长微博@工具</a> 这个网站比前一个还简陋.就不多说了。大概是这两个网站都没有时间做富文本编辑器。</p></li>
<li><p><a href="http://control.blog.sina.com.cn/admin/article/changWeiBo.php">新浪原生的长微博工具</a>  这个是支持富文本了，但是这个东西是和新浪博客合在一起使用的。如果不是新浪微博上自己的文字，是不能被发布的。基本无用。</p></li>
<li><p><a href="http://note.youdao.com">有道云笔记长微博工具</a> 使用方式在PC端中分享微博就可以了。老王卖瓜，我这里就不夸了。说说现在的缺点，对于某些富文本的内容展示的效果还不是太理想。另外字体还是不太好看。正在持续改进中&#8230;欢迎使用</p></li>
</ol>


<p>话说贵公司发的明信片太多的广告。有人问祝福语应该写在哪里？上面全都是贵公司各个产品做得广告。我说：&#8221;那你就写4个字：欢迎使用。&#8221;</p>

<p>老婆终于学会她年会的舞蹈了，太有喜感了。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[2013.01.07今日见闻，奖金，年终奖，感谢贵公司]]></title>
    <link href="http://chilly.github.com/blog/2013/01/06/2013-dot-01-dot-07jin-ri-jian-wen/"/>
    <updated>2013-01-06T22:16:00+08:00</updated>
    <id>http://chilly.github.com/blog/2013/01/06/2013-dot-01-dot-07jin-ri-jian-wen</id>
    <content type="html"><![CDATA[<p>today, 今天发了双薪，本来那一个月的薪水是应该在奖金中一起发的。按照过去的发钱方法交税是比较少的，还能给自己留点余额。今年可好了，一半的工资都被做为税收了&#8230;感谢国家，感谢党，感谢贵公司。</p>

<p>据说年终奖4万元以上的话，这样发双薪划算。想来贵公司这么的人性化。老婆说没发这么多年终奖的话，就不让我回家&#8230;所以我准备从现在开始筹钱。</p>

<p>今天贵公司发的二手笔记本电源灯一直闪红色，插电源充电也没有用。解决方法不是换电源、不是换主板、不是换另外一个二手电脑，而是用贴纸把灯贴住。感谢贵公司，我又学会了节省。</p>

<p>今天打开了久违的虚拟机，写了blog. 很长时间没有用，都不知道怎么写octopress的blog了。</p>

<p>老婆大人边在旁边跳舞，边在旁边讥讽我拿了双薪&#8230;我问她为什么跳舞不动手，她说还没有学会手的动作&#8230;</p>

<p>今天重构了一下RSA,AES模块，发现和c++通信的RSA模块还是不行，这该死的RSA算法,写的非常的通用，就是多个语言之间通常都不用。嗯，&#8221;通用&#8221;新解。</p>

<p>另外今天发布blog一直不成功，后来发现需要先验证git.com的邮箱&#8230;竟然有这样的事情.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[JAVA Mail API problem]]></title>
    <link href="http://chilly.github.com/blog/2012/07/08/java-mail-api-problem/"/>
    <updated>2012-07-08T23:07:00+08:00</updated>
    <id>http://chilly.github.com/blog/2012/07/08/java-mail-api-problem</id>
    <content type="html"><![CDATA[<ul>
<li>text/html mime 没有base64 编码问题</li>
</ul>


<p>java mail api 使用MimeBodyPart.setDataHandler()不能对text/html进行正常的base64编码而是使用quote-printable编码。 错误的样本：</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>// add headers 不能在最前面，一定要放在后面，否则可能不能正确编码
</span><span class='line'>mimeBody.addHeader("Content-Type", "text/html; charset=utf-8");
</span><span class='line'>mimeBody.addHeader("Content-Transfer-Encoding", "base64");
</span><span class='line'>DataHandler textDataHandler = new DataHandler(new ByteArrayDataSource(
</span><span class='line'>                message.getBytes("utf-8"), "text/html; charset=utf-8"));
</span><span class='line'>mimeBody.setDataHandler(textDataHandler);</span></code></pre></td></tr></table></div></figure>


<p>正确的样本：</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>DataHandler textDataHandler = new DataHandler(new ByteArrayDataSource(
</span><span class='line'>                message.getBytes("utf-8"), "text/html; charset=utf-8"));
</span><span class='line'>mimeBody.setDataHandler(textDataHandler);
</span><span class='line'>// add headers 一定要放在后面，否则可能不能正确编码
</span><span class='line'>mimeBody.addHeader("Content-Type", "text/html; charset=utf-8");
</span><span class='line'>mimeBody.addHeader("Content-Transfer-Encoding", "base64");</span></code></pre></td></tr></table></div></figure>


<ul>
<li>发送到新浪等邮箱，图片看不到</li>
</ul>


<p>rfc2045-2047中并没有规定Content-ID的形式必须是: Content-ID:<cid>的形式。但是新浪的邮箱服务解析得比较严格。所以在JavaMail Api 中使用MimeBodyPart 对其进行setContentID时必须加上&#8221;&lt;>&#8221;。否则图片会看不到。例如:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>MimeBodyPart tmpBodyPart = new MimeBodyPart();
</span><span class='line'>tmpBodyPart.setContentID("&lt;"+attachment.getFileid()+"&gt;");</span></code></pre></td></tr></table></div></figure>


<ul>
<li>html格式正文被163等邮箱当作附件，但是某些邮箱解析正常</li>
</ul>


<p>这是因为html格式的正文并不是MultiPart中的MimeBodyPart，而MultiPart的第一个MimeBodyPart可能是附件。在添加html正文时可以这样写：</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>//将html正文放入到mimBodyPart中
</span><span class='line'>String html="&lt;html&gt;xxxx&lt;/html&gt;";
</span><span class='line'>MimeBodyPart mimeBody = new MimeBodyPart();
</span><span class='line'>mimeBody.setText(html, "utf-8");     
</span><span class='line'>mimeBody.addHeader("Content-Type", "text/html; charset=utf-8");
</span><span class='line'>mimeBody.addHeader("Content-Transfer-Encoding, "base64");
</span><span class='line'>
</span><span class='line'>//创建mixed 和 related两种mime subType
</span><span class='line'>Multipart mPartRelated = new MimeMultipart("related");
</span><span class='line'>Multipart mPartMixed = new MimeMultipart("mixed");
</span><span class='line'>mPartRelated.addBodyPart(mimeBody);
</span><span class='line'>MimeBodyPart mimeBodyPart = new MimeBodyPart();
</span><span class='line'>mimeBodyPart.setContent(mPartRelated);
</span><span class='line'>// 设置为第一个 bodyPart,这样就不会再变为附件。
</span><span class='line'>mPartMixed.addBodyPart(mimeBodyPart, 0);
</span><span class='line'>
</span><span class='line'>// mPartMix就是最后要set到mimeMessage中的内容。</span></code></pre></td></tr></table></div></figure>


<ul>
<li>inline图片当作附件，或者inline图片在某些邮箱中显示了两次</li>
</ul>


<p>有些是邮箱会将这个作为feature,但是有些不是。这时要使用这些邮箱来发一封类似的邮件来看到底是那个邮箱的独特功能还是你的bug. 如果是你的错误，那应该是你将inline图片和html直接包到mime/mixed中，其实应该放入到mime/related中的。 所以把这个错误改正，应该就ok.</p>

<ul>
<li>邮件中的文本，线上打开乱码</li>
</ul>


<p>这是因为发送邮件的编码问题。文本的charset不要编码为utf-8，因为这样可能有非utf-8的文本放入到邮件中发送。所以要写二进制编码 Content-Type: application/octet-stream 然后使用base64编码。 这样大部分编码就解决了。但是qq等其他客户端会有问题，这是他们自己的问题.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[java 正则式]]></title>
    <link href="http://chilly.github.com/blog/2012/07/08/java-zheng-ze-shi/"/>
    <updated>2012-07-08T22:52:00+08:00</updated>
    <id>http://chilly.github.com/blog/2012/07/08/java-zheng-ze-shi</id>
    <content type="html"><![CDATA[<p>摸索多次终于写出正确的java的关于email匹配的正则式：</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>import java.util.regex.Pattern;
</span><span class='line'>import java.util.regex.Matcher;
</span><span class='line'>Pattern emailPattern = Pattern.compile("^[\\w\\!#\\$%\'\\*\\+/=\\?{\\|}\\~\\^\\.\\-_]+@[\\w\\.\\-]+$");
</span><span class='line'>Matcher m = emailPattern.matcher("xx@xxx.com");
</span><span class='line'>if(m.matches()){
</span><span class='line'>  // if match
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>注意其中的&#8221;-&#8220;，&#8221;+&#8221;等,这个在正则式中有特殊含义，如果&#8221;-&#8220;放在[]的中间，则表示从哪个字符到哪个字符,例如:[A-Z]。如果仅仅想表示&#8221;-&#8220;可能会出现，那么还要进行转移，所以就有&#8221;&#45;&#8221;这样的形式。 上面正则式的意思是：以字母或者数字\w或者以!#$&#8217;*+/=?{|}~<sup>.-_开头的1&#8230;n个字符，1个@字符，以字母或者数字或者.-结尾的字符串.</sup></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[上传大文件]]></title>
    <link href="http://chilly.github.com/blog/2012/05/16/shang-chuan-da-wen-jian/"/>
    <updated>2012-05-16T23:45:00+08:00</updated>
    <id>http://chilly.github.com/blog/2012/05/16/shang-chuan-da-wen-jian</id>
    <content type="html"><![CDATA[<p>今天解决了上传大文件问题。这个问题对于简单的web程序基本是不用关注的。不过需要考虑http超时和socket超时等情况。对于nginx代理跳转的web程序，需要在nginx中设置client_max_body_size 和 proxy_read_timeout这两个地方。前一个参数是http body size,例如你要上传10M的文件，你这里需要设置11M或者更大，因为http body中不光有文件的二进制信息。后者是设置proxy server与后端server的连接后等待返回的时间。例如后面使用的是JBoss那就是与JBOSS的连接。</p>

<p>确定问题比较容易。如果一个请求发生，但是后端Server没有打印access log.那就说明请求还没有到后端server，需要检查代理服务器的设置。如果请求写入access log,但是没有被server后端的webapp打印出log,一般说明在后端的server处挂掉，需要检查后端server的相应配置。当然也可能是webapp自己直接做了限制，例如设置如下类的参数</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>org.springframework.web.multipart.commons.CommonsMultipartResolver</span></code></pre></td></tr></table></div></figure>


<p>这里设置后会导致在<code>doFilter()</code>之后parseRequest时挂掉。如果看到报类似SizeLimit exception或者 max upload file exception,大概就是这里的问题。</p>

<p>最后要检测app代码中是否也有这些限制。以及检查client端socket timeout等情况。以下代码是针对client socket提前超时设置的。</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>HttpParams params = new BasicHttpParams();
</span><span class='line'>HttpConnectionHttpParams.setConnectionTimeout(params,60000); // 连接超时1分钟
</span><span class='line'>HttpConnectionHttpParams.setSoTimeout(params, 60000); // socket 读取写入超时
</span><span class='line'>DefaultHttpClient client = new DefaultHttpClient(params);</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[cookie]]></title>
    <link href="http://chilly.github.com/blog/2012/05/11/cookie/"/>
    <updated>2012-05-11T01:26:00+08:00</updated>
    <id>http://chilly.github.com/blog/2012/05/11/cookie</id>
    <content type="html"><![CDATA[<p>Cookie的特性：</p>

<ul>
<li>首先分为3种cookie:

<ol>
<li>持久化cookie(persist cookie), 这种cookie有过期时间, 关掉浏览器还存在。</li>
<li>会话cookie(session cookie), 这种cookie没有过期时间，关掉浏览器就消失。</li>
<li>要被删除的cookie(deleted cookie). 这种cookie到达请求方就立即失效了。不会再带回服务器端。</li>
</ol>
</li>
<li>Cookie的domain一定要对。例如发送给note.youdao.com的cookie, domain可以是.note.youdao.com, 可以是.youdao.com.但是最好是.note.youdao.com, 否则有可能给其他的应用带去不必要的cookie, 增大传输量。</li>
<li>Cookie的path一定要对，如果在生成cookie时没有指明，那就是那个页面的当前路径。例如note.youdao.com/web/x.html 生成了cookie, 那路径就是/web, 再访问note.youdao.com/时，这个cookie不会被带上。只有/web以及/web的子路径可以得到该cookie.所以一般cookie的path设置为&#8221;/&#8221;.</li>
<li>Cookie是否是HTTP ONLY.这个对JS很重要。其实就是SET-COOKIE: header中加入了httponly的字段。但是HttpOnly的cookie, JS是拿不到的。在一定程度上保证安全。</li>
<li>永久cookie是跨进程的。当然chrome做到session cookie也跨进程(跨chrome进程)。永久cookie可以跨所有的进程。例如客户端用A帐号访问，web端用B帐号访问。客户端的永久cookie会带到web访问中。</li>
<li>JAVA的HttpClient或者其他httpClient库发送cookie到server时不会带上HTTPOnly或者domain信息，因为他们只有对的domain才会发送cookie. 但是如果server要做抹除客户端cookie的事情，那就必须在返回消息中发送除cookie value和过期时间不一致，其他都要一致的cookie才行。否则达不到抹除的目的。</li>
</ul>


<p> 就先写到这里。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[server 1.6 上线]]></title>
    <link href="http://chilly.github.com/blog/2012/05/11/server-1-dot-6-shang-xian/"/>
    <updated>2012-05-11T00:30:00+08:00</updated>
    <id>http://chilly.github.com/blog/2012/05/11/server-1-dot-6-shang-xian</id>
    <content type="html"><![CDATA[<p>今天server端上线，自己负责的两个server上线，一个更新了依赖，另外一个FIX了一个稳定性问题。当然变化最大的server很快就会上线。话说本产品的最大竞争对手入住中国，本以为有啥大事发生，后来发现只改了个名字。搞出一个中国公司这事情还要瞒着zzzz</p>

<p>然后今天晚上发现微博里好多活动的人。都有做server的潜质呀。</p>

<p>个人感觉还是不要加什么硬类型，什么硬编码，什么字段。map存储是扩展王道。当然弱类型肯定速度慢，但如果这里速度慢不是瓶颈，那不算什么问题。</p>

<p>这周解决的问题颇多，后来发现是自己遗留下的问题颇多。当初的设计想想都是很奇葩的。现在只能愈加奇葩。下个版本重构一下，遗留的能fix的就fix吧。</p>

<p>答辩终于结束，心里压力顿时小许多。filter呀filter, 整合入common吧～</p>

<p>明早倒休&#8230;.要睡到中午~~~~</p>

<p>好吧，有空出篇技术贴，现在写blog太水了。</p>

<p>Server上线还是没有一次成功。又出了各种小问题。这次主要是由于配置文件线上和milestone不同。以后要diff一下milestone的配置文件和online的配置文件。确认后再上线。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[新浪Oauth认证又改出bug...mismatch url]]></title>
    <link href="http://chilly.github.com/blog/2012/04/26/sina-oauth2/"/>
    <updated>2012-04-26T22:18:00+08:00</updated>
    <id>http://chilly.github.com/blog/2012/04/26/sina-oauth2</id>
    <content type="html"><![CDATA[<p>万恶的新浪呀～～～今天本来事情多，结果新浪Oauth2.0接口突然有变化。导致新浪用户无法使用有道云笔记登录，登录就会有mismatch url error。于是今天做hot fix. 一时找不出问题时，客户端登录不上去，但是web可以正常使用。然后经大师兄点拨，对比了一下两个访问新浪的url,终于发现了不同。原因在于某个新浪小白程序猿写程序出了bug。我的callback地址是四级域名（xx.xx.youdao.com）而新浪现在的接口即使绑定了域名，还是只支持三级域名(xx.youdao.com). 以前新浪的小白程序猿还写出来仅接受一个url参数的神奇程序，当然出现这个情况也在意料之中。我时常在想写新浪微博和写新浪微博openAPI的一定不是同一批人。最主要的是新浪更新或者新浪自己挂掉从来不通知开发者。这让人相当费解。只有不要传播谣言啥的专门给开发者发信&#8230;他们真有趣。</p>

<p>知道了原因，首先做hot fix.让新浪那边改，那难比登天呀。做第三方这事情还是QQ做得好些。Hot fix比较恶心，不推荐大家学习。虽然只改了一句code，但是是硬编码。Hot Fix之后，所有的客户端就能正常登录了。但是有道云笔记的页面会最终说..其实你没有认证成功的&#8230;.但是客户端的确是活着好好的。这是为啥&#8230;上了趟厕所，灵感来了。有道server完成了跳转，但是因为cookie的domain和callback的域名不一致。所以那个最终页面看到没有带来cookie呀，那肯定登录失败了。但是cookie被client端很好接收。所以也就可以完成登录和获取数据。这就是为啥登录失败了，但是客户端还活着好好的。</p>

<p>然后继续做Hot FIX.后来发现自己编来编去，还是太丑陋。直接叫运维做了一个跳转&#8230;然后客户端就活得好好的了。也不会出现登录失败页了。</p>

<p>今天大事小事都赶到一起了。做了一个TTT，本以为写得概括大家就都能听懂，结果大家都听得很朦胧。以后写ppt还是要写细致一些，还要写挑战和为什么要做这件事。嗯嗯，下次会更好..这又让我想到写论文&#8230;话说敏姐的致谢中大部分都是在赞美导师&#8230;这一定是怕不让毕业&#8230;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[svn diff]]></title>
    <link href="http://chilly.github.com/blog/2012/03/21/svn-diff/"/>
    <updated>2012-03-21T21:21:00+08:00</updated>
    <id>http://chilly.github.com/blog/2012/03/21/svn-diff</id>
    <content type="html"><![CDATA[<p>最近碰到了<code>svn merge</code>之后，再使用<code>svn diff</code>产生出来的patch中缺少某些文件的信息。后来发现了原因。使用<code>svn st</code>查看那些文件信息，类似于:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>A       src/aa.c
</span><span class='line'>A   +   src/bb.c
</span><span class='line'>M       src/cc.c</span></code></pre></td></tr></table></div></figure>


<p>这样输出的patch中，aa.c是信息是都有的。cc.c也是有的。但是bb.c的信息不存在。主要是存在那个<code>+</code>. <code>+</code>的意思是这些文件存在于提交历史中，所以该文件不能再次被diff.但是为什么会存在于提交历史中，这个我就不知道了。   <br/>
下面是教你如何去掉<code>+</code>.
使用下面的脚本会方便的去掉各个文件的<code>+</code>,对于目录的<code>+</code>是不能去掉的.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>#!/bin/sh
</span><span class='line'>plus_file=`svn st | grep "^A" | grep "+" | cut -d" " -f6`
</span><span class='line'>for i in $plus_file; do
</span><span class='line'>        if [ -d $i ]; then
</span><span class='line'>                echo "skip $i"
</span><span class='line'>        else
</span><span class='line'>                cp ${i} ${i}.back;
</span><span class='line'>                echo $i;
</span><span class='line'>                svn revert $i;
</span><span class='line'>                mv ${i}.back ${i};
</span><span class='line'>                svn add $i;
</span><span class='line'>        fi
</span><span class='line'>
</span><span class='line'>done;</span></code></pre></td></tr></table></div></figure>




<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>上面脚本的工作原理是:
</span><span class='line'>cp src/bb.c src/bb.c.back
</span><span class='line'>svn revert src/bb.c
</span><span class='line'>mv src/bb.c.back src/bb.c
</span><span class='line'>svn add src/bb.c</span></code></pre></td></tr></table></div></figure>


<p>这样所有的<code>A +</code>状态就变为了<code>A</code>。这样再使用<code>svn diff</code>就可以得到完整的diff信息。如果有想法还可以处理一下文件夹。不过review code时，文件夹的意义并不大，所以就没有处理。这里顺便感谢下巧大牛。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[有道云笔记1.5正式版上线]]></title>
    <link href="http://chilly.github.com/blog/2012/02/23/you-dao-yun-bi-ji-1-dot-5zheng-shi-ban-shang-xian/"/>
    <updated>2012-02-23T02:08:00+08:00</updated>
    <id>http://chilly.github.com/blog/2012/02/23/you-dao-yun-bi-ji-1-dot-5zheng-shi-ban-shang-xian</id>
    <content type="html"><![CDATA[<p>今天晚上..或者说今天早上。反正是跨天的.有道云笔记1.5版本正式上线。开始时数据转换花了很长时间。后面基本没有出现什么大问题，主要是id不统一。整到两点钟才算正式搞好。明天早上就不准备去上班了.困&#8230;还是把这篇blog写完吧。</p>

<h4>问题：</h4>

<ol>
<li>其实测试环境下，还是不能测试出所有到问题。因为和线上的配置不一样。</li>
<li>其实组内改动什么设计问题，可能牵扯到几个人，但是做设计或者真正写代码的时候，其实不知道牵扯到谁。</li>
<li>web页面的文字链.其实没有提前做好。不知道为什么UI总是在临上线的时候才有。</li>
<li>技术先导的project,再让PM来设计.真的是比较痛苦。</li>
</ol>


<h4>新的功能：</h4>

<ol>
<li>客户端新浪微博帐号登录。其实根据现在的涉及还是有些bug的。比如打开两个授权页面，第一个页面其实已经不能再用来登录了。但是用户输入用户名密码还是会授权成功。至于为什么..我不告诉你～</li>
<li>锁屏&#8230;离线登录态&#8230;.还有啥就不知道了。</li>
<li>server端的设计有改动。</li>
<li>。。。。。</li>
</ol>


<h4>好了..该去睡觉了。</h4>

<p>另外今天上线的是有道云笔记1.5正式版&#8230;..比官方稿件快7-8个小时&#8230;
另外地址是<a href="http://note.youdao.com">有道云笔记1.5</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[windows c++程序迁移到linux]]></title>
    <link href="http://chilly.github.com/blog/2012/02/21/windows-c-plus-plus-cheng-xu-qian-yi-dao-linux/"/>
    <updated>2012-02-21T20:16:00+08:00</updated>
    <id>http://chilly.github.com/blog/2012/02/21/windows-c-plus-plus-cheng-xu-qian-yi-dao-linux</id>
    <content type="html"><![CDATA[<p>今天把程序从windows上迁移到了linux上。主要遇到到问题是: makeFile, lib库, compile error, 编码 encoding.</p>

<h4>make file</h4>

<p>这里其实可以使用eclipse中到cdt插件，然后就可以从eclipse中写c++。挺方便的，同时也解决了make file的问题。因为创建一个c++ 或者 c project，eclipse会自动创建一系列的makefile文件。所以让make file步骤简单无比。</p>

<h4>lib库和include库</h4>

<p>这里真的要注意/usr/include和/usr/lib中是否有你想要到文件。当然如果你是纯c++代码，可以尝试下只使用/usr/include/c++. 当如除了-L libpath, 还有-llibname, 这里的libname其实是libXXXX.so中的XXXX. 不过如果不会写，这里还是会费些劲。还有include路径要使用<code>-I</code>,每一个路径前都要有一个<code>-I</code>. 另外还要在eclipse run configurate中的environment中填入LD_LIBRARY_PATH,这个是你要调用的lib库（这个lib库如果不在/usr/lib中，那么就要手工将路径填入到LD_LIBRARY_PATH变量里）。并且在.bashrc中写：</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>LD_LIBRARY_PATH=$LD_LIBRARY_PATH:your_lib_path</span></code></pre></td></tr></table></div></figure>


<p></p>

<h4>编码</h4>

<p>因为windows上最常用到中文编码是GBK,而文件编码最常用到是utf-16el.这里最有可能会出错。在eclipse中或者gcc直接编译，都最好转换为UTF-8编码。文件也需要是UTF-8的编码。否则就会报&#8221;程序有游离的XXX, 忽略空字符&#8221;等诡异的错误。<a href="http://chillyc.info/blog/2012/02/20/jie-jue-cheng-xu-zhong-you-you-chi-de-slash-xxx-hu-lue-kong-zi-fu/">详见解决方法</a></p>

<h4>compile error</h4>

<p>这个可能就多种多样了。不过有c/c++基础的，应该大部分都可以搞定了。</p>

<p>如果使用eclipse, 直接build project就可以编译成功。然后找到main函数run就可以了。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[octopress error, rake generate]]></title>
    <link href="http://chilly.github.com/blog/2012/02/21/octopress-error/"/>
    <updated>2012-02-21T20:00:00+08:00</updated>
    <id>http://chilly.github.com/blog/2012/02/21/octopress-error</id>
    <content type="html"><![CDATA[<p>Today, I met the following problem. I wrote an article, and use <code>rake generate</code> to generate the site. Then the console reports:</p>

<blockquote><p>/home/chico/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:148:in `parse&#8217;: couldn&#8217;t parse YAML at line 3 column 17 (Psych::SyntaxError)</p></blockquote>


<p>why?   <br/>
Then I found the reason:</p>

<blockquote><p>&#8220;&#92;&#8221; should not be written in title of your article. If you really want to write it, use &#8220;&#92;&#92;&#8221;</p></blockquote>

]]></content>
  </entry>
  
</feed>
