生成支持chrome的域名证书【实测终极版】

chrome浏览器因为其安全性较高,所以普通生成的证书其总是验证不过,总会有安全的提示,为此进行了多次的实验及各种各样的测试,最终发现如下的方式可以彻底解决chrome证书安全的问题,并在地址栏显示其安全,所以,就将设置的方式分享如下,希望对大家能有所帮助。

当然最后生成的ca.crt证书一定要导入到浏览器的根证书下,作为其信任的发行机构。

配置网站的生成ssl证书,说实在了,经过了几天的测试实践,终于搞定,过程真是辛苦,最重要的是要明白其中的道理和原理,才不会走弯路。

另外双向认证其实无所谓,可以不用设置。顺便参考下我之前发表的几篇文章,对大家肯定会有所帮助。

修改openssl.cnf

[ req ]

distinguished_name = req_distinguished_name

req_extensions = v3_req #取消这行注释

# 确保req_distinguished_name下没有 0.xxx 的标签,有的话把0.xxx的0. 去掉

[ req_distinguished_name ]

countryName = Country Name (2 letter code)

countryName_default = CN

stateOrProvinceName = State or Province Name (full name)

stateOrProvinceName_default = GuangDong

localityName = Locality Name (eg, city)

localityName_default = ShenZhen

organizationalUnitName = Organizational Unit Name (eg, section)

organizationalUnitName_default = 303 IT Lab

commonName = IT Lab

commonName_max = 64

[ v3_req ]

# Extensions to add to a certificate request

basicConstraints = CA:FALSE

keyUsage = nonRepudiation, digitalSignature, keyEncipherment

subjectAltName = @alt_names #增加这行

# 新增以下部分

[ alt_names ]

DNS.1 = abc.com

DNS.2 = *.abc.com

DNS.3 = xyz.com

DNS.4 = *.xyz.com

可以自行增加多域名

创建相关目录及文件

mkdir -p CA/{certs,crl,newcerts,private}

touch CA/index.txt

echo 00 > CA/serial

1.生成ca.key并自签署

openssl req -sha256 -new -x509 -days 3650 -keyout ca.key -out ca.crt -config openssl.cnf

2.生成server.key

openssl genrsa -out server.key 2048

3.生成证书签名请求

openssl req -new -sha256 -key server.key -out server.csr -config openssl.cnf

Common Name 就是在这一步填写 *.abc.com common name一定要在alt_names中包含

4.查看签名请求文件信息

openssl req -in server.csr -text

检查 Signature Algorithm 是不是sha256WithRSAEncryptio

5.使用自签署的CA,签署server.scr

openssl ca -in server.csr -md sha256 -out server.crt -cert ca.crt -keyfile ca.key -extensions v3_req -config openssl.cnf

注意:即便是你前面是sha256的根证书和sha256的请求文件,如果不加-md sha256,默认是按照sha1进行签名的

6.查看证书

openssl x509 -in server.crt -text

同样检查 Signature Algorithm 是不是sha256WithRSAEncryptio

5.00 avg. rating (99% score) - 3 votes

Windows下搭建HTTP/HTTPS服务器方案二

3 制作CA证书、Server证书和Client证书
3.1 准备工作
在C:\Apache24\bin目录下创建demoCA目录,并在该目录下创建如下几个文件和文件夹

index.txt
newcerts\
serial
注:
serial文件没有文件后缀
用文本编辑器打开serial,并写入’01’(实际操作时不要加引号)
打开命令行,进入C:\Apache22\bin

cd C:\Apache22\bin
3.2 生成CA证书
1)生成CA私钥

openssl genrsa -out ca.key 2048
命令描述:
该命令会在当前目录下生成一个私钥文件ca.key
参数说明:
gensa:生成rsa密钥
-out:指定输出的文件名
2048:密钥长度

2)生成CA证书

openssl req -new -x509 -days 5000 -key ca.key -out ca.crt
命令描述:
该命令会在当前目录下生成一个自签名的CA证书文件ca.crt
参数说明:
req:请求操作
-new:生成新的文件
-x509:证书文件的格式
-days:证书有效期
-key:指定私钥文件
-out:指定输出文件
注:
由于CA文件是用来给其他证书签名文件签名以生成对应的证书文件的,不需要其他文件给CA证书签名,因此生成的CA证书是自签名的。

3.3 生成Server端证书
1)生成Server证书私钥
openssl genrsa -out server.key 2048

2)生成Server证书请求文件

openssl req -new -key server.key -out server.csr
命令描述:
该命令会在当前目录下生成一个证书请求文件server.csr,用CA证书给证书请求文件签名后即可生成证书文件。
参数说明:
req:请求操作
-new:生成新的文件
-key:指定私钥文件
-out:指定输出文件
运行该命令时,命令行会提示输入CountryName(填CN),ProvinceName和CommonName等。CommonName(公用名)是个很重要的参数,如果要在外网访问HTTP/HTTPS服务器,CommonName必须填服务器的域名或者公网IP;如果只在内网做测试,CommonName可以填服务器主机的内网IP。
注:
由于Server的证书请求文件需要被CA证书文件签名后才能生成证书文件,不能使用自签名,因此不使用-x509选项

3)生成Server证书

openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key
命令描述:
该命令使用CA证书对证书请求文件签名,以生成证书文件
参数说明:
ca:表示是对证书请求文件进行签名
-in:指定输入的证书请求文件
-out:指定输出文件
-cert:指定CA证书文件
-keyfile:指定CA私钥文件

4)验证Server证书

openssl verify -CAfile ca.crt server.crt
命令描述:
该命令用于验证生成的证书文件是否正确,若正确则输出OK,若错误则输出ERROR。
命令说明:
verify:表示是对证书文件进行认证
-CAfile:指定CA证书文件

3.4 生成Client端证书
1)生成Client私钥

openssl genrsa -out client.key 2048
2)生成Client证书请求文件

openssl req -new -key client.key -out client.csr
注意:
生成Client端证书请求文件时,ON(Organization Name)必须与生成服务器时使用的ON一样,并且OU(Organizational Unit Name)和CN(Common Name)不能与生成Server端证书请求文件时使用的OU和CN相同,否则会报错,原因是不能同时给同一个Server生成两个证书请求文件。

3)生成Client证书

openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key
4)验证Client证书

openssl verify -CAfile ca.crt client.crt
5)生成p12格式的Client证书

openssl pkcs12 -export -inkey client.key -in client.crt -out client.pfx
注:
由于在Windows下浏览器只能安装p12格式的客户端证书,因此要将.crt格式的Client证书转换成p12格式的证书。在SSL双向认证时需要客户端也安装自己的证书文件。

4 配置HTTP服务器
修改 Apache24\conf\httpd.conf 文件:
1)修改侦听端口号,将‘Listen 80’中的80改为想要设置的HTTP侦听端口号
若改成80端口以外的端口号,在用浏览器访问HTTP服务器时,URL中需指明端口号,格式是:http://hostip:port
其中,hostip指HTTP服务器主机的IP或域名,port是HTTP服务器侦听端口号
建议使用默认值80,若改为其他值,在服务器上用wireshark抓IP进行分析时,wireshark不能解析HTTP报文,不利于分析。
2)将DocumentRoot “${SRVROOT}/htdocs”用#注释掉,改为 DocumentRoot “D:\httpdocs”

#DocumentRoot “${SRVROOT}/htdocs”
DocumentRoot “D:\httpdocs”
3)将用#注释掉,改为

#

注:
D:/httpdocs就是HTTP访问的文件根目录,也可以改成其他文件目录,但DocumentRoot和Directory中的目录必须一致

5 配置HTTPS服务器
5.1 修改 Apache24\conf\httpd-ssl.conf 文件
1)修改侦听端口号,将‘Listen 433’中的443改为想要侦听的端口。
同样建议使用默认值443,若改为其他值,在服务器上用wireshark抓IP进行分析时,wireshark不能解析HTTPS报文。
2)将 SSLCertificateFile 后面的服务器证书文件路径修改为 “${SRVROOT}/conf/ssl/server.crt”

SSLCertificateFile “${SRVROOT}/conf/ssl/server.crt”
SRVROOT变量的值就是“/Apache24”
3)将SSLCertificateKeyFile后面的服务器私钥文件路径修改为 “${SRVROOT}/conf/ssl/server.key”

SSLCertificateKeyFile “${SRVROOT}/conf/ssl/server.key”
4)将SSLCACertificateFile后面的CA证书文件路径修改为 “${SRVROOT}/conf/ssl/ca.crt”

SSLCACertificateFile “${SRVROOT}/conf/ssl/ca.crt”
此项设置只用于双向认证,如果不需要做双向认证,CA证书路径不设置
5)将DocumentRoot后面的文件路径修改为 “D:\httpsdocs”

DocumentRoot “D:\httpsdocs”
6)将以下3行用#号注释掉


SSLOptions +StdEnvVars

增加以下行:


SSLOptions +StdEnvVars
Options +Indexes FollowSymLinks +ExecCGI
AllowOverride AuthConfig FileInfo
Order allow,deny
Allow from all

此处若不做修改,HTTPS服务器会无法访问,浏览器会显示403错误,错误信息是“服务器可能要求登录”。
注:
与设置HTTP服务器时类似,DocumentRoot和Directory表示HTTPS访问的文件根目录,可以设置成任何目录,但DocumentRoot和Directory设置值必须保持一致
7)如果需要设置SSL双向认证,需要将以下两行前的#注释符删掉(即取消注释):

SSLVerifyClient require
SSLVerifyDepth 10
5.2 修改Apache24\conf\extra\httpd-ahssl.conf文件
该文件中有三段以 行结尾的文本。后面两段配置文本配置的是两个虚拟主机,ServerName分别是serverone.tld:443和servertwo.tld:443。这两个虚拟主机我们都不用,因此将后面两段之间(包括这两行)的内容用#注释掉。
接下来修改第一段之间的配置文本,ServerName是localhost:443。
1)修改侦听端口号,将‘Listen 433’中的443改为想要侦听的端口。
建议使用443默认值,若改为其他值,在服务器上用wireshark抓IP进行分析时,wireshark不能解析HTTPS报文。
2)将SSLCertificateFile后面的服务器证书路径修改为 “${SRVROOT}/conf/ssl/server.crt”

SSLCertificateFile “${SRVROOT}/conf/ssl/server.crt”
3)将SSLCertificateKeyFile后面的服务器私钥文件路径修改为 “${SRVROOT}/conf/ssl/server.key”

SSLCertificateKeyFile “${SRVROOT}/conf/ssl/server.key”
4)将 DocumentRoot “${SRVROOT}/htdocs” 注释掉,修改为 DocumentRoot “D:/httpsdocs”

# DocumentRoot “${SRVROOT}/htdocs”
DocumentRoot “D:\httpsdocs”
5)将注释掉,修改为

#

注:
若此处是


SSLOptions +StdEnvVars

那么需要将这3行注释掉,增加以下行


SSLOptions +StdEnvVars
Options +Indexes FollowSymLinks +ExecCGI
AllowOverride AuthConfig FileInfo
Order allow,deny
Allow from all

安装httpd-2.4.25-x64时此处此处已经改好了,不需要另外做修改;但在安装httpd-2.2.32-x86时发现需要修改的。
6)如果要配置SSL双向认证,需在SSLCertificateKeyFile “${SRVROOT}/conf/ssl/server.key”行之后增加以下3行内容:

SSLCACertificateFile “${SRVROOT}/conf/ssl/ca.crt”
SSLVerifyClient require
SSLVerifyDepth 10
5.3 配置SSL单向认证/双向认证
如果需要将HTTPS服务器配置成SSL双向认证,打开5.2节7)的设置和5.3节7)的设置,重启Apache;
如果需要将HTTPS服务器配置成SSL单向认证,将5.2节7)的设置和5.3节7)的设置注释掉,重启Apache;

6 浏览器测试
测试之前,在D:/httpdocs目录下新建一个index.html文件,用文本编辑器打开后写入“HTTP works”;在D:/httpsdocs目录下同样新建一个index.html文件,写入“HTTPS works”。

6.1 测试HTTP服务器
在局域网内另一台电脑的IE浏览器地址栏输入http://hostip,其中hostip是服务器主机的IP或域名。
如果浏览器中显示“HTTP如果浏览器中显示“HTTP works”,表示HTTP服务器工作正常。

6.2 测试HTTPS单向认证
按照第5章的描述将HTTPS服务器设置成SSL单向认证
1)在IE浏览器地址栏输入https://hostip(hostip是服务器的IP或域名),此时无法正常访问服务器,原因是没有导入服务器的证书和CA证书。
2)导入服务器证书和CA证书
打开IE浏览器”Internet选项”——>“内容”——>“证书”,在弹出的“证书”窗口中,点击“受信任的根证书颁发机构”,导入ca.crt文件;然后点击“受信任的发布者”,导入server.crt文件。
3)重启IE浏览器,在地址栏输入https://hostip,如果显示“HTTPS works”,则表示HTTPS服务器工作正常。

6.3 测试HTTPS双向认证
按照第4章的描述将HTTPS服务器设置成SSL双向认证
1)在IE浏览器地址栏输入https://hostip
此时会发现,虽然已经导入服务器的证书和CA证书,但仍然无法正常访问HTTPS服务器,原因是设置了SSL双向认证后,服务器也会对客服端进行认证,只有受信任的客户端才能访问服务器。
2)双击client.pfx文件,安装客户端证书
完成客户端证书的安装后,在IE浏览器“Internet选项”——>“内容”——>“证书”——>”个人“中看到安装的client证书
3)重启IE浏览器,在地址栏输入https://iphost
这时会发现就已经可以正常访问HTTPS服务器了。

5.00 avg. rating (99% score) - 2 votes

windows下memcache的安装和PHP的管理

memcached下载地址:
http://www.newasp.net/soft/63735.html

php_memcache.dll下载地址:
http://windows.php.net/downloads/pecl/releases/memcache/3.0.8/

将memcached解压到一个非中文的目录下,然后再将php_memcache.dll复制到php下的exts目录下.

启动命令行,进入memcache.exe的安装目录, 在后面输入memcached.exe -d install 将memcache注册为windows服务

然后再输入 memcache.exe -d start,开启memcache服务

在php.ini文件最后面加上下面这句
extension=php_memcache.dll

5.00 avg. rating (99% score) - 1 vote

PHP 兼容 Curl/Socket/Stream 的 HTTP 操作类

<?php
/************************************************************
* 描述:HTTP操作类
* 作者:heiyeluren
* 创建:2009/12/13 04:43
* 修改:2009/12/16 10:30 实现基本HTTP各种接口操作支持
*
************************************************************/

 

/**
* HTTP功能工厂方法类
*
* 调用示例代码:
try {
$http = Http::factory(‘http://www.baidu.com’, Http::TYPE_SOCK );
echo $http->get();
$http = Http::factory(‘http://127.0.0.1/test/i.php’, Http::TYPE_SOCK );
echo $http->post(”, array(‘user’=>’我们’, ‘nick’=>’ASSADF@#!32812989+-239%ASDF’), ”, array(‘aa’=>’bb’, ‘cc’=>’dd’));
} catch (Exception $e) {
echo $e->getMessage();
}
*/
class Http
{
/**
* @var 使用 CURL
*/
const TYPE_CURL = 1;
/**
* @var 使用 Socket
*/
const TYPE_SOCK = 2;
/**
* @var 使用 Stream
*/
const TYPE_STREAM = 3;

/**
* 保证对象不被clone
*/
private function __clone() {}

/**
* 构造函数
*/
private function __construct() {}

 

/**
* HTTP工厂操作方法
*
* @param string $url 需要访问的URL
* @param int $type 需要使用的HTTP类
* @return object
*/
public static function factory($url = ”, $type = self::TYPE_SOCK){
if ($type == ”){
$type = self::TYPE_SOCK;
}
switch($type) {
case self::TYPE_CURL :
if (!function_exists(‘curl_init’)){
throw new Exception(__CLASS__ . ” PHP CURL extension not install”);
}
$obj = Http_Curl::getInstance($url);
break;
case self::TYPE_SOCK :
if (!function_exists(‘fsockopen’)){
throw new Exception(__CLASS__ . ” PHP function fsockopen() not support”);
}
$obj = Http_Sock::getInstance($url);
break;
case self::TYPE_STREAM :
if (!function_exists(‘stream_context_create’)){
throw new Exception(__CLASS__ . ” PHP Stream extension not install”);
}
$obj = Http_Stream::getInstance($url);
break;
default:
throw new Exception(“http access type $type not support”);
}
return $obj;
}

/**
* 生成一个供Cookie或HTTP GET Query的字符串
*
* @param array $data 需要生产的数据数组,必须是 Name => Value 结构
* @param string $sep 两个变量值之间分割的字符,缺省是 &
* @return string 返回生成好的Cookie查询字符串
*/
public static function makeQuery($data, $sep = ‘&’){
$encoded = ”;
while (list($k,$v) = each($data)) {
$encoded .= ($encoded ? “$sep” : “”);
$encoded .= rawurlencode($k).”=”.rawurlencode($v);
}
return $encoded;
}

}

 

 

/**
* 使用CURL 作为核心操作的HTTP访问类
*
* @desc CURL 以稳定、高效、移植性强作为很重要的HTTP协议访问客户端,必须在PHP中安装 CURL 扩展才能使用本功能
*/
class Http_Curl
{
/**
* @var object 对象单例
*/
static $_instance = NULL;

/**
* @var string 需要发送的cookie信息
*/
private $cookies = ”;
/**
* @var array 需要发送的头信息
*/
private $header = array();
/**
* @var string 需要访问的URL地址
*/
private $uri = ”;
/**
* @var array 需要发送的数据
*/
private $vars = array();

 

/**
* 构造函数
*
* @param string $configFile 配置文件路径
*/
private function __construct($url){
$this->uri = $url;
}

/**
* 保证对象不被clone
*/
private function __clone() {}

 

/**
* 获取对象唯一实例
*
* @param string $configFile 配置文件路径
* @return object 返回本对象实例
*/
public static function getInstance($url = ”){
if (!(self::$_instance instanceof self)){
self::$_instance = new self($url);
}
return self::$_instance;
}

/**
* 设置需要发送的HTTP头信息
*
* @param array/string 需要设置的头信息,可以是一个 类似 array(‘Host: example.com’, ‘Accept-Language: zh-cn’) 的头信息数组
* 或单一的一条类似于 ‘Host: example.com’ 头信息字符串
* @return void
*/
public function setHeader($header){
if (empty($header)) {
return;
}
if (is_array($header)){
foreach ($header as $k => $v){
$this->header[] = is_numeric($k) ? trim($v) : (trim($k) .”: “. trim($v));
}
} elseif (is_string($header)){
$this->header[] = $header;
}
}

/**
* 设置Cookie头信息
*
* 注意:本函数只能调用一次,下次调用会覆盖上一次的设置
*
* @param string/array 需要设置的Cookie信息,一个类似于 ‘name1=value1&name2=value2’ 的Cookie字符串信息,
* 或者是一个 array(‘name1’=>’value1’, ‘name2’=>’value2’) 的一维数组
* @return void
*/
public function setCookie($cookie){
if (empty($cookie)) {
return;
}
if (is_array($cookie)){
$this->cookies = Http::makeQuery($cookie, ‘;’);
} elseif (is_string($cookie)){
$this->cookies = $cookie;
}
}

/**
* 设置要发送的数据信息
*
* 注意:本函数只能调用一次,下次调用会覆盖上一次的设置
*
* @param array 设置需要发送的数据信息,一个类似于 array(‘name1’=>’value1’, ‘name2’=>’value2’) 的一维数组
* @return void
*/
public function setVar($vars){
if (empty($vars)) {
return;
}
if (is_array($vars)){
$this->vars = $vars;
}
}

/**
* 设置要请求的URL地址
*
* @param string $url 需要设置的URL地址
* @return void
*/
public function setUrl($url){
if ($url != ”) {
$this->uri = $url;
}
}

/**
* 发送HTTP GET请求
*
* @param string $url 如果初始化对象的时候没有设置或者要设置不同的访问URL,可以传本参数
* @param array $vars 需要单独返送的GET变量
* @param array/string 需要设置的头信息,可以是一个 类似 array(‘Host: example.com’, ‘Accept-Language: zh-cn’) 的头信息数组
* 或单一的一条类似于 ‘Host: example.com’ 头信息字符串
* @param string/array 需要设置的Cookie信息,一个类似于 ‘name1=value1&name2=value2’ 的Cookie字符串信息,
* 或者是一个 array(‘name1’=>’value1’, ‘name2’=>’value2’) 的一维数组
* @param int $timeout 连接对方服务器访问超时时间,单位为秒
* @param array $options 当前操作类一些特殊的属性设置
* @return unknown
*/
public function get($url = ”, $vars = array(), $header = array(), $cookie = ”, $timeout = 5, $options = array()){
$this->setUrl($url);
$this->setHeader($header);
$this->setCookie($cookie);
$this->setVar($vars);
return $this->send(‘GET’, $timeout);
}

/**
* 发送HTTP POST请求
*
* @param string $url 如果初始化对象的时候没有设置或者要设置不同的访问URL,可以传本参数
* @param array $vars 需要单独返送的GET变量
* @param array/string 需要设置的头信息,可以是一个 类似 array(‘Host: example.com’, ‘Accept-Language: zh-cn’) 的头信息数组
* 或单一的一条类似于 ‘Host: example.com’ 头信息字符串
* @param string/array 需要设置的Cookie信息,一个类似于 ‘name1=value1&name2=value2’ 的Cookie字符串信息,
* 或者是一个 array(‘name1’=>’value1’, ‘name2’=>’value2’) 的一维数组
* @param int $timeout 连接对方服务器访问超时时间,单位为秒
* @param array $options 当前操作类一些特殊的属性设置
* @return unknown
*/
public function post($url = ”, $vars = array(), $header = array(), $cookie = ”, $timeout = 5, $options = array()){
$this->setUrl($url);
$this->setHeader($header);
$this->setCookie($cookie);
$this->setVar($vars);
return $this->send(‘POST’, $timeout);
}

/**
* 发送HTTP请求核心函数
*
* @param string $method 使用GET还是POST方式访问
* @param array $vars 需要另外附加发送的GET/POST数据
* @param int $timeout 连接对方服务器访问超时时间,单位为秒
* @param array $options 当前操作类一些特殊的属性设置
* @return string 返回服务器端读取的返回数据
*/
public function send($method = ‘GET’, $timeout = 5, $options = array()){
//处理参数是否为空
if ($this->uri == ”){
throw new Exception(__CLASS__ .”: Access url is empty”);
}

//初始化CURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);

//设置特殊属性
if (!empty($options)){
curl_setopt_array($ch , $options);
}
//处理GET请求参数
if ($method == ‘GET’ && !empty($this->vars)){
$query = Http::makeQuery($this->vars);
$parse = parse_url($this->uri);
$sep = isset($parse[‘query’]) ? ‘&’ : ‘?’;
$this->uri .= $sep . $query;
}
//处理POST请求数据
if ($method == ‘POST’){
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->vars);
}

//设置cookie信息
if (!empty($this->cookies)){
curl_setopt($ch, CURLOPT_COOKIE, $this->cookies);
}
//设置HTTP缺省头
if (empty($this->header)){
$this->header = array(
‘User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)’,
//’Accept-Language: zh-cn’,
//’Cache-Control: no-cache’,
);
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->header);

//发送请求读取输数据
curl_setopt($ch, CURLOPT_URL, $this->uri);
$data = curl_exec($ch);
if( ($err = curl_error($ch)) ){
curl_close($ch);
throw new Exception(__CLASS__ .” error: “. $err);
}
curl_close($ch);
return $data;
}

}

 

 

/**
* 使用 Socket操作(fsockopen) 作为核心操作的HTTP访问接口
*
* @desc Network/fsockopen 是PHP内置的一个Sokcet网络访问接口,必须安装/打开 fsockopen 函数本类才能工作,
* 同时确保其他相关网络环境和配置是正确的
*/
class Http_Sock
{
/**
* @var object 对象单例
*/
static $_instance = NULL;

/**
* @var string 需要发送的cookie信息
*/
private $cookies = ”;
/**
* @var array 需要发送的头信息
*/
private $header = array();
/**
* @var string 需要访问的URL地址
*/
private $uri = ”;
/**
* @var array 需要发送的数据
*/
private $vars = array();

 

/**
* 构造函数
*
* @param string $configFile 配置文件路径
*/
private function __construct($url){
$this->uri = $url;
}

/**
* 保证对象不被clone
*/
private function __clone() {}

 

/**
* 获取对象唯一实例
*
* @param string $configFile 配置文件路径
* @return object 返回本对象实例
*/
public static function getInstance($url = ”){
if (!(self::$_instance instanceof self)){
self::$_instance = new self($url);
}
return self::$_instance;
}

/**
* 设置需要发送的HTTP头信息
*
* @param array/string 需要设置的头信息,可以是一个 类似 array(‘Host: example.com’, ‘Accept-Language: zh-cn’) 的头信息数组
* 或单一的一条类似于 ‘Host: example.com’ 头信息字符串
* @return void
*/
public function setHeader($header){
if (empty($header)) {
return;
}
if (is_array($header)){
foreach ($header as $k => $v){
$this->header[] = is_numeric($k) ? trim($v) : (trim($k) .”: “. trim($v));
}
} elseif (is_string($header)){
$this->header[] = $header;
}
}

/**
* 设置Cookie头信息
*
* 注意:本函数只能调用一次,下次调用会覆盖上一次的设置
*
* @param string/array 需要设置的Cookie信息,一个类似于 ‘name1=value1&name2=value2’ 的Cookie字符串信息,
* 或者是一个 array(‘name1’=>’value1’, ‘name2’=>’value2’) 的一维数组
* @return void
*/
public function setCookie($cookie){
if (empty($cookie)) {
return;
}
if (is_array($cookie)){
$this->cookies = Http::makeQuery($cookie, ‘;’);
} elseif (is_string($cookie)){
$this->cookies = $cookie;
}
}

/**
* 设置要发送的数据信息
*
* 注意:本函数只能调用一次,下次调用会覆盖上一次的设置
*
* @param array 设置需要发送的数据信息,一个类似于 array(‘name1’=>’value1’, ‘name2’=>’value2’) 的一维数组
* @return void
*/
public function setVar($vars){
if (empty($vars)) {
return;
}
if (is_array($vars)){
$this->vars = $vars;
}
}

/**
* 设置要请求的URL地址
*
* @param string $url 需要设置的URL地址
* @return void
*/
public function setUrl($url){
if ($url != ”) {
$this->uri = $url;
}
}

/**
* 发送HTTP GET请求
*
* @param string $url 如果初始化对象的时候没有设置或者要设置不同的访问URL,可以传本参数
* @param array $vars 需要单独返送的GET变量
* @param array/string 需要设置的头信息,可以是一个 类似 array(‘Host: example.com’, ‘Accept-Language: zh-cn’) 的头信息数组
* 或单一的一条类似于 ‘Host: example.com’ 头信息字符串
* @param string/array 需要设置的Cookie信息,一个类似于 ‘name1=value1&name2=value2’ 的Cookie字符串信息,
* 或者是一个 array(‘name1’=>’value1’, ‘name2’=>’value2’) 的一维数组
* @param int $timeout 连接对方服务器访问超时时间,单位为秒
* @param array $options 当前操作类一些特殊的属性设置
* @return unknown
*/
public function get($url = ”, $vars = array(), $header = array(), $cookie = ”, $timeout = 5, $options = array()){
$this->setUrl($url);
$this->setHeader($header);
$this->setCookie($cookie);
$this->setVar($vars);
return $this->send(‘GET’, $timeout);
}

/**
* 发送HTTP POST请求
*
* @param string $url 如果初始化对象的时候没有设置或者要设置不同的访问URL,可以传本参数
* @param array $vars 需要单独返送的GET变量
* @param array/string 需要设置的头信息,可以是一个 类似 array(‘Host: example.com’, ‘Accept-Language: zh-cn’) 的头信息数组
* 或单一的一条类似于 ‘Host: example.com’ 头信息字符串
* @param string/array 需要设置的Cookie信息,一个类似于 ‘name1=value1&name2=value2’ 的Cookie字符串信息,
* 或者是一个 array(‘name1’=>’value1’, ‘name2’=>’value2’) 的一维数组
* @param int $timeout 连接对方服务器访问超时时间,单位为秒
* @param array $options 当前操作类一些特殊的属性设置
* @return unknown
*/
public function post($url = ”, $vars = array(), $header = array(), $cookie = ”, $timeout = 5, $options = array()){
$this->setUrl($url);
$this->setHeader($header);
$this->setCookie($cookie);
$this->setVar($vars);
return $this->send(‘POST’, $timeout);
}

/**
* 发送HTTP请求核心函数
*
* @param string $method 使用GET还是POST方式访问
* @param array $vars 需要另外附加发送的GET/POST数据
* @param int $timeout 连接对方服务器访问超时时间,单位为秒
* @param array $options 当前操作类一些特殊的属性设置
* @return string 返回服务器端读取的返回数据
*/
public function send($method = ‘GET’, $timeout = 5, $options = array()){
//处理参数是否为空
if ($this->uri == ”){
throw new Exception(__CLASS__ .”: Access url is empty”);
}

//处理GET请求参数
if ($method == ‘GET’ && !empty($this->vars)){
$query = Http::makeQuery($this->vars);
$parse = parse_url($this->uri);
$sep = isset($parse[‘query’])&&($parse[‘query’]!=”) ? ‘&’ : ‘?’;
$this->uri .= $sep . $query;
}

//处理POST请求数据
$data = ”;
if ($method == ‘POST’ && !empty($this->vars)){
$data = Http::makeQuery($this->vars);
$this->setHeader(‘Content-Type: application/x-www-form-urlencoded’);
$this->setHeader(‘Content-Length: ‘. strlen($data));
}

//解析URL地址
$url = parse_url($this->uri);
$host = $url[‘host’];
$port = isset($url[‘port’]) && ($url[‘port’]!=”) ? $url[‘port’] : 80;
$path = isset($url[‘path’]) && ($url[‘path’]!=”) ? $url[‘path’] : ‘/’;
$path .= isset($url[‘query’]) ? “?”. $url[‘query’] : ”;

//组织HTTP请求头信息
array_unshift(&$this->header, $method .” “. $path .” HTTP/1.1″);
$this->setHeader(‘User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)’);
if (!preg_match(“/^[/d]{1,3}/.[/d]{1,3}/.[/d]{1,3}/.[/d]{1,3}$/”, $host)){
$this->setHeader(“Host: “.$host);
}
if ($this->cookies != ”){
$this->setHeader(“Cookie: “. $this->cookies);
}
$this->setHeader(“Connection: Close”);
//’Accept-Language: zh-cn’,
//’Cache-Control: no-cache’,

//构造请求信息
$header = ”;
foreach ($this->header as $h) {
$header .= $h .”/r/n”;
}
$header .= “/r/n”;
if ($method == ‘POST’ && $data != ”){
$header .= $data .”/r/n”;
}

//连接服务器发送请求数据
$ip = gethostbyname($host);
if (!($fp = fsockopen($ip, $port, &$errno, &$errstr, $timeout))){
throw new Exception(__CLASS__ .”: Can’t connect $host:$port, errno:$errno,message:$errstr”);
}
fputs($fp, $header);
$lineSize = 1024;

//处理301,302跳转页面访问
$line = fgets($fp, $lineSize);
$first = preg_split(“//s/”, trim($line));
if ( isset($first[1]) && in_array($first[1], array(‘301′,’302′)) ){
while (!feof($fp)) {
$line = fgets($fp, $lineSize);
$second = preg_split(“//s/”, trim($line));
if (ucfirst(trim($second[0]))==’Location:’ && $second[1]!=”){
$this->header = array();
return $this->get(trim($second[1]));
}
}
}

//正常读取返回数据
$buf = ”;
$inheader = 1;
while (!feof($fp)) {
if ($inheader && ($line == “/n” || $line == “/r/n”)) {
$inheader = 0;
}
$line = fgets($fp, $lineSize);
if ($inheader == 0) {
$buf .=$line;
}
}
fclose($fp);

return $buf;
}

}

 

 

 

/**
* 使用文件流操作函数为核心操作的HTTP访问接口
*
* @desc stream_* 和 fopen/file_get_contents 是PHP内置的一个流和文件操作接口,必须打开 fsockopen 函数本类才能工作,
* 同时确保其他相关网络环境和配置是正确的,包括 allow_url_fopen 等设置
*/
class Http_Stream
{

/**
* @var object 对象单例
*/
static $_instance = NULL;

/**
* @var string 需要发送的cookie信息
*/
private $cookies = ”;
/**
* @var array 需要发送的头信息
*/
private $header = array();
/**
* @var string 需要访问的URL地址
*/
private $uri = ”;
/**
* @var array 需要发送的数据
*/
private $vars = array();

 

/**
* 构造函数
*
* @param string $configFile 配置文件路径
*/
private function __construct($url){
$this->uri = $url;
}

/**
* 保证对象不被clone
*/
private function __clone() {}

 

/**
* 获取对象唯一实例
*
* @param string $configFile 配置文件路径
* @return object 返回本对象实例
*/
public static function getInstance($url = ”){
if (!(self::$_instance instanceof self)){
self::$_instance = new self($url);
}
return self::$_instance;
}

/**
* 设置需要发送的HTTP头信息
*
* @param array/string 需要设置的头信息,可以是一个 类似 array(‘Host: example.com’, ‘Accept-Language: zh-cn’) 的头信息数组
* 或单一的一条类似于 ‘Host: example.com’ 头信息字符串
* @return void
*/
public function setHeader($header){
if (empty($header)) {
return;
}
if (is_array($header)){
foreach ($header as $k => $v){
$this->header[] = is_numeric($k) ? trim($v) : (trim($k) .”: “. trim($v));
}
} elseif (is_string($header)){
$this->header[] = $header;
}
}

/**
* 设置Cookie头信息
*
* 注意:本函数只能调用一次,下次调用会覆盖上一次的设置
*
* @param string/array 需要设置的Cookie信息,一个类似于 ‘name1=value1&name2=value2’ 的Cookie字符串信息,
* 或者是一个 array(‘name1’=>’value1’, ‘name2’=>’value2’) 的一维数组
* @return void
*/
public function setCookie($cookie){
if (empty($cookie)) {
return;
}
if (is_array($cookie)){
$this->cookies = Http::makeQuery($cookie, ‘;’);
} elseif (is_string($cookie)){
$this->cookies = $cookie;
}
}

/**
* 设置要发送的数据信息
*
* 注意:本函数只能调用一次,下次调用会覆盖上一次的设置
*
* @param array 设置需要发送的数据信息,一个类似于 array(‘name1’=>’value1’, ‘name2’=>’value2’) 的一维数组
* @return void
*/
public function setVar($vars){
if (empty($vars)) {
return;
}
if (is_array($vars)){
$this->vars = $vars;
}
}

/**
* 设置要请求的URL地址
*
* @param string $url 需要设置的URL地址
* @return void
*/
public function setUrl($url){
if ($url != ”) {
$this->uri = $url;
}
}

/**
* 发送HTTP GET请求
*
* @param string $url 如果初始化对象的时候没有设置或者要设置不同的访问URL,可以传本参数
* @param array $vars 需要单独返送的GET变量
* @param array/string 需要设置的头信息,可以是一个 类似 array(‘Host: example.com’, ‘Accept-Language: zh-cn’) 的头信息数组
* 或单一的一条类似于 ‘Host: example.com’ 头信息字符串
* @param string/array 需要设置的Cookie信息,一个类似于 ‘name1=value1&name2=value2’ 的Cookie字符串信息,
* 或者是一个 array(‘name1’=>’value1’, ‘name2’=>’value2’) 的一维数组
* @param int $timeout 连接对方服务器访问超时时间,单位为秒
* @param array $options 当前操作类一些特殊的属性设置
* @return unknown
*/
public function get($url = ”, $vars = array(), $header = array(), $cookie = ”, $timeout = 5, $options = array()){
$this->setUrl($url);
$this->setHeader($header);
$this->setCookie($cookie);
$this->setVar($vars);
return $this->send(‘GET’, $timeout);
}

/**
* 发送HTTP POST请求
*
* @param string $url 如果初始化对象的时候没有设置或者要设置不同的访问URL,可以传本参数
* @param array $vars 需要单独返送的GET变量
* @param array/string 需要设置的头信息,可以是一个 类似 array(‘Host: example.com’, ‘Accept-Language: zh-cn’) 的头信息数组
* 或单一的一条类似于 ‘Host: example.com’ 头信息字符串
* @param string/array 需要设置的Cookie信息,一个类似于 ‘name1=value1&name2=value2’ 的Cookie字符串信息,
* 或者是一个 array(‘name1’=>’value1’, ‘name2’=>’value2’) 的一维数组
* @param int $timeout 连接对方服务器访问超时时间,单位为秒
* @param array $options 当前操作类一些特殊的属性设置
* @return unknown
*/
public function post($url = ”, $vars = array(), $header = array(), $cookie = ”, $timeout = 5, $options = array()){
$this->setUrl($url);
$this->setHeader($header);
$this->setCookie($cookie);
$this->setVar($vars);
return $this->send(‘POST’, $timeout);
}

/**
* 发送HTTP请求核心函数
*
* @param string $method 使用GET还是POST方式访问
* @param array $vars 需要另外附加发送的GET/POST数据
* @param int $timeout 连接对方服务器访问超时时间,单位为秒
* @param array $options 当前操作类一些特殊的属性设置
* @return string 返回服务器端读取的返回数据
*/
public function send($method = ‘GET’, $timeout = 5, $options = array()){
//处理参数是否为空
if ($this->uri == ”){
throw new Exception(__CLASS__ .”: Access url is empty”);
}
$parse = parse_url($this->uri);
$host = $parse[‘host’];

//处理GET请求参数
if ($method == ‘GET’ && !empty($this->vars)){
$query = Http::makeQuery($this->vars);
$sep = isset($parse[‘query’])&&($parse[‘query’]!=”) ? ‘&’ : ‘?’;
$this->uri .= $sep . $query;
}

//处理POST请求数据
$data = ”;
if ($method == ‘POST’ && !empty($this->vars)){
$data = Http::makeQuery($this->vars);
}

//设置缺省头
$this->setHeader(‘User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)’);
if (!preg_match(“/^[/d]{1,3}/.[/d]{1,3}/.[/d]{1,3}/.[/d]{1,3}$/”, $host)){
$this->setHeader(“Host: “.$host);
}
if ($this->cookies != ”){
$this->setHeader(“Cookie: “. $this->cookies);
}
$this->setHeader(“Connection: Close”);
//’Accept-Language: zh-cn’,
//’Cache-Control: no-cache’,

//构造头信息
$opts = array(
‘http’ => array(
‘method’ => $method,
‘timeout’ => $timeout,
)
);
if ($data != ”){
$opts[‘http’][‘content’] = $data;
}
$opts[‘http’][‘header’] = ”;
foreach ($this->header as $h){
$opts[‘http’][‘header’] .= $h . “/r/n”;
}
//print_r($opts);exit;

//读取扩展设置选项
if (!empty($options)){
isset($options[‘proxy’]) ? $opts[‘http’][‘proxy’] = $options[‘proxy’] : ”;
isset($options[‘max_redirects’]) ? $opts[‘http’][‘max_redirects’] = $options[‘max_redirects’] : ”;
isset($options[‘request_fulluri’]) ? $opts[‘http’][‘request_fulluri’] = $options[‘request_fulluri’] : ”;
}

//发送数据返回
$context = stream_context_create($opts);
if (($buf = file_get_contents($this->uri, null, $context)) === false){
throw new Exception(__CLASS__ .”: file_get_contents(“. $this->uri .”) fail”);
}

return $buf;

}

}

 

 

 

0.00 avg. rating (0% score) - 0 votes

windows下安装memacache及PHP扩展

一、Memcached和Memcache的区别:

网上关于Memcached和Memcache的区别的理解众说纷纭,我个人的理解是:

Memcached是一个内存缓存系统,而Memcache是php的一个扩展,是php用于操作和管理Memcached的工具。如果安装了Memcached但没有安装Memcache,php无法操控Memcached,但是可以使用命令行来操控Memcached;如果安装了Memcache却没安装Memcached,则无法使用。只有同时安装了Memcached和Memcache,才能在PHP中使用Memcached。

    以上仅代表个人观点。

    网上关于Memcached和Memcache的安装教程有很多,下面是我参考网上教程并动手操作后总结出来的方法,注意,我的操作是基于64位win7系统的。

 

二、安装memcached:

1. 下载地址:http://pan.baidu.com/s/1gdKbp8R

  (这是在网上找的下载地址,我试过,可以下载)

2. 解压下载后的文件,把它放到一个目录中,如D:\memcached。

3. 打开cmd,进入memcached解压后存放的目录,运行命令:

   memcached.exe -d install

   如果没有意外的话已经安装成功了。

   (目录中应该有memcached.exe这个文件)

4. 测试是否安装成功:

   打开cmd,进入memcached解压后存放的目录,运行命令:

   memcached -h,若安装成功,会出现如下界面:

5. 启动memcached:

  打开cmd,进入memcached解压后存放的目录,运行命令:

  memcached.exe -d start

  这时memcached已经启动,在任务管理器中可以看到这个进程:

 

6. 连接Memcached:

  打开cmd,运行命令:

  telnet 127.0.0.1 11211

  即可连接Memcached。

 

注:win7中可能会出现“telnet’不是内部或外部命令”的错误,这是因为系统中默认没有安装telnet的缘故,可在“控制面板”->“程序”->“程序和功能”->“打开或关闭Windows功能”中打开“Telnet客户端”。

三、安装memcache的php扩展:

1. 下载地址:http://windows.php.net/downloads/pecl/releases/memcache/3.0.8/

  (注意:要下载对应php版本和系统位数的dll文件)

2. 把php_memcache.dll放到php的ext目录下,如:

   D:\wamp\bin\php\php5.5.12\ext

3. 打开php.ini,在extension处添加一行代码:

   extension=php_memcache.dll

4. 重启服务器。

5. 查看php的extensions服务,php_memcache现在应该可以使用了,即处于打钩状态,之

  前是处于叹号状态的,若还处于叹号状态,用鼠标在上面点击一下就好了。

6. 通过代码测试php是否已经可以使用memcached:

  $memcache = new Memcache;

  $memcache->connect("127.0.0.1",11211);

  echo "Memcached's version: " . $memcache->getVersion() . "<br />";

  $data = array(

           'url' => "http://www.cnblogs.com/wujuntian/",

           'name' => "编程人,在天涯"

  );

  $memcache -> set("info",$data,0,10);

  $info = $memcache->get("info");

  echo '<pre>';

  print_r($info);

若能打印出memcache中的信息,则说明php的memcache扩展已安装成功且能使用了!

 

注意:运行代码时若出现错误Fatal error: Class ‘Memcache’ not found,有可能是下载的

php_memcache.dll文件与php版本不符,或者与系统位数不符。

我的是64位系统,php版本是5.5.12,下载的是php_memcache-3.0.8-5.5-ts-vc11-x64.zip

这个文件。

5.00 avg. rating (99% score) - 1 vote

[亲测]windows下apache2.4.9支持ssl

所需的环境参考上一篇文章,简单地搭建了一个Apache+PHP的服务器,这个apache是自带SSL的,
http://blog.csdn.net/wlmnzf/article/details/50229407

因为看到网上的各种教程不全还有很多错误,自己绕了好多弯最后参考了官方文档,才最终解决,所以这里综合各方大神所写的文章,改正和完善细节后再发一次。这里不得不说一下,官方文档虽然是英文的平时还特别低调,显得相当高冷,可是它却是我们最靠谱,最坚强的后盾。

1.修改两个配置文件,一个为conf/httpd.conf,另一个为conf/extra/httpd-ssl.conf

在httpd.conf中
a. 删掉以下语句前的’#’

#LoadModule ssl_module modules/mod_ssl.so
#Include conf/extra/httpd-mpm.conf 
#Include conf/extra/httpd-ssl.conf 

b. httpd-ssl.conf中把相应选项改成如下,有’#’的删掉

SSLCertificateFile "c:/Apache24/conf/server.crt"
SSLCertificateKeyFile "c:/Apache24/conf/server.key"
SSLCACertificateFile "c:/Apache24/conf/ca.crt"
SSLVerifyClient require
SSLVerifyDepth  1

继续阅读

5.00 avg. rating (99% score) - 1 vote

莱阳网服务器升级

随着网站的流量越来越大,以及图片和数据库的空间需求越来越大,原来的服务器的配置已经不能支持现在的流量也业务量,所以在本月15日对莱阳网莱阳房产网的服务器进行了升级.将原来的服务器配置进行了重大的升级,新增加了一块50GB的硬盘,将内存的空间扩容了一倍,带宽暂时没有升级,因为发现峰值的使用量还能承受得住,所以此次升级就暂时没有升级带宽.

升级大约用了2个小时的时间,升级之后服务器的性能配置比之前稳定了很多,内存的平时使用量也由原来的60%,变为现在的30%,负载维持在0.1以下.暂时以这样的配置运行一段时间应该不会有什么大的问题了.

现在服务器一直用着阿里云的服务器,性能和后台操作方面,大都没有什么太大的问题,也不用要求客服给予处理什么问题.稳定就是最大的满足.不过阿里云上的收费项目可真是不少,只有想不到没有收不到的.

5.00 avg. rating (99% score) - 1 vote

在linux下vsftpd读取目录列表失败的解决办法

搭建好ftp之后,登陆账户和密码,提示正确,但是就是列表目录失败,出现该错误是由iptables的配置引起的,临时的解决方法是执行如下命令:
[root@localhost yuweixian]# modprobe ip_nat_ftp
再次登陆列表正常啦!
但当你重新启动服务器则iptables规则失效,又会出现相同的情况,所以我们需要修改/etc/sysconfig/iptables-config文件:
[root@localhost yuweixian]# vi /etc/sysconfig/iptables-config
# Load additional iptables modules (nat helpers)
#   Default: -none-
# Space separated list of nat helpers (e.g. ‘ip_nat_ftp ip_nat_irc’), which
# are loaded after the firewall rules are applied. Options for the helpers are
# stored in /etc/modprobe.conf.
IPTABLES_MODULES=””
# Unload modules on restart and stop
#   Value: yes|no,  default: yes
# This option has to be ‘yes’ to get to a sane state for a firewall
# restart or stop. Only set to ‘no’ if there are problems unloading netfilter
# modules.
IPTABLES_MODULES_UNLOAD=”yes”
……
IPTABLES_MODULES_UNLOAD=”yes”的意义:每次iptables停止或者重启都会Unload modules
IPTABLES_MODULES=””的意义:每次防火墙规则应用以后加载的模块
我们需要把:
IPTABLES_MODULES=””
修改为:
IPTABLES_MODULES=”ip_nat_ftp”
这样重启服务器之后就不必再每次都执行mobprobe啦。
0.00 avg. rating (0% score) - 0 votes

给Linux服务增加防火墙的端口号

#/sbin/iptables -I INPUT -p tcp –dport 80 -j ACCEPT
#/sbin/iptables -I INPUT -p tcp –dport 22 -j ACCEPT
#/sbin/iptables -I INPUT -p tcp –dport 3306 -j ACCEPT
然后保存:
#/etc/rc.d/init.d/iptables save

查看打开的端口:
# /etc/init.d/iptables status

5.00 avg. rating (99% score) - 1 vote