09年05月08日   2 条评论

首先确认apache支持mod_ssl, 也正确安装。

Fedora 8中apache关于ssl的配置文件在/etc/httpd/conf.d/ssl.conf文件中,使用SSLEngine on选项来开启HTTPS的支持,apache默认会使用一个自带的localhost 的证书来进行HTTPS连接。

接下来我们使用生成自己的证书进行HTTPS连接:

mkdir /etc/httpd/conf.d/ssl.crt/
cd /etc/httpd/conf.d/ssl.crt
(1)
生成服务器的私钥:
rsa -in server.key -out server.key

req -new -key server.key -out server.csr
生成Certificate Signing Request(CSR),生成的csr文件交给CA签名后形成服务端自己的证书.屏幕上将有提示,依照其指示一步一步输入要求的个人信息即可.

(2)
对客户端也使用同样的方式:
genrsa -out client.key 1024
req -new -key client.key -out client.csr

(3)
生成CA中心的私钥:
genrsa -out ca.key 1024
生成X509格式的CA证书:
req -new -x509 -keyout ca.key -out ca.crt

(4)
用生成的CA的证书为刚才生成的server.csr,client.csr文件签名:
mkdir ../../CA
mkdir ../../CA/newcerts
touch ../../CA/serial
cat “01″ > ../../CA/serial
touch ../../CA/index.txt
ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key
ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key

(5)
生成浏览器使用的PFX格式的证书:
pkcs12 -export -in client.crt -inkey client.key -out client.pfx
把ca.crt安装到信任的机构,client.pfx安装或安装到个人证书位置

(6)
编辑ssl.conf配置文件,修改证书相关的地方:
SSLCertificateFile /etc/httpd/conf.d/ssl.crt/server.crt
SSLCertificateKeyFile /etc/httpd/conf.d/ssl.crt/server.key
SSLCACertificateFile /etc/httpd/conf.d/ssl.crt/ca.crt

标签 :
分类 : 互联网
Top
09年05月04日   27 条评论

前几天在中文件邮件列表里看到讨论使用Python实现迅雷,后来又在Ubuntu论坛看到一个贴子,实现了获取迅雷服务器上的侯选资源(不是开源的)。突然就对这个迅雷协议很感兴趣,在别人分析的基础上用写了个小工具,与Ubuntu论坛上那个作用是一样的,获取迅雷服务器上的侯选资源。

迅雷有多个资源服务器,有的资源服务器返回完全一样,有的返回某些一样,这样可以指定多个服务器,获取更多的资源,同时也可以防止某个服务器不能正常响应。

用webpy写了个演示面面:

http://cocobear.info/demo//?url=http://3.duote.com/xunleidt.exe

不知道开源了会不会产生麻烦?

———————————解释下标题——————————
前几天拿U盘做产量的时候没把代码备份出来,所以原本已经写好了今天又写了一遍,幸好代码很短:-)

标签 :
分类 : Python
Top
09年05月04日   3 条评论

先说下练字吧,只有一天没有写,去同学那里玩了,没回来,坚持的还算不错,可惜没觉得有什么进步,有时候觉得就根本没效果,所以好几天写的不认真,似乎应该端正下态度了。试着去临贴,不描红了,老爸说钢笔字重要的是字的结构、总局,没必要像写毛笔字一样描红好长时间。29/30

7点起床,几乎每个周末都没能按时起来,是不是因该把周末排除啊?很郁闷:-( 8/30

12点前睡觉,基本都做到了,没什么说的,想睡太迟也不行,不年轻了,呵呵。 28/30

睡前阅读,坚持的不好,只有21天,而且好多时候没看几分钟就睡着了,这个月看完了《明朝的那些事儿》。手机上看书真不爽,不过像这类书去买又有点浪费了:-) 21/30

这个月继续巩固吧。

标签 :
分类 : Life
Top
09年04月25日   41 条评论

最近有同学反映不能在GAE上使用,我看了下别人给出的错误,问题不出在上,无论是TCP方式还是HTTP方式,使用本机测试都可以正常工作。
应该是移动的飞信服务器屏蔽了的出口IP地址(某同学反应的urlopen使用的是同一IP)。

原因大概是广大的爱好者众多,玩的又比较多,所以移动不爽了,就封掉你。

问题出来了,原因也大概知道了,那怎么解决方案呢,下面就给出几个吧:

  1. 强烈要求增加代理支持。
  2. 打电话给10086,然后说你的飞信上不出了,然后给客服MM说你的IP是:[GAE_IP(哪位知道这个IP来补充一下)]。
  3. 脱离,使用自己的服务器。
  4. 继续使用,使用另一服务器做为跳板。
  5. 解释一下,不能直接访问飞信服务器了,可以在另一个地方,比如cocobear.info/.py?phone=13838381438&pwd=383838&msg=^_^
    做这样的一个的接口,然后使用去访问这个服务器。

Update(09.4.27):
据gohsy同学反映,上不能使用是因为服务器返回了405错误,而别的fetion实现会忽略405错误,继续进行,而遇到这个错误会产生异常。记得以前调的时候也遇到过405错误,应该是发送的数据格式不对而造成的,所以我猜想这里是因为网络环境影响造成的数据不完整,从而使得飞信服务器返回405错误。因为在还是可以偶尔发送成功的,所以出错的原因应该不是程序本身。

为了在上能更好的使用,我修改了一下,增加了遇到405错误时重试功能,默认重试5次,这样会使得发送的成功率提高很多,但是由于405的出现,重试多次会影响到发送的速度,这一点是无法避免的。更新请到google code查看:http://code.google.com/p/pytool/source/detail?r=30

其实根本的原因我想还是上用的人过多造成的:-)

为了在上调,在gohsy同学的帮助下,搭建了环境,感觉还不错,做应用挺方便的,不错的东东。

标签 :
分类 : Python, 编程相关
Top
09年04月08日   3 条评论

花了差不多两周的时间读完了Lua Programming in Lua (first edition) ,没找到pdf格式的,一直在官网在线看的,不是很舒服。看的似乎有点慢,里面的英文很简单,讲的内容难点也不多,也没有太多的代码去动手实践,似乎是受别人打击了:-)(看到人家博客里写道:“花两天的时间过了一遍PIL”)。

作为一个脚本语言在很多地方与有相似之处,不过小巧了很多,数据类型、表达式、语句等都很精简,但是这并不影响成为一个流行的脚本语言,灵活的table成就了的强大,table可以演化出list,dict,更强大的是table可以实现OO,并没有在语言级提供OO的实现,不过的作者在PIL中展示了使用table完全可以实现近乎完美的OO编程,我觉得这是对整天鼓吹OO思想的人一个极大讽刺,OO其实没什么,C语言中使用结构体,函数指针也可以有模有样的进行OO编程。

中也有很多函数式编程语言的影子,所以很多人把和Scheme归为了近亲,不过俺不了解Scheme,对函数式编程也是一知半解,只能凑个热闹。

之所以在游戏中使用比较广泛,是因为它可以很好的和C/C++结合在一起,可以很方便的互操作,通过使用Stack的方式。还有一个很重要的原因,提供的是搭积木的原料,而不是搭好的建筑,所以你可以很灵活的用自己的方式去写程序。比如你可以用table实现一个完整的OO系统,然后在OO上面写程序(这里有一点很重要,基于table实现OO是很轻量的,而不是语言级的OO);你也可以用metatable来实现中很强大的filter,map,reduce。

中的table有点类似道家学说里面的”道”,”道生一,一生二,二生三,三生万物”,而table就是中的“道”。

还得提一点是完全用ANSI C编写的。

cocobear@0-0 /home/cocobear/Codes/-5.1.4/src $ wc *.c *.h -l | tail -1
17002 total

标签 :
分类 : Lua
Top
09年03月31日   8 条评论

月中开始写字,每天都能坚持写半个小时以上,不过有那么一两天写的不太认真,进步倒是看不起来,不过已经可以很自觉的去练字了,算是个进步,希望可以到7月的时候能有些进步,09年底能写得像个样子吧。15/15

晚上12点前睡觉只有一天没做到,记得是看《色戒》,可惜这电影也不怎么样。14/15

早上7点起床两个周末都没那么早起来,还有一天是因为前一天晚上看《色戒》了,没按时起来。10/15

下个月继续努力吧。

标签 :
分类 : Life
Top
09年03月31日   3 条评论
:
  1. >     function foo (n)
  2. >>       if n> 0 then return foo(n - 1) end
  3. >>     end
  4. > foo(100)
  5. > foo(1000)
  6. > foo(10000)
  7. > foo(100000)
  8. > foo(1000000)

如果函数最后一句是return g(...)这样的形式,将会把这句解释为goto g(x),因为这里除了对g函数调用,再没有别的事做,也不需要保存堆栈里调用函数的信息。因此上面即使调用很多次也没有出现堆栈溢出的问题,把上面的代码转换为:

:
  1. >>> def foo(n):
  2. ...     if n>0: return foo(n-1)
  3. ...
  4. >>> foo(100)
  5. >>> foo(1000)
  6. ...
  7.   File "<stdin>", line 2, in foo
  8.   File "</stdin><stdin>", line 2, in foo
  9.   File "</stdin><stdin>", line 2, in foo
  10. RuntimeError: maximum recursion depth exceeded

很快出就现了堆栈溢出的问题,在这里表现为达到了递归调用的最大限制。自身没有实现尾部调用优化,不过也可以通过实现一个decorator办法来实现:

:
  1. #!/usr/bin/env python2.4
  2. # This program shows off a decorator(
  3. # which implements tail call optimization. It
  4. # does this by throwing an exception if it is
  5. # it's own grandparent, and catching such
  6. # exceptions to recall the stack.
  7.  
  8. import sys
  9.  
  10. class TailRecurseException:
  11.   def __init__(self, args, kwargs):
  12.     self.args = args
  13.     self.kwargs = kwargs
  14.  
  15. def tail_call_optimized(g):
  16.   """
  17.  This function decorates a function with tail call
  18.  optimization. It does this by throwing an exception
  19.  if it is it's own grandparent, and catching such
  20.  exceptions to fake the tail call optimization.
  21.  
  22.  This function fails if the decorated
  23.  function recurses in a non-tail context.
  24.  """
  25.   def func(*args, **kwargs):
  26.     f = sys._getframe()
  27.     if f.f_back and f.f_back.f_back
  28.         and f.f_back.f_back.f_code == f.f_code:
  29.       raise TailRecurseException(args, kwargs)
  30.     else:
  31.       while 1:
  32.         try:
  33.           return g(*args, **kwargs)
  34.         except TailRecurseException, e:
  35.           args = e.args
  36.           kwargs = e.kwargs
  37.   func.__doc__ = g.__doc__
  38.   return func
  39.  
  40. @tail_call_optimized
  41. def factorial(n, acc=1):
  42.   "calculate a factorial"
  43.   if n == 0:
  44.     return acc
  45.   return factorial(n-1, n*acc)
  46.  
  47. print factorial(10000)
  48. # prints a big, big number,
  49. # but doesn't hit the recursion limit.
  50.  
  51. @tail_call_optimized
  52. def fib(i, current = 0, next = 1):
  53.   if i == 0:
  54.     return current
  55.   else:
  56.     return fib(i - 1, next, current + next)
  57.  
  58. print fib(10000)
  59. # also prints a big number,
  60. # but doesn't hit the recursion limit.

代码来自http://code.activestate.com/recipes/474088/

在这段代码里tail_call_optimized是一个decorator,在执行factorial函数前,这个decorator先执行,tail_call_optimized中通过sys._getframe()这个方法会返回一个frame对象,包含了堆栈顶部的信息,当发现当前调用是一个递归调用:

:
  1. if f.f_back and f.f_back.f_back
  2.         and f.f_back.f_back.f_code == f.f_code:

则抛出一个异常,下面的代码则截获异常,继续执行,这样就避免了堆栈的使用,很巧妙的一种方式。

-dev的邮件列表里,有人曾经做过一个的尾调用优化的补丁,不过Guido拒绝了这个补丁:

I'm not interested in adding this to the official release.

One reason is that if an exception happens in such a tail-recursive
call, the stack trace will be confusing.

Another reason is that I don't think it's a good idea to try to
encourage a Scheme-ish "solve everything with recursion" programming
style in .

But feel free to maintain this as an independent modification, a la
Stackless -- I'm sure there are people who would like to try this
out.

--Guido van Rossum (home page: http://www..org/~guido/)

标签 :
分类 : Python
Top
09年03月31日   3 条评论

:

:
  1. >   function newCounter ()
  2. >>     local i = 0
  3. >>     return function ()   -- anonymous function
  4. >>              i = i + 1
  5. >>              return i
  6. >>            end
  7. >>   end
  8. >  
  9. >   c1 = newCounter()
  10. > print(c1())
  11. 1
  12. > print(c1())
  13. 2

类似,也可以嵌套定义函数,不过嵌套函数可以访问上层闭包函数的局部变量,而在这个内嵌函数中这些变量不是全局变量,也不是局部变量,而是一种upvalue,与C语言中的static修饰的变量类似,所以在这里可以利用这个特性完成这个计数器。

:

:
  1. >>> def counter(last=[1]):
  2.   ...     next = last[0] + 1
  3.   ...     last[0] = next
  4.   ...     return next
  5.   ...
  6.  >>> counter()
  7.   2
  8.  >>> counter()
  9.   3

今天看的时候觉得也应该有比较简单的办法写个计数器,找到一篇文章介绍这个小技巧,其中有一句话:

However, if named parameters are given mutable default values, the parameters can act as persistent memories of previous invocations. Lists, specifically, are handy mutable objects that can conveniently even hold multiple values.

作为一个嵌入式(嵌入到其它语言中)的脚本语言,在很多地方与类似,这几天在看Programming in

标签 :
分类 : Lua, Python
Top
09年03月24日   8 条评论

加入了HTTP代理的支持,HTTP发送方式中。TCP发送方式也可能会加上吧,使用SocksiPy这个库吧,有时间再说。

的时候发现urllib2的一个问题:
先看下面这段代码:

:
  1. import urllib2
  2. headers = [("Content-Type","application/oct-stream"),]
  3. opener = urllib2.build_opener()
  4. opener.addheaders = headers
  5. urllib2.install_opener(opener)
  6. print "after install_opener"
  7.  
  8. ret = opener.open('http://www.dict.cn',data="word=ss")
  9. print ret.read()

抓包发现发送的内容为:

POST / HTTP/1.1
Accept-Encoding: identity
Content-Length: 7
Host: www.dict.cn
Content-Type: application/x-www-form-urlencoded
Connection: close

word=ss

这里我在代码里已经指定了HTTP的header: Content-Type,但是发出去的时候却被改变了。

通过分析urllib2的代码,找到:

:
  1. if request.has_data():  # POST
  2.     data = request.get_data()
  3.     if not request.has_header('Content-type'):
  4.         request.add_unredirected_header(
  5.             'Content-type',
  6.             'application/x-www-form-urlencoded')
  7.     if not request.has_header('Content-length'):
  8.          request.add_unredirected_header(
  9.            'Content-length', '%d' % len(data))
  10.  
  11. scheme, sel = splittype(request.get_selector())
  12. sel_host, sel_path = splithost(sel)
  13. if not request.has_header('Host'):
  14.     request.add_unredirected_header('Host', sel_host
  15.     or host)
  16.     for name, value in self.parent.addheaders:
  17.     #这里的parent是opener对象
  18.     name = name.capitalize()
  19.     if not request.has_header(name):
  20.         request.add_unredirected_header(name, value)

urllib2发现如果是POST数据的话自己添加了Content-Type,接着才去追加opener对象中的headers,这时已经有Content-Type了,所以opener对象增加的Content-Type就无效了。

解决办法是创建request对象,在request对象中设置Content-Type:

request = urllib2.Request(url,headers=headers,data=body)

不知道是上面的示例代码写法不规范呢?还是算的一个小问题呢?

最近发现周董的不少歌挺好听,于是找个脚本来下载周董的歌(从百度mp3中), getsong就进入了眼的视野,不过不支持下载某个歌手的全部歌曲,俺自己加上去,正在下载周董的歌:

[cocobear@cocobear ]$ ./.py -a 周杰伦
正在下载第1首(共104首) 歌手:周杰伦 曲名:她的睫毛
已经成功下载《周杰伦 - 她的睫毛》
.......

不过这会儿断了,好像又有bug了,今天就不折腾了,明天再整整吧,看书,睡觉了。

分类 : Python
Top
09年03月20日   4 条评论

一个是以前写的导出抓虾收藏的工具,增加了保存抓虾上文章的功能,因为只导出链接有些文章地址可能已经失效。

另一个就是,前面文章介绍过了,整理了一下,测试了一下,然后放在了google code上面,直接使用星际译王的词典,查一个单词大概0.15秒的时间:

cocobear@0-0 /home/cocobear/Work/pytool/ $ make
gcc lookup.c -g -I/usr/include/python2.5 -lz -shared -fPIC -o lookup.so
cocobear@0-0 /home/cocobear/Work/pytool/ $ time ./.py test
*[test]
n. 测试, 试验, 化验, 检验, 考验, 甲壳
vt. 测试, 试验, 化验
vi. 接受测验, 进行测试
【医】 试验, 测验
【经】 检验, 试验, 测试
相关词组:
put sth to the test
stand the test
give a test
take a test
test sb's ability

real 0m0.164s
user 0m0.143s
sys 0m0.010s

如果是未使用gzip压缩过的dict文件,则0.05秒左右。

标签 :
分类 : Python
Top