让htm支持SSI

2011年8月26日 没有评论

iis中:
  也就是需要两步,
  1.在虚拟主机块中加入,或者全局加
  AddOutputFilter INCLUDES .htm
  AddHandler server-parsed .htm
  2.在Directory中的Options加入Includes参数,我觉得使用IncludesNOEXEC可能会更好。

<Directory "F:/hx/">
    Options Indexes FollowSymLinks IncludesNOEXEC
</Directory>

  一些错误的解决:
  包含的文件出现如下提示:[an error occurred while processing this directive]
  原因之一:先检查一下包含的文件路径对不对,文件是否存在。
  如果正确,则问题出在包含的语句上。

<!--#include file="文件名称"-->
<!--#include virtual="文件名称"-->

  file 文件名是一个相对路径,该路径相对于使用 #include 指令的文档所在的目录。被包含文件可以在同一级目录或其子目录中,但不能在上一级目录中。如表示当前目录下的的top.htm文档,则为file=”top.htm”。
  virtual 文件名是 Web 站点上的虚拟目录的完整路径。如表示相对于服务器文档根目录下hx目录下的top.htm文件;则为virtual=”/hx/top.htm”
  如果是上一级目录的子目录,就是使用路径../hx/top.htm时,需要使用Virtual,如果使用file,则会产生上面的提示。但在IIS下这样好像不会产生错误。
  Apache中:
  要使服务器允许SSI ,必须在httpd.conf或.htaccess文件中有如下配置:
  Options +Includes
  这样就告诉服务器允许解析文件中的SSI指令。注意,在多数配置中,多个Options指令会互相覆盖,所以可能需要对使用SSI的目录专门使用一个Options指令,以确保其有效。
  并非所有文件中的SSI指令都会被解析,必须告诉Apache应该解析哪些文件。有两种方法使Apache解析带有特定后缀名的文件,比如:.shtml ,配置如下:

  AddType text/html .shtml
  AddOutputFilter INCLUDES .shtml

  该方法的缺点之一是,为了使文件具有.shtml后缀从而执行其中的指令,需要加入SSI指令的现有文件的名字,以及所有指向此页面的连接。
  另一种方法是,使用XBitHack指令:
  XBitHack on
  XBitHack告诉Apache解析所有设置了执行位的文件中的SSI指令。这样,无需修改文件名,只要用chmod使文件变成可执行的,就可以对现有页面增加SSI指令。
  chmod +x pagename.html
  这里简要说明一点:偶然会有人向你推荐,无须用带.shtml的文件名,只要使Apache解析所有.html文件的SSI就可以了。那些人可能没听说过XBitHack 。要知道,这样做会使Apache在发送文件到客户端之前通读此文件,即使其中并没有任何SSI指令,从而对速度有很不利的影响,所以这并不是好办法。
  当然,在Windows上,没有对应的执行位可以设置,所以对你的配置方法就有一些限制。
  在默认配置的情况下,Apache不会为SSI页面发送最后修改日期或者内容长度的HTTP头,因为这些值对动态页面来说难以确定。这样会阻止页面被缓冲,导致客户端性能有明显的下降。有两种解决方法:
  设置 XBitHack Full ,告诉Apache在判断最后修改日期时,只查看被请求文件本身的日期,而忽略其中包含的其它文件的修改日期。
  使用mod_expires提供的指令为文件设置一个明确的过期时间,并告诉浏览器和代理这个文件可以被缓冲。
From – http://ued.stuin.com/server/htm-ssi/

分类: 服务器管理 标签: , , , ,

将程序所需的第三方库静态编译进可执行文件中

2011年7月11日 没有评论

这两天由于项目的需要,需要将一个第三方库libxml2编译进可执行文件中,最终能够在没有安装libxml2的linux机器上运行所编写的程序。

我编写的程序是一个日志记录模块,有三个很简单的文件,log.c,log.h,main.c。log.c负责实现日志记录的相应接口,main.c则调用log.c编译生成的库文件使用这个接口来记录日志。

首先查阅网上资料以后,知道了gcc的-static选项可以完成这一功能,同时需要注意的是使用-static选项时需要将-lxml2选项放在gcc命令的最后。

所以正常情况下,如下的命令即可完成我的需求。(lxml2依赖于pthread,z,m库)

gcc -c log.c -I/usr/include/libxml2 -L/usr/lib -lxml2
 
ar -r liblog.a log.o
 
gcc -static main.c -o main -I/usr/include/libxml2 -L. -llog -L/usr/lib -lxml2 -lpthread -lz -lm

但是非常不幸的是,这样子编译出来的可执行文件运行后会出现段错误。但是如果不加上static选项进行编译,那么编译出来的二进制文件可以运行。

然后郁闷了半个小时,在网上搜了很多的资料,皇天不负有心人,终于被我找到原因了。

由于我是使用的虚拟机下面的Ubuntu8.04进行相关的开发工作的,所以在安装libxml2的开发包时就直接用了apt-get install。但是,非常悲剧的是,该版本下的libxml2存在一个与线程相关的bug。

该bug的描述如下,from Jerome

i just found out an issue with libxml2 and static linking. It is occuring on ubuntu 8.04.

  1. take a libxml2 example from the official website at http://xmlsoft.org/examples/tree2.c
  2. you compile it and link it in static gcc -g -static -Wl,–start-group `xml2-config –cflags –libs –static` tree2.c -Wl,–end-group -o tree2
  3. and then ./tree2 and you get core dump

oopsa not happy jerome not happy

LATER: before i was using ubuntu feisty 7.04 and all was fine. so i looked at launchpad and took 2.6.27.dfsg-1ubuntu3version. recompiled it myself under hardy and linked it statically. no more crash. oopsa. and i filled a bug for it

解决方案如上所述,但是查看了bug列表后,我又找到了一个更简单的解决方案

The answer is simple, don’t link threaded programs statically, there are

many reasons why it is a wrong thing to do.

If you really must do so, the safest solution is
-Wl,–whole-archive -lpthread -Wl,–no-while-archive

所以最后,我的最后一个编译命令变为了

 gcc -static main.c -o main -I/usr/include/libxml2 -L. -llog -L/usr/lib -lxml2 -Wl,--whole-archive-lpthread -Wl,--no-whole-archive -lz -lm

 

分类: C 标签: , , ,

I’m back

2011年7月11日 1 条评论

Hi, all dears, I’m back to myhome.
In the last two years, I didn’t often update my blogs. Sorry for your expect!
I’ve learned a lot in software development and research in this period.
Now I’ve completed my first year of postgraduate life. I think it’s time to summarize what I have learned before. And good news is in my second year I have plenty of time!
Finally, Best wishes with you all!

分类: 未分类 标签:

Python的哲学

2010年5月4日 3 条评论

今天看了豆瓣洪强宁技术分享,又看到了pep上的这段话,觉得太经典了,于是就转了过来,细细品味,很有味道

The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one– and preferably only one –obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea — let’s do more of those!

分类: Python, 语言 标签: ,

[转]谈一下怎样判断网页是静态的还是伪静态的?

2010年2月8日 没有评论

怎样判断网页是静态还是伪静态呢?

SEO文章看多了,经常能听到静态、伪静态这类的词语,那什么样的网页是静态的,什么样的网页是伪静态的呢?

IE5浏览器以上:
打开你想判断的网站后,再在网址框中输入javascript:alert(document.lastModified)
IE5以上… ,此方法可以判断一个网页的最后更新时间,如果这个时间与现在的时间相同,说明是伪静态的,反之为静态的。

火狐浏览器下:

先用火狐打开一个网页如:http://bbs.ittang.com/forum-13-1.html 等网页完全打开后进入FireFox的控制台。”工具”-“错误控制台”快捷键:shift+ctrl+J 然后在控制台里面输入:alert(document.lastModified); 查看最后修改时间并记录。

接下来关闭控制台,重新刷新网页,再用相同的方法在控制台里输入查询代码,再查看文件的最后修改时间,连续几次如果发现时间不同则可以判断它是伪静态的了

相关知识:关于伪静态和真静态网页用处和利弊对比

1.关于伪静态的用处
有些用户觉得,伪静态和真静态实际被收录量会相差很大,其实不然,从你个人角度,你去判断一下一个帖子到底是真静态还是伪静态?
估计很难看得出,因为所谓静态的意思,就是地址中不带问号,不带问号的就是静态,管他是真的还是伪的?搜索引擎看得出吗?
所以说,其实不论是真的还是伪的,其实对于搜索引擎来说都是一样的,搜索引擎没有说,你这个是伪的,我不收录你.
揪根掘底的来说,为什么搜索引擎会不收录带问号的网址?因为搜索引擎怕由于问号而进入死循环(以前动网就有这样一个漏洞,蜘蛛进去出不来了),所以很多时候带问号的地址是不会进去的,伪静态对于搜索引擎来说,其实就是静态,因为地址中没有带问号,所以没有真静态比伪静态收录得多的说法.

2.为什么选择伪静态
有很多用户说:
真静态不好吗?
为什么不用真静态?
访问起来不是更快吗?
负载不是更好吗?
等等等等…
在这里,其实只用一个问题来回答:为什么选择MYSQL.
很多用户大概不明白为什么那么多大型论坛都选择了MYSQL数据库作为储存机制,大概大部分都是想:”因为DZ用了MYSQL,所以就是MYSQL”.
其实不然,试想DZ为什么会在那么多论坛程序并存的日子生存下来并笑傲江湖,很大原因是因为DZ用了MYSQL.试想如果大C当年改的程序是一个文本论坛,那还会有DZ的今天吗?
或者从另一个角度问,为什么那么多大型网站都选择了MYSQL而不是文本作为储存机制?
所谓文本论坛,实际就跟真静态的说法差不多了,将数据储存在空间上面,大量读写硬盘,等等…
为什么这种写法会被淘汰呢?
我相信答案不会是老师所说的:

“discuz.net 目前有 2129867 篇帖子,存储成html的话大约是 20799 M,也就是 20G左右。这当中还不计算由于磁盘存储机制造成的空间浪费(100个1k 的文件占用的空间可能会是200K)。”

这种说法从我个人观点来看,这个理由不能给予用户不使用真静态充分的理由.
然而,另一个理由却是值得我们注意思考的,也是为什么绝大多数站都不选择生成静态:

“删除、更新这些html内容会导致大量的磁盘io操作以及大量的磁盘碎片.”

正如上面这个说法,在实际当中确实会导致大量的磁盘I/O操作(input,output),大量进行I/O操作带来的后果可想而知,会产生大量的磁盘碎片甚至会导致硬盘出现坏道.

所以对于生成静态而言,还不如去用文本论坛,可以更好的解决你们的需求.
(副W就是做文本论坛出生的,当时的名字为ofstar http://www.ofstar.net ,后因发展困难转为MYSQL,而PW生成静态页面也就是PW以前文本方式稍加改进用于吸引用户眼球的噘头)
当然,如果大家记忆力好的话,应该可以记得PW4的时候PW论坛不能访问很长一段时间,后来恢复到一段时间前的数据,官方的说法是被人攻击而导致硬盘损坏,其实这种说法是比较不可信的,相对于是被攻击导致硬盘损坏还是大量I/O操作而产生的后果,我个人更倾向于后者.

当然,如果大家比较关注5d6d的话,应该知道前几天有一天时间5d6d无法访问,根据非官方消息是因为硬盘坏了,而损坏的原因我想当然是因为大量用户大量进行I/O操作了,试想,我们一个论坛,进行磁盘I/O操作的仅为管理员进行更新缓存时进行的,而5d6d每一个会员就是一个管理员,试想下对磁盘是多大的考验?所以我并不奇怪5d6d的硬盘坏了.

当然,也许在读这篇文章的很多朋友都有使用过BT,也听说过BT对硬盘很伤,不能开多,而所谓伤害,和这里指的都是同一样东西,大量I/O导致磁盘出现碎片甚至出现磁盘坏道.

这里都是说些很实际的例子来说明问题了.

3.关于伪静态的坏处
当然犹如一篇文章的作者所说的

“如果流量稍大一些使用伪静态就出现CPU使用超负荷,我的同时在线300多人就挂了,而不使用伪静态的时候同时在线超500人都不挂,我的ISS数是1000″

确实是这样的,由于伪静态是用正则判断而不是真实地址,分辨到底显示哪个页面的责任也由直接指定转由CPU来判断了,所以CPU占有量的上升,确实是伪静态最大的弊病.

4.我们该如何做?

我们来总结一下.
1.使用真静态和假静态对SEO来说没有什么区别
2.使用真静态可能将导致硬盘损坏并将影响论坛性能
3.使用伪静态将占用一定量的CPU占有率,大量使用将导致CPU超负荷
4.最重要的一点,我们要静态是为了SEO

所以.
1.使用真静态的方法可以直接排除了,因为无论怎么生成,对硬盘来说都是很伤的.
2.既然真伪静态的效果一样,我们就可以选择伪静态了.
3.但是伪静态大量使用会照成CPU超负荷.
4.所以我们只要不大量使用就可以了.
5.既然静态只是给SEO看的,我们只需要伪静态给SEO就行了,不需要给用户使用.
6.所以我们只要在专门提供给SEO爬的Archiver中使用伪静态就可以了.
7.谢谢大家耐心看我写的文章.
8.有何不解的地方或是有不同的看法欢迎提出.

PDFmyURL.com – 把任意网站转换成PDF

2010年1月15日 没有评论

在cnbeta上发现一个很好玩的网站,于是就转过来吧。
如果您要将一个网站迅速保存下来,可以用多种方法,首先是普通的HTML,这样会带来许多网页文件,保存成mht也可以解决问题,不过不够直观,而PDF文件的通用性和对电子阅读器的友好性,让这家名叫PDFmyURL.com的网站亮了。它可以迅速将HTML转换成PDF文件,这一切非常简单,访问他们主页,输入要做PDF的页面地址就好了,制作结束网站会提示你获取PDF,不过需要注意的是,它并没有中文字库,因此会显示一个一个框框。
访问www.PDFmyURL.com

分类: 趣味网站 标签: , , ,

用find,xargs,tar命令可选备份

2010年1月12日 2 条评论

今天写了一个脚本要把server上所有的文件重新处理一下,由于没仔细检查就在server上跑了,导致server上所有的文件改错了,而且这个过程不可逆,幸好在另外一个server上面有备份,于是就想着把备份移过来,刚开始移的时候直接tar命令,没想到要恢复的那个目录下面还有很多pdf,mp3,ppt…文件,估计大概有20多个G,而我的脚本只改动了文本文件,于是,用find加tar试了一下,可是没想到对文件名中存在空格的文件会出错,搜索了一下,找到了一个好办法。

基本的用法比如:

find . -name '*.htm' | xargs tar czvf backup.tar.gz

一般情况,上面这个命令运行的很好,但是如果找到的文件名代空格,上面的命令运行就可能会出问题了。

find有一个参数-print0,于默认的-print相比,输出的序列不是以空格分隔,而是以null字符分隔。而xargs也有一个参数-0,可以接受以null而非空格间隔的输入流。所以说xargs简直就是为find而生的。上面的问题就很好解决了:

find . -name '*.htm' -print0 | xargs -0 tar czvf backup.tar.gz

python脚本抓取学位照信息

2009年12月27日 1 条评论

前两天学校里拍了学位照,在档案馆网站上可以看到自己照片了,由于只要学号和姓名信息,所以就写了个脚本把照片给全部抓下来了,主要用到了urllib2,urllib,汗,以前一直用很底层的httplib做东西,还有这次写了一下代码对浏览器如何操作整个请求过程有了比较深入的了解,脚本执行时需要同目录下有个数据文件,其中包含学号和姓名信息,用逗号隔开,代码如下:

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
import os
import urllib
import urllib2
import re
 
def save_image(dir,image_name,image):
    if not os.path.isdir(dir):
        os.makedirs(dir)
    try:
        image_file = open(dir + image_name,'wb')
    except IOError as (error, strerror):
        print "I/O error({0}):{1}".format(error,strerror)
    else:
        image_file.write(image)
        image_file.close()
 
def get_image(name,student_no,login_url,picture_url,pattern):
    #Parameter Information
    login_type = 'yes'
    #Configure opener to handle cookies
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
    urllib2.install_opener(opener)
    #Build Prameters
    params = urllib.urlencode({'xm':name,'xh':student_no,'login':login_type})
    #Open login html
    f = opener.open(login_url,params)
    login_html = f.read()
    f.close()
    #Search the image link
    m = re.search(pattern,login_html)
    if m is None:#The student hasn't taken picture
        return None
    else:
        #Get the image    
        match_part = m.group(1)
        f = opener.open(picture_url + match_part)
        image = f.read()
        return image
 
def grab_all():
    dir = r'D:\\temp\\'
    login_url = 'http://dawww.nju.edu.cn/xwz/login.asp'
    picture_url = 'http://dawww.nju.edu.cn/xwz/picture.asp'
    picture_pattern = 'src="picture.asp(\?i=\d+)"'
    try:
        software_student_file = open('software.txt','r')
    except IOError as (error, strerror):
        print "I/O error({0}):{1}".format(error,strerror)
    else:
        lines = software_student_file.readlines()
        for line in lines:
            line = line.rstrip('\n')
            name = line.split(',')[0]
            student_no = line.split(',')[1]
            image = get_image(name,student_no,login_url,picture_url,picture_pattern)
            if image is not None:
                save_image(dir,student_no + '_' + name + '.jpg',image)
                print student_no + '_' + name + '.jpg' + ' is saved'
        software_student_file.close()
 
if __name__ == "__main__":
    grab_all()
分类: 数据抓取 标签: , ,

如何控制frames的部分打印

2009年12月22日 没有评论

前两天要做一个页面的print button,但是网页是由两个frame构成的,而且其中的一个frame中包含了一个width很大的table,所以每次使用ie打印的时候都会将table的右部截去,但是FF打印的时候会自动缩放,T_T,由此可见ie的劣根性。。。

网上搜索了一下,大概有几种方法可以解决局部打印问题。

  1. 在html里面嵌入<!–start_pirnt–><!–end_print–>标签,然后使用js将要打印的部分取出,然后新打开一个窗口,将要打印的部分送入新窗口,onload事件里面写window.print即可,这样做了以后table就会全打出来了,但是这样做的用户体验不会太好,新开的窗口还需手动关上,但是我看了一下好几个大型网站的做法,在页面布局很复杂的情况下,按下print按钮,先会出来一个print preview的页面,然后再打印,这样也许给了用户适当的选择。
  2. 使用css控制要打印的内容,对不打印的部分加上<div class=”noprint”></div>,对要缩放的table加上id=zoom_table,然后css里面加上@media print{.noprint {display:none;} #zoom_talbe{zoom:70%}},这里要注意的是,zoom这个属性只有ie支持,这样就可以解决部分打印的问题了,自己使用的是第二种方法

这里还要注意的是如果不想把另外一个frame打印出来,则需window.parent.frame_name.print

    分类: 前台设计 标签: , , ,

    上海交通大学08年研究生机试题B

    2009年9月23日 没有评论

    题目
    Problem B. Simple Sorting
    Input file: Standard Input
    Output file: Standard Output
    Time Limit: 1 Second

    You are given an unsorted array of integer numbers. Your task is to sort this array and kill possible duplicated elements occurring in it.

    Input
    The first line of the input contains an integer number N representing the quantity of numbers in this array(1≤N≤1000). Next N lines contain N integer numbers(one number per each line) of the original array.

    Output
    Output file should contain at most N numbers sorted in ascending order. Every number in the output file should occur only once.

    Sample input and output
    Standard Input Standard Output
    6 3
    8 7
    8 8
    7
    3
    7
    7

    C++代码

    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
    
    #include <iostream>
    #include <fstream>
    using namespace std;
    #define MAX_LEN 1000
     
    int number_of_inputs;
    int inputs[MAX_LEN];
     
    void get_inputs()
    {
    	int i;
    	cin >> number_of_inputs;
    	for (i=0;i<number_of_inputs;++i)
    	{
    		cin >> inputs[i];
    	}
    }
     
    void qsort(int left,int right)
    {
    	int i = left;
    	int j = right;
    	int pivot_index = (i + j) / 2;
    	int pivot = inputs[pivot_index];
    	while (i <= j)
    	{
    		while (inputs[i] < pivot)
    			++i;
    		while (inputs[j] > pivot)
    			--j;
    		if (i <= j)
    		{
    			int temp = inputs[i];
    			inputs[i++] = inputs[j];
    			inputs[j--] = temp;
    		}
    	}
    	if (i > left)
    		qsort(left,j);
    	if (j < right)
    		qsort(i,right);
    }
    int main()
    {
    	get_inputs();
     
    	qsort(0,number_of_inputs-1);
    	ofstream output_file;
    	output_file.open("output.txt");
    	for (int i =0;i<number_of_inputs-1;++i)
    	{
    		if (inputs[i] != inputs[i+1])
    			output_file << inputs[i] << endl;
    	}
    	if (i == number_of_inputs -1)
    		output_file << inputs[i] << endl;
    	output_file.close();
    	return 0;
    }
    分类: 算法 标签: , ,