So Tired !_! 逆水行舟, 不进则退!

26Jul/12

解决IIS7返回header里面的date值不正确导致firefox里cookies无效的问题.

Posted by Nick Xu

问题:

突然有一天,easybug.net上的登录功能无法使用,原本以为是自己电脑有问题,所以没有理会.后来又有好些用户反应无法登录.我就奇怪了,最近都没有更新过什么,怎么会突然就登录不了了呢.

用了很多方法都没有查到具体的原因,后来因为我点击切换语言的时候,发现这个功能也失效了.所以大致的原因可以锁定在cookies上了.用firebug上的net和cookies模块来监控http请求和cookies的值,发现在net里面是有带了cookies,但是在cookies标签里却看不到系统创建的cookies,就是说浏览器没有把cookies写入到浏览器里面,查了半天没找到什么原因,太神奇了...

后来想想既然在net标签里都已经有cookies信息了,那浏览器应该也是收到的了,会不会是在header里有什么问题呢?果然,看到一个很奇特的信息,在header里面看到这么一行信息:

date:2013-7-25 19:32:28

奇怪了,怎么日期是2013年呢,现在才2012年呢...于是顺藤摸瓜,查一下http协议相关的资料,果然被我查到这样一篇内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Problem Description
 
W3SVC logs show incorrect time - stuck on the same time 2007-11-04 04:56:06
REPRO STEPS
 
    Changed the system time to a future time (e.g. 11th May 2020)
    Browsed any site - verified the log file created in the new date/time
    Changed the system time to be correct (today's date and time)
    Now, browsed any website and saw that the time on the log files is now stuck on 11th May 2020's time
 
RESOLUTION
 
    net stop http
    net start w3svc
 
OR
 
    net stop http
    net start http
    iisreset
 
You must restart the http service whenever you change the date in the server.
 
Verified in the code and confirmed that this is by design and you need to follow the above steps to make IIS logging the correct time.

 

大致的意思是在IIS上,如果修改了服务器当前的日期到2020年,然后访问服务器上的站点,日志文件会以当前日期来记录日志内容,此时再把服务器上的日期修改回正确的日期,再访问站点,日志文件里的日期还是2020年的日期,不会自动修改回来,要解决这种问题,只有重启IIS,而且还一定要重启http这个服务,不然不会有效果的.我按上面的步骤试了一下,再来看一下header里面的date,果然现在已经是正确的值了,试一下登录easybug.net,yeah!!登录成功了!!!

总结出现以上问题的原因来自几个方面:
1. 这算是IIS的一个小小的BUG,不过为何会出现日期不一至呢?大部分是人为的原因造成的.
2.各个浏览器里面,好像只有Firefox在IIS出现这种情况的时候有问题,其它浏览器没有问题.
3.通过设置cookies的失效时间大于header里面date的时间应该也可以解决这个问题,不过没有去测试.
4.百年一遇的情况,RP问题啊:(

 

18Jul/12

在linux下编译安装nginx+php(fastcgi)

Posted by Nick Xu

nginx使用fastcgi方式连接php,在linux下面编译安装时要编译php支持fastcgi方式,其他的一些东西,照着原来的方式装就可以了。

分为以下步骤:

1、安装php的fastcgi版
2、使用spawn-fcgi启动php的fastcgi引擎
3、配置nginx连接php的fastcgi引擎

1、安装php的fastcgi版

mkdir /usr/local/modules

#jpeg目录
mkdir /usr/local/modules/jpeg6
mkdir /usr/local/modules/jpeg6/bin
mkdir /usr/local/modules/jpeg6/lib
mkdir /usr/local/modules/jpeg6/include
mkdir /usr/local/modules/jpeg6/man
mkdir /usr/local/modules/jpeg6/man/man1

A1、安装zlib

tar xzvf zlib-1.2.1.tar.gz
cd zlib-1.2.1
#不要用--prefix自定义安装目录,影响gd的安装
./configure
make
make install

A2、安装freetype

tar xzvf freetype-2.1.5.tar.gz
cd freetype-2.1.5
./configure --prefix=/usr/local/modules/freetype
make
make install

A3、安装libpng

tar xzvf libpng-1.2.5.tar.gz
#不要用--prefix自定义安装目录,影响gd的安装
cd libpng-1.2.5
cp scripts/makefile.std makefile
make test
make install

A3、安装jpeg

tar xzvf jpegsrc.v6b.tar.gz
cd jpeg-6b
./configure --prefix=/usr/local/modules/jpeg6 --enable-shared --enable-static
make
make install

A4、安装GD

tar xzvf gd-2.0.28.tar.gz
./configure --prefix=/usr/local/modules/gd --with-jpeg=/usr/local/modules/jpeg6 --with-png --with-zlib --with-freetype=/usr/local/modules/freetype
make
make install

然后编译安装php,注意加上--enable-fastcgi参数和--enable-force-cgi-redirect参数

./configure --prefix=/usr/local/php --with-gd=/usr/local/modules/gd --with-jpeg-dir=/usr/local/modules/jpeg6 --with-zlib --with-png --with-freetype-dir=/usr/local/modules/freetype --enable-magic-quotes --enable-fastcgi --with-mysql=/usr/local/mysql --enable-track-vars --enable-ftp --with-config-file-path=/usr/local/php/etc --with-zip --enable-force-cgi-redirect
make -j10
make install

如果过程中发现有错误:

mysql的错误在ubuntu 12.04 x64上解决方法:
sudo ln -s /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18 /usr/lib64/
sudo ln -s /usr/lib/x86_64-linux-gnu/libmysqlclient.so /usr/lib64/
2、使用spawn-fcgi启动php的fastcgi引擎

编译完成后在/usr/local/php/bin/下面就会有php-cgi这个可执行程序,使用spawn-fcgi启动php的fastcgi引擎:

/data/nginx/sbin/spawn-fcgi -a 127.0.0.1 -p 9000 -u nobody -f /usr/bin/php-cgi -C 20

意思是fastcgi使用本机ip和端口9000提供服务,权限nobody,启动20个进程。其中主要留意-C这个参数,一般20个进程足够用了,觉得不够亦可开大,在我的机器上每个php-cgi进程会占用7-8兆内存,开100个就是700-800兆。

spawn-fcgi这个程序在nginx里没有提供,可以在

http://www.sudone.com/download/spawn-fcgi

下载到,一般放在nginx的sbin目录下,然后要给它加上可执行权限:

chmod +x /data/nginx/sbin/spawn-fcgi

3、配置nginx连接php的fastcgi引擎

首先弄一份fastcgi-params配置,在nginx的conf目录下建一份文本文件,内容是:

#fastcgi-params
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;
#end

这个是最原始的fastcgi-params,在网上也可能有更优化的版本,可以相应取用。

然后配置nginx.conf,比如www.sudone.com,这样配置就可以用了:

server {
include port.conf;
server_name www.sudone.com sudone.com;

location / {
index index.html index.php;
root /data/sudone/php/;
}

location ~ .php$ {
fastcgi_pass   127.0.0.1:9000;
fastcgi_index  index.php;
fastcgi_param  SCRIPT_FILENAME  /data/sudone/php$fastcgi_script_name;
include        fastcgi_params;
}
}

拿下来之后,有几个需要改的地方:

1、server_name
2、location /里面的root
3、location ~ .php$里面的fastcgi_param  SCRIPT_FILENAME

其中fastcgi_param  SCRIPT_FILENAME的参数中,$fastcgi_script_name前面是php文件的路径一般和root一样的,最后不用写/,貌似会有点问题,不要画蛇添足。

注意事项:

可能会有的管理员启动nginx后总是忘记启动spawn-fcgi,所以最好是写一份脚本来启动,然后要养成测试服务可用性的习惯。

16Jul/12

Setting up a Mercurial server under IIS7 on Windows Server 2008 R2

Posted by Nick Xu

This guide walks you through setting up a Mercurial server under IIS7 on Windows Server 2008 R2.

Note: This post uses Mercurial 1.4.3 and Python 2.5.4, although this process will also work with Mercurial 1.5 and Python 2.6.4

Install Mercurial

First you’ll need to download and install Mercurial. I won’t walk through this as it’s a simple case of pressing "next" several times.

Install Python

Next you’ll need to install Python. Note that you need to use the same version of Python that was used to build Mercurial. This guide uses Mercurial 1.4.3 with Python 2.5.4, but if you’re installing Mercurial 1.5 then you’ll need to use Python 2.6 instead.

Be sure to install the x86 version of Python even if you’re running on an x64 system.

Get hgwebdir

Next you’ll need to download hgwebdir.cgi. This is the python script that will allow serving Mercurial repositories through a web server.

Hgwebdir is part of the Mercurial source code, so you’ll need to download the source package to get it. This can be found on the Mercurial site or you can check out the hg source by running the following command:

hg clone http://selenic.com/repo/hg

Once downloaded, hgwebdir.cgi is in the root of the source distribution.

Install IIS

Under Windows Server 2008 you can install IIS under the Server Manager and clicking "Add Roles". Proceed through the wizard and select the "Web Server (IIS)" role.

Under "Role Services" ensure that you enable Basic Authentication as well as CGI extensibility.

Configure Python for IIS

First, create a new directory under the wwwroot directory (C:inetpubwwwroot). I’m going to call it "hg".

In the "Handler mappings" section for this directory select "Add Script Map":

Next, enter *.cgi as the Request Path and the Executable Path should be set toc:Python25python.exe -u "%s". Enter "Python" as the Name.

At this point, you can test whether Python is working properly by creating a simple python script:

print 'Status: 200 OK'
print 'Content-type: text/html'
print

print '<html><head>'
print ''
print '<h1>It works!</h1>'
print ''
print ''

Save this in the directory that you created (C:inetpubwwwroothg) as test.cgi. Now, when you point your browser to http://localhost/hg/test.cgi you should see the following output:

Enabling hgwebdir.cgi

First, copy hgwebdir.cgi (that you downloaded in step 3) and paste it into c:inetpubwwwroothg. Open this file in a text editor and scroll down to the end. The last lines should look like this:

application = hgwebdir('hgweb.config')
wsgicgi.launch(application)

Change the first line to explicitly specify the path to your hg directory:

application = hgwebdir('c:inetpubwwwroothghgweb.config')
wsgicgi.launch(application)

Next, you’ll need to unzip the Mercurial library into c:inetpubwwwroothg. This can be found inLibrary.zip under the c:program files (x86)Mercurial directory.

You’ll now need to copy the hgweb templates directory into c:inetpubwwwroothg. This is located in the root of the Mercurial installation directory (C:program files (x86)Mercurial)

Finally, create a file called hgweb.config in c:inetpubwwwroothg. This file can be empty for now (we’ll be putting something in it shortly).

At this point, visiting http://localhost/hg/hgwebdir.cgi will show you an empty repository page:

Configuring Repositories

Now you’ll need to create some repositories to publish. To do this, create a directory in the root of the C: drive called "Repositories". This is where our repositories are going to be stored.

Next, I’m going to create a "test" repository by issuing the following commands:

cd c:repositories
mkdir test
hg init test

Now we have a repository created, we need to tell hgwebdir where to find it. We can do this by opening up the hgweb.config file we created earlier and adding the following lines:

[collections]
C:repositories = C:repositories

Now, visiting http://localhost/hg/hgwebdir.cgi should display our "test" repository

At this point it should now be possible to clone the test repository from the server with the following command:

hg clone http://localhost/hg/hgwebdir.cgi/test

Pretty URLs

Personally, I don’t like having to specify "hgwebdir.cgi" in the URLs. I’d much prefer something like http://localhost/hg/test to access my test repository.

This can be achived by using the URL rewriting extension for IIS which can be downloaded from Microsoft.

Once installed, you can access the URL rewriting settings though the "URL Rewrite" section of the IIS Manager. Select the "hg" subdirectory in the Connections pane and then select "URL Rewrite":

In the URL rewrite section add a new blank rule. The name of the rule is going to be "rewrite to hgwebdir".

Under the "Match URL" section set "Using" to "Wildcards" and set the "Pattern" to "*"

Under "Conditions" we want to ensure that we do not re-write URLs to any physical files, so add a condition for "Is Not a File":

In the "Rewrite URL" box at the bottom of the screen enter hgwebdir.cgi/{R:1}

The end result will look like this:

Finally, re-open your hgweb.config and add the following section:

[web]
baseurl = /hg

This will ensure that hgwebdir generates urls to /hg rather than /hg/hgwebdir.cgi

Now, visiting http://localhost/hg will display our repositories page and http://localhost/hg/test will show our test repository. Likewise, we can now clone repositories using this url format.

Pushing Changes

By default, all repositores served via hgwebdir are read only – you cannot push changes to them. To change this, we can specify the users that should be able to push to the repositores by adding an "allow_push" section to our hgweb.config:

[collections]
c:repositories = c:repositories

[web]
baseurl = /hg
allow_push = Jeremy

This means that the user account "Jeremy" (a local user account on the server) will have push access to the repository.

However, if we try and push changes we’ll get an error:

c:projectstest&gt;hg push
pushing to http://localhost/hg/hgwebdir.cgi/test
searching for changes
ssl required

For now, we’ll disable SSL by setting push_ssl to false in our hgweb.config:

[collections]
c:repositories = c:repositories

[web]
baseurl = /hg
allow_push = Jeremy
push_ssl = false

Now when we try and push we get a different error:

c:projectstest&gt;hg push
pushing to http://localhost/hg/hgwebdir.cgi/test
searching for changes
abort: authorization failed

This happens because by default IIS is serving up our site without authentication. We need to enable Basic Authentication in the Authentication area of IIS:

Now you’ll be prompted to enter your username and password:

After specifying the credetails, the changes will be pushed up. We can view the commit in our web UI:

Enabling SSL

When you use Basic authentication, your username and password will be sent over the wire in plain text. To make this more secure we can enable SSL. For this example I’m going to use a self-signed certificate, although this will also work with a real SSL certificate purchased from a provider.

First, you’ll need to go into the IIS manager, select "Server Certificates" and click "Create Self-Signed Certificate"

Now, add a binding for your Web Site for https on port 443 by right clicking on the site and selecting "Edit Bindings".

Add a new binding for https on port 443:

Once this is done, you should now be able to access the hgwebdir site by using https (https://localhost/hg). You’ll probably get an invalid certificate warning in your browser.

Now you can re-clone the repository using the secure url (also be sure to remove the "push_ssl = false" line from hgweb.config)

All done!

At this point, you should have successfully set up everything you need to use Mercurial in IIS7.

   
site
site