-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
1002 lines (834 loc) · 71.9 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[Trade Off]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/atom.xml" rel="self"/>
<link href="http://www.youth2009.org/www.youth2009.org/"/>
<updated>2015-11-30T23:30:32+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/</id>
<author>
<name><![CDATA[dawncold]]></name>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[Region]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/11/30/region/"/>
<updated>2015-11-30T22:27:11+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/11/30/region</id>
<content type="html"><![CDATA[<p><strong>先说结果,如果你需要构建一个中国大陆地区的省市区数据库,请只参考这里:<a href="http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/">http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/</a>,目前没有比这里更加准确的数据了,但若你又和某些电商网站集成了订单信息,那很可能还会遇到问题,可以看后面。</strong></p>
<p>region问题说大不大说小不小,如果你需要精确的规划物流(或者以后有可能的话)从而降低配送成本,那么region的问题就躲不过。</p>
<p>我国的行政规划编码挺简单,具体编码规则不谈(如果想了解请搜索相关GB开头的文件),某GB文件提到规则中的一条就是作废了的code不会再被是使用,也许有这一条规则就够用一阵子了。行政规划结构很清晰——三级结构,第一层是省及直辖市,第二层一般是“市”、“县”或“xxx市”这样的,第三级是“区”。但根据精简行政规划或者发展的需要,有些地区没有第三级,例如广东省中山市,这样的情况不算多但若要构建一个精确的region表的话,这点知识必不可少。</p>
<p>如果你是一个电商网站,用户只能在你的网站下单,那没问题,但这个时代如果你做的稍微大一些的话,势必要和其他电商网站或平台集成,简单说就是在人家那里开了个店,订单会被导入到你的系统中去(如果不需要导入到你的系统中的话可以不用往下看了,你基本不会遇到region的问题)很可惜现在大家都在拼命收集数据,会员啊、订单啊、用户的个人隐私啊等等,怎么能错过订单这么重要的信息,既然如此,别的平台的订单信息势必会导入到自己系统中来,其中订单中的一个重要的信息就是收货地址。</p>
<p>此时就会遇到一个问题,其他平台的region和我们用的是一样的吗?基本是不一样的,好的developer也许会找一份统计局的数据,但一般的也就从网上搜一个出来,搜到哪个格式看着顺眼的就拿来用了,不对比的话你还看不出大的疏漏,因为省区市的数据变化都不太大。</p>
<p>每年统计局都会更新这个库(除了数据的格式乱七八糟外都还好),有的时候你能看到一次新发布,有的时候你看到的是更新原来的发布时间,但变动都不大,可能有某几个市改名啦、合并啦、降级到区啦、区升级到市啦等等。就是因为改动不会很大所以从网上随便找来一个数据库还真的可以用一阵子,出来混早晚是要还的。</p>
<p>就是由于很多标准不统一,你用A版本的region,我用B版本的,他用C版本的,到底以谁的为准?一般情况下谁都不会改自己的region,因为有历史数据的负担,所以region的集成方式是“不集成”,也就是说直接拼好省市区和详细地址,这样看起来是没问题的,用起来可能也凑合,但这些数据就不再是格式化的了,起码不是符合规范的了,因为有的数据在你这边可能不存在,等你需要用这些数据的时候会很痛苦。</p>
<p>我遇到的问题是,已有系统中的region不知道是哪个版本,和X猫等平台集成的订单没有格式化的省市区数据。更新自己平台的region数据库工作量并不算大,抓取最新数据按照三级的结构存储好,再和已有数据对比,新增、删除(标记删除)、改名就好了,这里用的主键是code,code的编码很简单,前两位是省,中间两位是市,最后的是区,如果是省,那么后面的市区位置都是0,因为我们知道<strong>用过的code不会被重新使用</strong>,所以可以用作主键。</p>
<p>这样可以解决自己数据与最新数据不一致的问题,但仍无法解决多平台region不一致问题,除了大家使用统一标准外没有轻松解决的办法,这里只能吐槽X宝的网站和手机版,他们使用的region都是不一样的,更有甚者手机版的每个城市下面都能找到一个万能的区——“其他区”,PC版的还好,看起来准确,不过因为他们有对地址更加精细的管理,会添加一些本身并不存在区以方便用户的地址添加?例如某些工业园区、开发区、新区等等,最终的解决只能是我们处理这样的地址,看是归到某个区下还是怎样,总之这样的处理规则很多,一切都是为了数据的真实性。</p>
<p><strong>希望有能力可以让这个世界变得更加美好一点的企业能从这些方面出发做一点让人感受得到的改进,有一批人会感受到专业和幸福。</strong></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Push Notification]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/10/30/push-notification/"/>
<updated>2015-10-30T00:30:44+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/10/30/push-notification</id>
<content type="html"><![CDATA[<p>最近App工作接近尾声,还有几个接口没有完成,其中之一就是需要在某些事件发生的时候通知App的后台,继而由App后台通知App,比如“订单即将被关闭,请尽快付款”、“优惠券即将到期”这样的消息。因为这些消息最终是要在用户的App上出现的,一般的做法是以Push notification的形式出现,主流平台android和iOS都是在屏幕最上方出现一些提示,点击后可以进入App的某个地方。</p>
<p>既然这样我们就直接集成第三方平台发送相应的消息好了,不过App做得实在很遗憾,用户点击消息后总会进入到App的消息中心,再点击某条消息才能看到具体内容,这样做可能是比较快,但体验不太好,至少和现有的主流App做法都不太一样,像上个时代的做法。</p>
<p>以上是背景,基于此我们希望能够把App作为推送会员消息的渠道,因为短信渠道现在变得越来越不可用,仅限于发送验证码等transactional消息,其实以上说的消息都是transactional消息,区别于marketing消息,这些消息一般是由用户自主激活的或满足一定条件触发,最终是区别于用户的,一般不是群发性的,例如营销类信息就属于marketing。将用户的App作为消息推送渠道的前提是能够较准确地获取这个用户的App渠道是否可用,如果不可用还是得选择短信等。</p>
<p>对于不同手机平台使用的技术差不多,但机制不太一样,不过这是有原因的。例如iOS上的推送机制:设备连接APNs,商户后端推送消息给APNs,再由APNs推送到最终用户的设备上;但android在国内不大一样,由于某些特殊的原因,android的GCM服务(类似APNs)无法使用,继而诞生了很多第三方推送服务商,这些服务商一方面做android的推送,另一方面也接管了到APNs的这块,其实接管APNs这块也不错,因为向APNs推送也并不容易实现——socket长连接,二进制消息等都增加了用户的开发成本,对于一般规模的App开发,使用第三方消息服务商几乎是没得选。</p>
<p><strong>iOS的推送</strong>:在成功推送到APNs时服务商得不到任何响应,也不保证给你送达,用户不在线可以给你保留一段时间等用户上线了再推送,但长时间不在线的话推送消息也会被删除。除非消息格式有错等语法性的错误会得到响应,再就是如果APNs发现用户设备上没有这个App(被用户删除或被用户禁用了推送)会将该设备的ID记录下来,服务商可以通过APNs提供的反馈接口得到这些信息,也就是说只有再次给App推送消息后才有可能知道这条渠道还是不是可用。</p>
<p><strong>android的推送</strong>:目前第三方服务商的做法是做出SDK,让开发App的人集成到App中,这个App安装到系统中后会出现一个Push Service在运行,当然不知道他们哪里来的智慧,如果多个App都用了某一家提供商,并不会启动多个Push Service,一般是一两个,这一两个服务所有App,从而实现了他们所描绘的多App共享长连接很省电什么的。某个设备后台的Push Service会自动和服务商的后端连接,等有消息过来时这些Service会知道该送给哪个App,到了具体的App再由用户的代码处理。由于机制的作用,android的消息服务商是可以实时知道某条消息能不能推送到设备上的,但这毕竟是一个不太常用的功能,所以服务商们一般不会公开这种API,我们用的这家在邮件中才告诉我们是有类似的API,但是VIP级别的,详情需要联系商务部门了解。</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Build Hybla for Ubuntu 14.04]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/10/27/build-hybla-for-ubuntu-14-dot-04/"/>
<updated>2015-10-27T00:42:28+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/10/27/build-hybla-for-ubuntu-14-dot-04</id>
<content type="html"><![CDATA[<p>When I modify some ipv4 config for system I got an error like this: <code>sysctl: setting key "net.ipv4.tcp_congestion_control": No such file or directory</code>, so I followed <a href="http://v2ex.com/t/114788">this post</a> to build a kernel module for ubuntu 14.04</p>
<p>The net/ipv4 hybla Makefile(bad script format in original post):</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'># Makefile for tcp_hybla.ko
</span><span class='line'>obj-m := tcp_hybla.o
</span><span class='line'>KDIR := /home/dejavu/linux-4.1.5
</span><span class='line'>PWD := $(shell pwd)
</span><span class='line'>default:
</span><span class='line'> $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules</span></code></pre></td></tr></table></div></figure>
<p>I also got a warning during build modules: <code>No X.509 certificates found</code>, but it doesn’t matter I think, I can build the <code>tcp_hybla.ko</code> and load in kernel.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Save Red Status Elasticsearch]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/10/26/save-red-status-elasticsearch/"/>
<updated>2015-10-26T22:49:13+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/10/26/save-red-status-elasticsearch</id>
<content type="html"><![CDATA[<p>Someday when I use Kibana, I got an error all shards failed, so I look through office guide and some posts on the Internet.</p>
<p>Maybe the memory limit results in some primary shards can not be loaded by elasticsearch. If one or all primary shards are unsigned, your elasticsearch cluster will be in red status, if all primary shards are loaded, your cluster status will be yellow, if all shards are loaded, the green status you will be get.</p>
<p>The data is stored in <code>index</code> in elasticsearch, the <code>index</code> will be divided into some shards, the shards are <code>primary</code> and <code>replica</code> kind, you can have no replica, but you can have no primary. replica shards will be stored on the other nodes in cluster, but in default setting, you have only two nodes, one is data store node, another one is a client node, and the default setting of index is 2 or 3 replicas for each primary shard, you can update all index setting to disabling this config.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[MSA Thoughts]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/08/29/msa-thoughts/"/>
<updated>2015-08-29T21:51:24+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/08/29/msa-thoughts</id>
<content type="html"><![CDATA[<p>MSA (Micro Service Architecture) is a methodology of dependencies management. Its core thought is divided a large application into some independent small applications, these small applications can be deployed independent and use different programming language, etc.</p>
<p>I think it’s not a new methodology, but a new concept.</p>
<p>We can think you make an application, used some libraries written by others, these libraries are some independent application, they expose some APIs for you, your application import them and call some APIs to fullfill some functions. Generally they will keep same APIs during update and fix bugs, so you can upgrade them and use latest version. You can also copy their codes to your application code base, just like you write all codes, but if they updated, you must copy new codes to your code base, that likes the development without MSA.</p>
<p>So, MSA is a methodology of dependencies management, the example is a small scope of MSA, the real MSA means some independent application, for instance an order service, an logistics service, etc. We may name these order module, logistics module before, but now we name these xxx service.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Sort and Uniq Count]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/08/27/sort-and-uniq-count/"/>
<updated>2015-08-27T19:41:46+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/08/27/sort-and-uniq-count</id>
<content type="html"><![CDATA[<p>I got some logs which recorded someone IP address and the URL it requests, I want to summary how many unique IP addresses request some specified URL, and request counts for one IP address.</p>
<p>so I filter out specified URL rows:</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'>grep URL_PATH *.log</span></code></pre></td></tr></table></div></figure>
<p>then I got these rows:</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>
</pre></td><td class='code'><pre><code class=''><span class='line'>...
</span><span class='line'>[ 2015-08-26T23:59:59+08:00 ] 14.219.202.241 /xx
</span><span class='line'>[ 2015-08-26T23:59:59+08:00 ] 14.219.202.241 /xx
</span><span class='line'>[ 2015-08-26T23:59:59+08:00 ] 14.219.202.241 /xx
</span><span class='line'>[ 2015-08-26T23:59:59+08:00 ] 14.219.202.241 /xx
</span><span class='line'>[ 2015-08-26T23:59:59+08:00 ] 14.219.202.241 /xx
</span><span class='line'>[ 2015-08-26T23:59:59+08:00 ] 14.219.202.241 /xx
</span><span class='line'>...</span></code></pre></td></tr></table></div></figure>
<p>then I use <code>awk</code> print the fourth column:</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'>grep URL_PATH *.log | awk '{print $4}'</span></code></pre></td></tr></table></div></figure>
<p>then I got these IPs, I stored these IPs to a file, then <code>sort</code> and <code>uniq</code>, the <code>uniq</code> excepts a sorted file, the <code>-c</code> option means count these rows:</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'>sort ips | uniq -c</span></code></pre></td></tr></table></div></figure>
<p>then I got some unique rows with counts, but I want sort these rows order by counts desc:</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'>sort ips | uniq -c | sort -k1nr -k2</span></code></pre></td></tr></table></div></figure>
<p>the <code>-k1nr</code> means the KEY starts with first field, and as (n)umber, and ®everse, the <code>-k2</code> means ends with second field. The <code>field</code> means the column in your data.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Tornado-2]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/08/21/tornado-2/"/>
<updated>2015-08-21T22:17:23+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/08/21/tornado-2</id>
<content type="html"><![CDATA[<p>write some subclasses of <code>RequestHandler</code> and mapped these with routers, pass these routers to <code>Application</code>, run <code>Application</code>.</p>
<figure class='code'><figcaption><span></span></figcaption><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>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="kn">from</span> <span class="nn">tornado.ioloop</span> <span class="kn">import</span> <span class="n">IOLoop</span>
</span><span class='line'><span class="kn">from</span> <span class="nn">tornado.web</span> <span class="kn">import</span> <span class="n">RequestHandler</span><span class="p">,</span> <span class="n">Application</span><span class="p">,</span> <span class="n">url</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">HelloHandler</span><span class="p">(</span><span class="n">RequestHandler</span><span class="p">):</span>
</span><span class='line'> <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span class='line'> <span class="bp">self</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"Hello, world"</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">make_app</span><span class="p">():</span>
</span><span class='line'> <span class="k">return</span> <span class="n">Application</span><span class="p">([</span>
</span><span class='line'> <span class="n">url</span><span class="p">(</span><span class="s">r"/"</span><span class="p">,</span> <span class="n">HelloHandler</span><span class="p">),</span>
</span><span class='line'> <span class="p">])</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
</span><span class='line'> <span class="n">app</span> <span class="o">=</span> <span class="n">make_app</span><span class="p">()</span>
</span><span class='line'> <span class="n">app</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">8888</span><span class="p">)</span>
</span><span class='line'> <span class="n">IOLoop</span><span class="o">.</span><span class="n">current</span><span class="p">()</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</span></code></pre></td></tr></table></div></figure>
<p>Tornado supports strings, bytes, and dictionaries as response, you can use Template to building strings and bytes, also you can write response by hand. If you pass a dictionary to response, it will be encoded as JSON.</p>
<p>Tornado will not parse other types request arguments, e.g. Tornado will not parse JSON request bodies, you need to parse these by yourself(override <code>prepare</code> method)</p>
<p>CSRF/XSRF prevent: the session cookie from SiteA is not expired, there is a form in SiteB, the form aims doing something to SiteA, if SiteA don’t support XSRF prevent, it will allow submitting if you constructed valid form arguments. If SiteA supports XSRF prevent, it will set a cookie with token to user, and that token will filled in any action form(POST,PUT,DELETE), if these two values are not equal, that request will be prevented, because SiteB can’t retrive SiteA’s cookie, so that form can’t submit with valid cookie value.</p>
<p>Due to the Python GIL (Global Interpreter Lock), it is necessary to run multiple Python processes to take full advantage of multi-CPU machines. Typically it is best to run one process per CPU.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Tornado-1]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/08/16/tornado-1/"/>
<updated>2015-08-16T16:16:51+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/08/16/tornado-1</id>
<content type="html"><![CDATA[<p>This is the first part of Tornado studying project.</p>
<p>Tornado can be roughly divided into four major components:</p>
<ul>
<li>A web framework (including RequestHandler which is subclassed to create web applications, and various supporting classes).</li>
<li>Client- and server-side implementions of HTTP (HTTPServer and AsyncHTTPClient).</li>
<li>An asynchronous networking library (IOLoop and IOStream), which serve as the building blocks for the HTTP components and can also be used to implement other protocols.</li>
<li>A coroutine library (tornado.gen) which allows asynchronous code to be written in a more straightforward way than chaining callbacks.</li>
</ul>
<p>Tornado uses a signle-threaded event loop.This means that all application code should aim to be asynchronous and non-blocking because only one operation can be active at a time.</p>
<p>There are many styles of asynchronous interfaces:</p>
<ul>
<li>Callback argument</li>
<li>Return a placeholder (Future, Promise, Deferred)</li>
<li>Deliver to a queue</li>
<li>Callback registry (e.g. POSIX signals)</li>
</ul>
<p>There is no free way to make a synchronous function asynchronous in a way that is transparent to its callers.</p>
<p>Coroutines are the recommended way to write asynchronous code in Tornado</p>
<p>A function containing yield is a generator. All generators are asynchronous; when called they return a generator object instead of running to completion.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Checksum Functions in MacOs]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/08/16/checksums-function-in-macos/"/>
<updated>2015-08-16T15:22:06+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/08/16/checksums-function-in-macos</id>
<content type="html"><![CDATA[<p>It’s better to calculate checksum for your downloaded files, it can make sure you download that real file from server, not from the ISP proxy server.</p>
<p>In MacOS, you can use <code>md5</code> and <code>shasum</code> to calculate file checksums.</p>
<ul>
<li>calculate a MD5 checksum</li>
</ul>
<p><code>md5 xxx.data</code></p>
<ul>
<li>calculate a SHA-1 checksum</li>
</ul>
<p><code>shasum -a 1 xxx.data</code></p>
<ul>
<li>calcuate a SHA-256 checksum</li>
</ul>
<p><code>shasum -a 256 xxx.data</code></p>
<p>Thanks for <a href="http://notepad2.blogspot.jp/2012/07/mac-os-x-how-to-generate-md5-sha1.html">here</a></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Exception in Python]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/04/19/exception-in-python/"/>
<updated>2015-04-19T17:05:31+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/04/19/exception-in-python</id>
<content type="html"><![CDATA[<p>My colleague remembered that if you pass some <code>kwargs</code> to an <code>Exception</code> subclass e.g. <code>class MyException(Exception): pass</code>, you will get a composed message when you catch the exception and call <code>e.message</code>. Unitil we got nothing from one place which it should display exception’s message, python language part is implemented by C, so we downloaded python source code(2.7.9), and find these lines.</p>
<figure class='code'><figcaption><span></span></figcaption><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='c'><span class='line'><span class="k">static</span> <span class="kt">int</span>
</span><span class='line'><span class="nf">BaseException_init</span><span class="p">(</span><span class="n">PyBaseExceptionObject</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">PyObject</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">PyObject</span> <span class="o">*</span><span class="n">kwds</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">_PyArg_NoKeywords</span><span class="p">(</span><span class="n">Py_TYPE</span><span class="p">(</span><span class="n">self</span><span class="p">)</span><span class="o">-></span><span class="n">tp_name</span><span class="p">,</span> <span class="n">kwds</span><span class="p">))</span>
</span><span class='line'> <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'> <span class="n">Py_DECREF</span><span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">args</span><span class="p">);</span>
</span><span class='line'> <span class="n">self</span><span class="o">-></span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span><span class="p">;</span>
</span><span class='line'> <span class="n">Py_INCREF</span><span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">args</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">PyTuple_GET_SIZE</span><span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">args</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="n">Py_CLEAR</span><span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">message</span><span class="p">);</span>
</span><span class='line'> <span class="n">self</span><span class="o">-></span><span class="n">message</span> <span class="o">=</span> <span class="n">PyTuple_GET_ITEM</span><span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">args</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'> <span class="n">Py_INCREF</span><span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">message</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>This is python BaseException’s C implementation, I can understand logic but C syntax. The BaseException accepts <code>kwargs</code>, but if you pass a <code>kwargs</code> to Exception, you will get a warning, because of <code>_PyArg_NoKeywords</code>, maybe it needs compatibility with old code, but now, you can’t use <code>kwargs</code>.</p>
<p>Another notice, if you pass one argument to it, this argument will be the <code>e.message</code> value, if not, your args will be placed in <code>e.args</code>.</p>
<p>We finally implemented <code>__str__</code> and <code>__unicode__</code> methods, because of we imported <code>unicode_literals</code>, so we think this is the best practice, we just use <code>str(e)</code> in those places.</p>
<figure class='code'><figcaption><span></span></figcaption><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>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="k">class</span> <span class="nc">TmallAPIException</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
</span><span class='line'> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">sub_code</span><span class="p">,</span> <span class="n">sub_msg</span><span class="p">):</span>
</span><span class='line'> <span class="nb">super</span><span class="p">(</span><span class="n">TmallAPIException</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">sub_code</span><span class="p">,</span> <span class="n">sub_msg</span><span class="p">)</span>
</span><span class='line'> <span class="bp">self</span><span class="o">.</span><span class="n">code</span> <span class="o">=</span> <span class="n">code</span>
</span><span class='line'> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span>
</span><span class='line'> <span class="bp">self</span><span class="o">.</span><span class="n">sub_code</span> <span class="o">=</span> <span class="n">sub_code</span>
</span><span class='line'> <span class="bp">self</span><span class="o">.</span><span class="n">sub_msg</span> <span class="o">=</span> <span class="n">sub_msg</span>
</span><span class='line'>
</span><span class='line'> <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="c"># TODO: not necessary under python3</span>
</span><span class='line'> <span class="k">return</span> <span class="s">'code: {}, msg: {}, sub_code: {}, sub_msg: {}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">code</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sub_code</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sub_msg</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'> <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span class='line'> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__unicode__</span><span class="p">()</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Optimize Shadowsocks NAT Rules]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/01/11/optimize-shadowsocks-nat-rules/"/>
<updated>2015-01-11T23:46:08+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/01/11/optimize-shadowsocks-nat-rules</id>
<content type="html"><![CDATA[<p>Few days ago, I upgraded my OpenWrt box to latest version, there is a new style(Bootstrap) interface and I like it very much(too long lived old world).</p>
<p>Also I found a shadowsocks <a href="https://github.com/shadowsocks/openwrt-shadowsocks">special version</a> for openwrt, it includs China main IP blocks, some requests within this IP range, you could bypass shadowsocks, and this IP blocks is from <code>apnic</code>, very precise but a little long for openwrt, 4000+lines.</p>
<p>I think the most counted IP block I would use it in the future very soon, so I can sort them desc.</p>
<p><code>iptables -t nat -xvnL SS_SPEC_WAN_AC | tail -n+12 | head -n -1 | sort -crnsk 1,1 | awk '{ print $NF }' > /etc/shadowsocks/ignore.list</code></p>
<p><code>tail -n+12</code> means display results from the first 12 row to the end, first 11 rows includes two lines heads, one line shadowsocks server IP, eight lines internal IP blocks;</p>
<p><code>head -n -1</code> means display results except last line(doesn’t work on MacOS), and last line is default shadowsocks redirect rule, so keep it at the same place.</p>
<p><code>sort -crnsk 1,1</code> means <code>c</code>heck first, <code>r</code>everse result, <code>n</code>umerical value(converted from input string), <code>s</code>table sort, <code>k 1,1</code> sort key (start a key at POS1, end it at POS2 (origin 1))</p>
<p><code>awk print $NF</code>, print the last column, that’s very cool.</p>
<p>rewrite the results to ignore.list, and restart shadowsocks, it will use the sorted IP blocks, maybe fast than before 0.xx ms!</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Mailing List in Postfix]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/01/08/mailing-list-in-postfix/"/>
<updated>2015-01-08T19:20:14+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/01/08/mailing-list-in-postfix</id>
<content type="html"><![CDATA[<p>Too simple to making a mailing list in postfix, just define a mailing list name and recipients in <code>/etc/postfix/virtual</code>, like this: <code>dev-group dev1@company.com dev2@company.com dev3@company.com</code>, after that, generate the virtual db by <code>postmap /etc/postfix/virtual</code>.</p>
<p>Don’t forget add <code>virtual_alias_maps=hash:/etc/postfix/virtual</code> in your <code>main.cf</code> file, and restart postfix finally.</p>
<p>I think I need study postfix systemally, just build a private smtp/imap server.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Be Careful Python Fdopen]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/01/07/be-careful-python-fdopen/"/>
<updated>2015-01-07T23:13:39+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/01/07/be-careful-python-fdopen</id>
<content type="html"><![CDATA[<p>I have got a bug when I <code>print</code> something to <code>stdout</code>, I got <code>Bad file descriptor</code>, it means my stdout is a bad descriptor, what?!</p>
<p>Core code like this: <code>logger.StreamHandler(os.fdopen(sys.stdout.fileno(), 'w', 0))</code>, I want to a unbuffered stdout, so I reopen it by <code>fdopen</code>, and reset the buffer size to 0, I still also did same thing to <code>stderr</code>, but that is no sense, because of <code>stderr</code> is unbuffered normally(but in Python3, it maybe line buffered, in MacOS).</p>
<p>If your <code>stdout</code> is reopened by <code>fdopen</code>, and its reference count hits zero, it will be collected by Python GC, also your <code>stdout</code> will be ate by GC, something wrong will happen after that.</p>
<p>So, be careful with <code>fdopen</code> for <code>stdin</code>, <code>stderr</code>, <code>stdin</code>:)</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[联通封了80和8080 but 443 Is Ok]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/01/05/unicom-blocked-80-8080/"/>
<updated>2015-01-05T23:24:57+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/01/05/unicom-blocked-80-8080</id>
<content type="html"><![CDATA[<pre><code>地点:北京
ISP:中国联通
接入方式:光纤入户
</code></pre>
<p>换联通宽带几个月了,感觉良好,但觉得BT下载不够快,因为下的少,也没深究,而且多用迅雷离线下载,基本就是直连迅雷CDN的速度,都能跑满带宽。</p>
<p>OpenWrt多拨尝试过,没有效果,据说早就被封了,所以不再尝试。</p>
<p>前段时间打算把openwrt的管理界面移到WAN和LAN上,即在外面也能访问路由器,默认我就放到了WAN的80上,很可惜失败了,内部访问没问题,外面不行,当时也没多想,总觉得是iptables有问题,一看openwrt的规则,好可怕,嵌套了几层,不看了,改成了别的端口,比如9999,竟然内外都可以,因为后来很少从外面访问,所以这个需求基本是为需求,不管了。</p>
<p>最近把一个网站放到raspberry pi上,路由器做端口映射到内部的80,当时在内网里测试的没问题,还把https也一并做好了。碰巧在公司访问了一下,80不能访问,但443没问题。</p>
<p>今晚直接在PREROUTING的第一行加了log,从外部服务器请求80直接看不到,但443的没问题,而且PREROUTING是第一个被执行的,只能说80的请求就没到这里,可这都是公网对公网的访问了,难道这个请求被某个路由截获然后丢弃了?Google了一下发现几年前几大运营商的能提供公网IP的服务里80和8080端口被封了,说是不能随意搭建网站,想想也是啊,现在国内都得备案才行。</p>
<p>BUT PORT 443 IS OK…</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[聚石塔里面的坑]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/01/05/traps-of-jushita/"/>
<updated>2015-01-05T22:56:42+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/01/05/traps-of-jushita</id>
<content type="html"><![CDATA[<p>今天开始全面接触聚石塔,就是天猫的云平台,上面服务众多,全都能收费,第一次听说了API调用也是可以收费的。下面记录一些可能成为坑的东西,希望有人看到后可以小心躲避。</p>
<h2>创建应用要先报备</h2>
<p>说明书要按照模版写,模板有下载,看说明就能找到,其中里面有个架构图,这个要仔细画,基本思想(阿里思想)就是把你所有的业务系统都放到ECS上,如果在ECS外出现了一个你们自己的平台,他们就怀疑你用ECS做了一个代理来调用API,因为收费API只能是塔内调用,其他没有遇到特别的,时间大概是3天出结果。</p>
<h2>创建应用</h2>
<p>报备通过就可以创建应用了,创建成功后可以去买ECS和RDS等服务,别的服务暂时没用到,这两个服务都是绑定应用的,所以要先有应用。ECS的配置可选的比较少,我在北京,但机房目前只有杭州,所以你写了你的位置也没用,据说杭州那个机房是6线接入,出口质量和淘宝一样,但拿到ECS后ping了一下,31ms左右,第二天ping到了70ms左右,虽然ping不代表什么,但总感觉怪怪的。。。价格和阿里云的ECS相比有些贵。</p>
<h2>ECS</h2>
<p>管理终端有个密码,要改的话记得改完重启机器,否则不生效,而且重启后自己再用管理终端连接一下看看是不是生效了。</p>
<p>他们把10和172.16网段都用了,自己要用内网的话可以考虑多租几个ECS实例,但想玩LXC的话,可以考虑用192.168网段。</p>
<p>DNS不要换别的,就用ECS配置好的,据说改了影响内部访问和RDS通信,我改成114dns后直接无法使用。</p>
<p>我买的是最便宜的ECS,但不知道为何没有SWAP分区,512Mb内存在起了LXC后又编译了一个东西就超了,那里怎么都不行,于是加了SWAP,可以。</p>
<h2>RDS</h2>
<p>我想用聚石塔的推送服务,就是可以把订单、商品等数据推送到买的RDS中,但今天申请的时候对方说应用未上线,不能申请。。。我就是需要这些数据才能开发应用,这不就变成死锁了?</p>
<p><strong>2015年1月7日</strong>:后来和客服沟通,说是应用需要先上线,即便你还没有开始开发,这点虽然有点怪怪的,但只有这样才能申请到同步服务。应用上线挺简单,创建完应用只是第一步,完善基本信息后点下一步即可进入安全扫描阶段,再提交,瞬间说审核通过,这就上线运行了。</p>
<p><strong>2015年1月9日</strong>:商家后台应用有web和客户端两种架构方式,就是你做出一个web应用,一般就是用web的架构方式,用户登陆、授权后,你能拿到用户session,然后就可以用了,和大多数oauth的方式一样,客户端类似。但有一点需要注意,商家后台应用拿到用户的session和refresh token后,文档记载session有效期1年,但这个refresh token无用,只能等session到期后重新授权。</p>
<p>真正开始做了,发现API用起来也不那么爽,这个具体看个人的感觉了,但比拍拍强了不少。</p>
<hr />
<p>目前就遇到这些坑,欢迎更新坑们。</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Host-octopress-blog-on-raspberry-pi]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2015/01/01/build-octopress-blog-on-raspberry-pi/"/>
<updated>2015-01-01T20:25:24+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2015/01/01/build-octopress-blog-on-raspberry-pi</id>
<content type="html"><![CDATA[<p>First post on 2015!</p>
<p>I have a raspberry pi several months ago, and I often use it to recording temp and humidity, uploading to a cloud host, but after a home movement, it had been stored in my drawer. Last day of 2014, while waiting 2015, I want build it and host an external disk for MacBookPro backup(Time Machine), but failed for power supply, normal power supply is not enough for raspi, so I should buy another USB Hub powered by itself.</p>
<p>My raspi used a wireless NIC to connecting with my router(OpenWrt), but I want use a ethernet cable for it, so it can get a unique IP on Internet, but when I pluged it, the wireless NIC would down, because of ifplugd or something else, so I keep the wireless NIC working and add some rules on route, port forward, WAN 80 to rasp 80, WAN 443 to rasp 443.</p>
<p>Install nginx via<code>sudo apt-get install nginx</code>, remove default site<code>rm /etc/nginx/sites-enable/default</code>, add conf in <code>/etc/nginx/conf.d</code>, like this:</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>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>server {
</span><span class='line'> listen 80;
</span><span class='line'> server_name dawncold.me;
</span><span class='line'> return 301 https://$server_name$request_uri;
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'># HTTPS server
</span><span class='line'>
</span><span class='line'>server {
</span><span class='line'> listen 443 ssl;
</span><span class='line'> server_name dawncold.me;
</span><span class='line'>
</span><span class='line'> root /usr/share/nginx/dawncold.me;
</span><span class='line'> index index.html index.htm;
</span><span class='line'>
</span><span class='line'> ssl on;
</span><span class='line'> ssl_certificate /usr/share/nginx/dawncold.me/dawncold.me.crt;
</span><span class='line'> ssl_certificate_key /usr/share/nginx/dawncold.me/dawncold.me.key;
</span><span class='line'>
</span><span class='line'> ssl_session_timeout 5m;
</span><span class='line'>
</span><span class='line'> ssl_protocols SSLv3 TLSv1;
</span><span class='line'> ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
</span><span class='line'> ssl_prefer_server_ciphers on;
</span><span class='line'>
</span><span class='line'> location / {
</span><span class='line'> try_files $uri $uri/ =404;
</span><span class='line'> }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>
<p>I got a SSL certificate from nc.me(github student pack), so I rewrite HTTP to HTTPS.</p>
<p>start nginx via <code>sudo nginx</code> or reload config via <code>sudo nginx -s reload</code>.</p>
<p>Oh, your should update your domain A record to your router WAN ip address, you can write a script or use your router buildin DDNS function.</p>
<p>Octopress supported rsync publishment, so edit your Rakefile and enter your raspi ssh account and nginx html root path, like <code>/usr/share/nginx/www</code>.</p>
<p>publish to github and rasp: <code>rake gen_deploy rsync</code> or only to raspi: <code>rake rsync</code>.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[NotImplemented-in-python]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2014/12/26/notimplemented-in-python/"/>
<updated>2014-12-26T21:03:20+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2014/12/26/notimplemented-in-python</id>
<content type="html"><![CDATA[<p>It’s best to return <code>NotImplemented</code> in magic method(e.g. <code>__eq__</code>, <code>__ne__</code>, etc), see <a href="http://shahriar.svbtle.com/python-notimplemented-type">here</a> for details.</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>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c"># example.py</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">A</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span><span class='line'> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
</span><span class='line'> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
</span><span class='line'>
</span><span class='line'> <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
</span><span class='line'> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">A</span><span class="p">):</span>
</span><span class='line'> <span class="k">print</span><span class="p">(</span><span class="s">'Comparing an A with an A'</span><span class="p">)</span>
</span><span class='line'> <span class="k">return</span> <span class="n">other</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span>
</span><span class='line'> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">B</span><span class="p">):</span>
</span><span class='line'> <span class="k">print</span><span class="p">(</span><span class="s">'Comparing an A with a B'</span><span class="p">)</span>
</span><span class='line'> <span class="k">return</span> <span class="n">other</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span>
</span><span class='line'> <span class="k">print</span><span class="p">(</span><span class="s">'Could not compare A with the other class'</span><span class="p">)</span>
</span><span class='line'> <span class="k">return</span> <span class="bp">NotImplemented</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">B</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span><span class='line'> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
</span><span class='line'> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
</span><span class='line'>
</span><span class='line'> <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
</span><span class='line'> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">B</span><span class="p">):</span>
</span><span class='line'> <span class="k">print</span><span class="p">(</span><span class="s">'Comparing a B with another B'</span><span class="p">)</span>
</span><span class='line'> <span class="k">return</span> <span class="n">other</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span>
</span><span class='line'> <span class="k">print</span><span class="p">(</span><span class="s">'Could not compare B with the other class'</span><span class="p">)</span>
</span><span class='line'> <span class="k">return</span> <span class="bp">NotImplemented</span>
</span></code></pre></td></tr></table></div></figure>
<p><code>a</code> is instance of ClassA, and <code>b</code> is instance of ClassB, if we invoke <code>a == b</code>, we will get the result, True or False, but if we invoke <code>b == a</code>, we will also get the result! Because of we return <code>NotImplemented</code> in Class B’s <code>__eq__</code> method, runtime could invoke Class A’s <code>__eq__</code>, that method can compare A and B.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Safe Characters of Quote Method in Urllib]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2014/12/20/quote-in-urllib/"/>
<updated>2014-12-20T20:27:59+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2014/12/20/quote-in-urllib</id>
<content type="html"><![CDATA[<p>quote accept two arguments: a string and safe characters. If you pass empty to <code>quote</code> as the second parameter, it means every characters except preserved characters will be replaced by a % leading characters, e.g. space will be replaced by %20, etc.</p>
<p>In my project, I invoke quote like <code>quote(params, '')</code>, and I have imported <code>unicode_literals</code>, so I passed a unicode parameter to <code>quote</code> method.</p>
<p>What will happen?</p>
<p>Next time you invoke quote with the same <code>safe</code> parameter you used before, you may get an error like <code>UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)</code>, urllib will cache the safe parameter(urllib.py 1277 line), it expects a byte type parameter but you pass an unicode one, also, that library didn’t check or convert it before it uses.</p>
<p>Best practice, pass a byte parameter like <code>b''</code> to <code>quote</code> if you have same usage(unicode literals) like me.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Linux-study]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2014/11/22/linux-study/"/>
<updated>2014-11-22T14:14:25+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2014/11/22/linux-study</id>
<content type="html"><![CDATA[<p>directory permission x means this directory can be work directory, if you want to write or read a file behind this directory, you must have permission x of this directory.</p>
<p>directory permission w means you can delete or create files or directories behind this</p>
<p>usr = unix software resource</p>
<p>“-” means last work directory(cd /mnt;cd;cd -)</p>
<p>umask means default permission minus this mask, e.g default new directory 777, if mask is 022, then you will get 777-022——>755 directory; default new file 666, is mask is 002, then you will get 666 - 002——>664 file. mask only can be set in (1, 2, 4) every bit, one bit means the sum of one permission group(current/group/others). umask is based on user, default root has a 0022 mask, normal user has a 0002 mask.</p>
<p>lsattr/chattr is available on ext2/ext3 filesystem, add ‘+i’ attribute can lock one file, no edit or delete, even you are root, ‘+a’ attribute can let a file only accept append content, etc.</p>
<p>SUID, SGID, SBIT special permission:
there is a ’s’ on x position of user part, like ‘rws- - - - - -‘. SUID can only set to binary program, if user has x permission of this binary, it can temporarily get the owner permission of this binary, e.g binary ‘passwd’ and /etc/shadow file, shadow only can be updated by root, but every user can change their password via ‘passwd’, it means the user temporarily get owner(root) permission by SUID special permission.
SGID similar as SUID, there will be a ’s’ on x position of group part like ‘rwx- - s - - x’. if a user can execute binary, he will temporarily get owner permission, e.g binary ‘locate’ and file ‘mlocate.db’. SGID can be set on a directory, it means if a user have r and x permission of one directory, and ’s’ set on this directory, this user can create a file which owner group is this directory’s.
SBIT(Sticky BIT) only set to directory, if a directory has this permission, a user who can create file or directory on this directory, the new file or new directory can only delete by root or himself, e.g /tmp directory, root can delete your new file, and you can also delete it, but others can not.
SUID = 4, SGID = 2, SBIT = 1, chmod x755 xxx_file, x means sum of SUID, SGID, SBIT, if omit, this bit is zero, if you set a invalid SUID/SGID/SBIT, there will be upper case S/T, lower case is valid.</p>
<p>find / -size 1M -exec ls -l {} \; {} means the args from find, “\;” means the end of “exec”, commands in exec can not use alias.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Aix-security]]></title>
<link href="http://www.youth2009.org/www.youth2009.org/blog/2014/11/22/aix-security/"/>
<updated>2014-11-22T14:04:41+08:00</updated>
<id>http://www.youth2009.org/www.youth2009.org/blog/2014/11/22/aix-security</id>
<content type="html"><![CDATA[<p>some security configuration for AIX ssh and system services</p>
<p>create a user group named rmt_acc, only allow this group user access ssh, don’t allow root login and use public key authentication.</p>
<h1>sshd_config content</h1>
<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>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
<span class='line-number'>105</span>
<span class='line-number'>106</span>
<span class='line-number'>107</span>
<span class='line-number'>108</span>
<span class='line-number'>109</span>
<span class='line-number'>110</span>
<span class='line-number'>111</span>
<span class='line-number'>112</span>
<span class='line-number'>113</span>
<span class='line-number'>114</span>
<span class='line-number'>115</span>
<span class='line-number'>116</span>
<span class='line-number'>117</span>
<span class='line-number'>118</span>
<span class='line-number'>119</span>
<span class='line-number'>120</span>
<span class='line-number'>121</span>
<span class='line-number'>122</span>
<span class='line-number'>123</span>
<span class='line-number'>124</span>
<span class='line-number'>125</span>
<span class='line-number'>126</span>
<span class='line-number'>127</span>
<span class='line-number'>128</span>
<span class='line-number'>129</span>
<span class='line-number'>130</span>
<span class='line-number'>131</span>
<span class='line-number'>132</span>
<span class='line-number'>133</span>
<span class='line-number'>134</span>
<span class='line-number'>135</span>
<span class='line-number'>136</span>
<span class='line-number'>137</span>
<span class='line-number'>138</span>
<span class='line-number'>139</span>
<span class='line-number'>140</span>
<span class='line-number'>141</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># $OpenBSD: sshd_config,v 1.77 2008/02/08 23:24:07 djm Exp $
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># This is the sshd server system-wide configuration file. See
</span><span class='line'># sshd_config(5) for more information.
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># The strategy used for options in the default sshd_config shipped with
</span><span class='line'># OpenSSH is to specify options with their default value where
</span><span class='line'># possible, but leave them commented. Uncommented options change a
</span><span class='line'># default value.
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>#Port 22
</span><span class='line'>#AddressFamily any
</span><span class='line'>#ListenAddress 0.0.0.0
</span><span class='line'>#ListenAddress ::
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># Disable legacy (protocol version 1) support in the server for new
</span><span class='line'># installations. In future the default will change to require explicit
</span><span class='line'># activation of protocol 1
</span><span class='line'>Protocol 2
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># HostKey for protocol version 1
</span><span class='line'>#HostKey /etc/ssh/ssh_host_key
</span><span class='line'># HostKeys for protocol version 2
</span><span class='line'>#HostKey /etc/ssh/ssh_host_rsa_key
</span><span class='line'>#HostKey /etc/ssh/ssh_host_dsa_key
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># Lifetime and size of ephemeral version 1 server key
</span><span class='line'>#KeyRegenerationInterval 1h
</span><span class='line'>#ServerKeyBits 768
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># Logging
</span><span class='line'># obsoletes QuietMode and FascistLogging
</span><span class='line'>#SyslogFacility AUTH
</span><span class='line'>#LogLevel INFO
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># Authentication:
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>#LoginGraceTime 2m
</span><span class='line'>PermitRootLogin no
</span><span class='line'>StrictModes yes
</span><span class='line'>#MaxAuthTries 6
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>#RSAAuthentication yes
</span><span class='line'>PubkeyAuthentication yes
</span><span class='line'>#AuthorizedKeysFile .ssh/authorized_keys
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
</span><span class='line'>#RhostsRSAAuthentication no
</span><span class='line'># similar for protocol version 2
</span><span class='line'>#HostbasedAuthentication no
</span><span class='line'># Change to yes if you don't trust ~/.ssh/known_hosts for
</span><span class='line'># RhostsRSAAuthentication and HostbasedAuthentication
</span><span class='line'>#IgnoreUserKnownHosts no
</span><span class='line'># Don't read the user's ~/.rhosts and ~/.shosts files
</span><span class='line'>#IgnoreRhosts yes
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># To disable tunneled clear text passwords, change to no here!
</span><span class='line'>PasswordAuthentication no
</span><span class='line'>PermitEmptyPasswords no
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># Change to no to disable s/key passwords
</span><span class='line'>ChallengeResponseAuthentication no
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># Kerberos options
</span><span class='line'>#KerberosAuthentication no
</span><span class='line'>#KerberosOrLocalPasswd yes
</span><span class='line'>#KerberosTicketCleanup yes
</span><span class='line'>#KerberosGetAFSToken no
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># GSSAPI options
</span><span class='line'>#GSSAPIAuthentication no
</span><span class='line'>#GSSAPICleanupCredentials yes
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># Set this to 'yes' to enable PAM authentication, account processing,
</span><span class='line'># and session processing. If this is enabled, PAM authentication will
</span><span class='line'># be allowed through the ChallengeResponseAuthentication and
</span><span class='line'># PasswordAuthentication. Depending on your PAM configuration,
</span><span class='line'># PAM authentication via ChallengeResponseAuthentication may bypass
</span><span class='line'># the setting of "PermitRootLogin without-password".
</span><span class='line'># If you just want the PAM account and session checks to run without
</span><span class='line'># PAM authentication, then enable this but set PasswordAuthentication
</span><span class='line'># and ChallengeResponseAuthentication to 'no'.
</span><span class='line'>UsePAM yes
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>#AllowTcpForwarding yes
</span><span class='line'>#GatewayPorts no
</span><span class='line'>#X11Forwarding no
</span><span class='line'>#X11DisplayOffset 10
</span><span class='line'>#X11UseLocalhost yes
</span><span class='line'>#PrintMotd yes
</span><span class='line'>#PrintLastLog yes
</span><span class='line'>#TCPKeepAlive yes
</span><span class='line'>#UseLogin no
</span><span class='line'>UsePrivilegeSeparation yes
</span><span class='line'>#PermitUserEnvironment no
</span><span class='line'>#Compression delayed
</span><span class='line'>ClientAliveInterval 600
</span><span class='line'>ClientAliveCountMax 0
</span><span class='line'>#UseDNS yes
</span><span class='line'>#PidFile /var/run/sshd.pid
</span><span class='line'>#MaxStartups 10
</span><span class='line'>PermitTunnel no
</span><span class='line'>#ChrootDirectory none
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># no default banner path
</span><span class='line'>#Banner none
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># override default of no subsystems
</span><span class='line'>Subsystem sftp /usr/sbin/sftp-server
</span><span class='line'>
</span><span class='line'>
</span><span class='line'># Example of overriding settings on a per-user basis
</span><span class='line'>#Match User anoncvs
</span><span class='line'># X11Forwarding no
</span><span class='line'># AllowTcpForwarding no
</span><span class='line'># ForceCommand cvs server
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>AllowGroups rmt_acc</span></code></pre></td></tr></table></div></figure>
<h1>install sudo for AIX</h1>
<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'>rpm -i sudo-for-aix.rpm</span></code></pre></td></tr></table></div></figure>
<h1>stop telnet/login/ftp/shell/exec service:</h1>
<p>don’t start telnet if reboot:</p>
<p>comment the line starts with ‘telnet’/‘login’/‘ftp’/‘shell’/‘exec’ in /etc/inetd.conf</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'>stopsrc -t telnet</span></code></pre></td></tr></table></div></figure>
]]></content>
</entry>