Cross-Site Request Forgery (CSRF)

2016 Oct 21

来自Ruby on Rails Security Guide的一个章节,内容基本上是和特定web框架无关的,推荐一读。

Code Highlighting and More

2016 Oct 19
public void greeting() {
  System.out.println("Hello World");
}

Encode String before Put It into URL

2016 Oct 18

在实现、测试OneFeed的tag功能时,发现tag c++不能正常工作,

<a href="<%= '/posts?tag=' + t.name %>" class="..."><%= t.name %></a>

请求/posts?tag=c++到达server端后,params[:tag]的值为c ,导致数据库查询没有返回正确的结果。

原因是构造href时没有对tag的name做encode,而+恰好是URL规范里的特殊字符,它代表一个空格

Within the query string, the plus sign is reserved as shorthand notation for a space. Therefore, real plus signs must be encoded.

所以,在把一个字符串拼接到URL里前,要先把它encode一下。 毕竟,不是每次测试时都有足够运气使用像c++这样测试数据,提前发现bug。

在Rails里可以通过下面的方法来encode一个字符串,

URI.encode 'c++ java'
# => "c++%20java" 空格被encode,URL规范的特殊字符“+”没有被encode
ERB::Util.url_encode 'c++ java'
#=> "c%2B%2B%20java" 所有字符都被encode,包括像"+", "/", "?"这样的保留字符
<!-- fix: u是url_encode的alias -->
<a href="<%= '/posts?tag=' + u(t.name) %>" class="..."><%= t.name %></a>

关于URL decode,大部分web框架都会自动decode。

注意⚠️,“URL”也包括同一页面内的anchor

<a href="#need-to-encode-too">about</a>
<div id="need-to-encode-too">About us...</div>

另外,在准备测试数据时,别忘了中文;中文也是需要encode的。

When should you use DateTime and when should you use Time?

2016 Oct 16

非常有意思的文章。 莎士比亚和塞万提斯(堂吉诃德的作者)都死于“1616年4月23日”,但是由于当时英国并没有像意大利一样采用公历(格里高利历), 所以两个“4月23日”时间上相隔了10天。

点击文章中的链接可以了解很多有趣的历史。 比如公历是什么时候推广的、联合国教科文组织犯的错误、每个国家推行公历的时间是不同的(比如中国是在1912年)等等。 另外时区的概念也是19世纪铁路流行后才有的概念。

如果程序里要处理历史上的日期,最好了解一下相关的国家是什么时候推行公历的,然后采用的库也要能正确处理这种Pre-Gregorian的日期。

Ruby中的Time类不能正确处理文中提到的“莎士比亚和塞万提斯是不是死于同一天”的问题。 另一个类DateTime可以。

附另一个Stackoverflow上的问题,Why is subtracting these two times (in 1927) giving a strange result?。 讲了什么上海时间的”1927-12-31 23:54:07”和”1927-12-31 23:54:08”差了353秒,而不是1秒。

JVM的noverify选项

2016 Oct 16

遇到java.lang.VerifyError错误可以用-noverify来关闭bytecode verification。

网易云音乐的缓存路径

2016 Oct 16

通过lsof | grep -e "[[:digit:]]\+w" | grep -i netease命令可以找到网易云音乐的缓存目录。

CLI

书籍推荐:Masterminds of Programming

2016 Oct 13

Masterminds of Programming,对多个编程语言作者的访谈。

亚马逊链接豆瓣链接

Masterminds of Programming

Trim String If It is a Key

2016 Oct 13

如果字符串的用途是某种类型的key,那么字符串最好要trim一下,去掉首尾的空格。

曾经遇到一个bug,RabbitMQ中一个queue始终收不到routing key为某些值的message, 但是却能收到routing key为另一个值的message。 Queue的binding是通过配置文件指定的,

<routingKey value="routing-key.a.*, routing-key.b.*, routing-key.c.*">

Routing key为routing-key.b.*routing-key.c.*的消息始终收不到。 尝试直接通过“RabbitMQ Management”(http://localhost:15672/)发送消息,总是得到 “Message published, but not routed.”错误。

最后发现root cause是binding创建的时候是通过value.split(',')来提取routing key的。 因为没有trim所以 routing-key.b.*的开头有个空格。 但是sender在publish message的时候用的routing key总是不带空格的😱。

数据库的index也可以认为是一种key。 假设Customer表有一个email column,且email column是有index的。 那么在存数据或者查询时应该先trim一下email。

不要把重要文件放在/tmp目录下!

2016 Oct 13

永远不要把重要文件放到/tmp目录下,即使是临时存放也不要,因为只要系统一重启/tmp目录就会被清空。

曾经在Ubuntu虚拟机上测试OneFeed部署的时候,想记录下部署时涉及到的每个命令方便后来在生产环境部署。 因为涉及到多个Linux user(一个没有sudo权限的Linux user用于跑Rails App,另一个有sudo权限的user用于安装各种软件), 所以就把文件放在了/tmp目录下。 在差不多部署好的时候,为了能在主机上访问虚拟机上部署的应用,需要配置VirtualBox的Host-only Networks, 配置好后需要重启虚拟机。。。😱

The cleaning of /tmp is done by the upstart script /etc/init/mounted-tmp.conf. The script is run by upstart everytime /tmp is mounted. Practically that means at every boot.

The script does roughly the following: if a file in /tmp is older than $TMPTIME days it will be deleted.

The default value of $TMPTIME is 0, which means every file and directory in /tmp gets deleted. $TMPTIME is an environment variable defined in /etc/default/rcS.

书籍推荐:The Definitive ANTLR 4 Reference

2016 Oct 13