Http 模块
CBrother提供了一个Http扩展,它可以作为服务提供http静态资源下载、动态接口编写。也可以作为http客户端请求其他服务器数据。
HttpServer 静态下载
先来看一段代码,启动一个静态的http
服务
import CBHttp.code
function main(parm)
{
var httpServer = new HttpServer();
httpServer.startServer();
while(1) //主线程不能退出
{
Sleep(1000);
}
}
服务启动好了,假设我们的项目根目录是E:\cbrotherwork\httpserver
,那么我们的服务根路径就默认是E:\cbrotherwork\httpserver\webroot
我们新建txt文件E:\cbrotherwork\httpserver\webroot\111.txt
,在文本里输入内容Hello HttpServer!
。
然后我们打开本机浏览器输入:http://127.0.0.1:8000/111.txt
,你发现你在网页上访问到了111.txt
主流的文件格式都支持下载
MIME控制
静态下载的过程中,有时需要控制可下载的文件格式,那么就要手动调配MIME
import CBHttp.code
function main(parm)
{
var httpServer = new HttpServer();
httpServer.addMIME("mystyle","text/html"); //添加后缀名为.mystyle,mime为text/html
httpServer.addMIME("c"); //添加后缀名为.c,mime类型让系统自动识别
httpServer.removeMIME("gif"); //删除gif
var mimiemap = httpServer.getMIME(); //获取目前支持的mime类型
mimiemap.begin();
do
{
print mimiemap.getKey() + ":" + mimiemap.getValue();
}
while(mimiemap.next());
httpServer.startServer();
while(1)
{
Sleep(1000);
}
}
运行结果:
rar:application/octet-stream
bmp:image/bmp
xml:application/xml
html:text/html
c:text/plain
js:application/x-javascript
txt:text/plain
ico:image/x-icon
zip:application/zip
jpg:image/jpeg
mystyle:text/html
7z:application/octet-stream
json:application/json
swf:application/x-shockwave-flash
css:text/css
png:image/png
HttpServer 动态接口
我们通常需要在用户调用一个接口时通过一些条件来返回不同的内容,下面我们再通过一段代码看一下
import CBHttp.code
class HelloAction
{
function DoAction(request,respon) //这个函数写法是固定的,request表示客户端请求信息,respon是回复给客户机的信息
{
var myTime = new Time();
respon.write("now time is:" + myTime.strftime("%Y/%m/%d %H:%M:%S"));
respon.flush();
}
}
function main(parm)
{
var httpServer = new HttpServer();
httpServer.addAction("hello.cb",new HelloAction()); //我们注册接口hello.cb,响应类是HelloAction
httpServer.startServer();
while(1) //主线程不能退出
{
Sleep(1000);
}
}
然后我们浏览器输入:http://127.0.0.1:8000/hello.cb
,每次访问返回的都是当前时间。
接口名字可以是任意字符串,官方建议用统一的后缀,方便跟其他web服务器协作。
HttpServer 接口
函数 | 描述 | 用法 |
---|---|---|
addAction(name,actobj) | 添加http 响应接口,name 为接口名字,actobj 为响应的Action 对象 | httpServer.addAction("hello.cb",actobj) |
startServer(port,listen_ip) | 启动服务
port : 监听端口,默认8000
listen_ip :监听IP,不传值默认为0.0.0.0 表示监听IPV4 所有IP
传值为字符串"::"表示监听IPV6 全部IP
传值为字符串""表示监听IPV6 与IPV4 的全部IP | httpServer.startServer(port,listen_ip) |
stopServer() | 停止服务 | httpServer.stopServer() |
setRoot(path) | 设置服务器跟目录,path : 根目录绝对路径 | httpServer.setRoot(path) |
setThreadCount(cnt) | 设置响应线程数量,默认10个 设置大了并发量大但是消耗资源多 | httpServer.setThreadCount(50) |
setNormalAction(actName) | 设置默认响应接口
访问http://x.x.x.x/ 后面不带路径时默认执行到的界面 | httpServer.setNormalAction("hello.cb")
httpServer.setNormalAction("hello.html") |
set404Action(actName) | 设置错误响应接口,不设置CBrother 有默认页面 | httpServer.set404Action("404.cb") |
setOutTime(t) | 设置请求超时时间,默认10秒,单位为秒 | httpServer.setOutTime(3) |
setMaxReqDataLen(len) | 设置客户机发送的最大请求数据长度,默认500K,参数单位为(字节) | httpServer.setMaxReqDataLen(1024 \ 1024) |
openLog() | 打开日志,在webroot平级建立log目录默认关闭,建议打开 | httpServer.openLog() |
closeFileService() | 关闭文件下载服务录 | httpServer.closeFileService() |
setHttpsCertFile(CRT_PATH,KEY_PATH) | 设置https证书
如果设置了证书,服务将为https协议,CRT_PATH : crt证书路径
key : 证书路径证书与Nginx 所需证书相同 | httpServer.setHttpsCertFile("e:/a.crt","e:/a.key") |
setWebSocketModule(name,wsmodule) | 设置websocket模块来支持websocket协议
name : 接口名字
wsmodule :websocket 模块对象 | httpServer.setWebSocketModule(name,wsmodule) |
getMIME() | 获取服务目前支持的mime 格式,返回一个map 对象,key 为扩展,value 为类型 | var map = httpServer.getMIME() |
addMIME(ext,type) | 添加mime 类型,ext : 扩展名
type :类型,type 不传值系统会自动识别 | httpServer.addMIME("txt");httpServer.addMIME("mystyle","text/plain"); |
removeMIME(ext) | 移除mime 类型,ext 为扩展名 | httpServer.removeMIME("txt"); |
除了stopServer
,其他接口都应该在startServer
之前调用。
HttpServer 响应Action类
响应类必须要有function DoAction(request,respon)
函数,如果没有会注册失败。
这个方法会被多线程调用,如果要访问公共资源需要加锁。
·request记录了客户端请求的信息
函数 | 描述 | 用法 |
---|---|---|
getUrl() | 获取请求的路径 | var url = request.getUrl() |
getProperty(name) | 获取HTTP 头里的参数 | var v = request.getProperty("Content-Type") |
getAllProperty() | 获取HTTP 头里的所有的参数,返回一个Map 对象 | var proMap = request.getAllProperty() |
getParm(name) | 获取请求链接?后面的参数,127.0.0.1?k=v&k1=1 | var v = request.getParm("k") |
getParmInt(name) | 获取请求链接?后面的参数,强转整形 | var v = request.getParmInt("k1") |
getAllParm() | 获取请求链接?后面的所有参数,返回一个Map 对象 | var parmMap = request.getAllParm() |
getData() | 获取请求post 的数据 | var data = request.getData() |
getRemoteIP() | 获取客户机IP | var ip = request.getRemoteIP() |
getMethod() | 获取请求类型,"GET" 或"POST" | var method = request.getMethod() |
getCookieCount() | 获取cookie 数量 | var cnt = request.getCookieCount() |
getCookie(index) | 根据索引获取cookie ,返回cookie 对象 | var cookie = request.getCookie(0) |
getCookie(cookieName) | 根据名字获取cookie ,如果有重名的cookie 返回第一个 | var cookie = request.getCookie("userName") |
getFormData() | 获取form 表单数据,当客户端以form 表单格式提交才返回FormData 对象,否则返回null | var formdata = request.getFormData() |
isKeepAlive() | 客户端请求是否为保持连接状态,true 为保持连接,false 为立即关闭 | var isKeep = request.isKeepAlive() |
isHttps() | 客户端请求是否为https ,true 为https ,false 为http | var isKeep = request.isHttps() |
·respon是返回给客户端的信息
函数 | 描述 | 用法 |
---|---|---|
addProperty(key,value) | 添加http 头数据,必须为字符串 | respon.addProperty("Access-Control-Allow-Origin","*") |
addCookie(cookie) | 添加cookie | respon.addCookie(new Cookie("aaa","bbb")) |
setStatus(status) | 设置返回http 状态 | respon.setStatus(200) |
write(data) | 写入要返回数据 | respon.write("hello") |
flush() | 发送数据 | respon.flush() |
Cookie 类
在日常开发中,服务器需要通过cookie
来判别客户机身份,CBrother
提供了Cookie
类来描述http
头中的Set-Cookie
与Cookie
字段
函数 | 描述 | 用法 |
---|---|---|
setName(name) | 设置cookie 的名称 | myCookie.setName("aaa") |
setValue(v,pwd) | 设置cookie 的字段,pwd不传为明文,传入密码会增加一个签名 | myCookie.setValue("bbb")myCookie.setValue("bbb","pwdstr") |
getName() | 获取cookie 的名称 | var name = myCookie.getName() |
getValue(pwd) | 获取cookie 的字段,pwd 不传返回原文,传入密码会检查签名 | var cookie = myCookie.getValue()var cookie = myCookie.setValue("pwdstr") |
setPath(path) | 设置cookie 的有效路径,不设置默认为'/' | myCookie.setPath("/aa/cc/") |
setDomain(domain) | 设置cookie 的域,默认为空 | myCookie.setDomain("cbrother.net") |
setExpires(timeSeconds) | 设置cookie 有效时间,单位为秒,设置为0表示删除cookie ,默认浏览器关闭失效 | myCookie.setExpires(300) |
setHttpOnly(boolValue) | cookie 的HttpOnly 标签,默认false | myCookie.setHttpOnly(true) |
getPath() | 获取cookie 的有效路径 | var path = myCookie.getPath() |
getDomain() | 获取cookie 的域 | var domain = myCookie.getDomain() |
getExpires() | 获取cookie 有效时间 | var t = myCookie.getExpires() |
getHttpOnly() | 获取cookie 的HttpOnly 标签 | var httponly = myCookie.getHttpOnly() |
其中带密码的setValue
方法会用密码和原始明文算一个md5
值作为cookie
签名,这样保证了cookie
不可被伪造,一般可以用于登陆状态验证。当然,在一些安全性要求比较高的场景,开发者也可以自己实现安全级别更高的cookie
加密验证方式。
通过一个段代码来学习一下Cookie
的用法:
class CookieAction
{
function DoAction(request,respon)
{
var cookieCnt = request.getCookieCount(); //获取客户机Cookie数量
if(cookieCnt > 0)
{
for(var i = 0 ; i < cookieCnt ; i++) //遍历的方式可以获取所有的Cookie,包括名字相同的Cookie
{
//客户机已经有cookie
var cookie = request.getCookie(i);
if(cookie.getName() == "pwdCookie")
{
print cookie.getValue();
print cookie.getValue("pwd222"); //带密码的cookie
}
else
{
print cookie.getValue(); //明文cookie
}
}
var pwdCookie request.getCookie("pwdCookie"); //根据名字获取Cookie,如果有同名Cookie则只返回第一个
print pwdCookie.getValue("pwd222");
}
else
{
//客户机没有cookie
var cookie = new Cookie("normalCookie","3333");
respon.addCookie(cookie); //添加明文cookie
cookie = new Cookie();
cookie.setName("pwdCookie");
cookie.setValue("3333","pwd222");
respon.addCookie(cookie); //添加带密码的cookie
}
var myTime = new Time();
respon.write("now time is:" + myTime.strftime("%Y/%m/%d %H:%M:%S"));
respon.flush();
}
}
表单FormData 类
CBrother提供了FormData类来描述form表单数据
函数 | 描述 | 用法 |
---|---|---|
getType() | 获取表单enctype 类型,FORM_WWW_URLENCODED 表示application/x-www-form-urlencoded ,FORM_MULTI_PART 表示multipart/form-data 。在lib/htppdef 里定义 | var t = form.getType() |
getTextCnt() | 获取type 不为"file" 的input 数量 | var cnt = form.getTextCnt() |
getText(index) | 根据坐标获取input 的value ,type 为file 获取不到 | var value = form.getText(0) |
getText(name) | 根据name 获取input 的value ,type 为file 获取不到 | var value = form.getText("txt1") |
getTextName(index) | 根据坐标获取input 的name ,type 为file 获取不到 | var name = form.getTextName(0) |
getMultiPartCnt() | 当form 的enctype 为FORM_MULTI_PART 时候,获取input 数量 | var cnt = form.getMultiPartCnt() |
getMultiPart(index) | 根据坐标获取input 数据,返回Multipart 对象 | var data = form.getMultiPart(0) |
getMultiPart(name) | 根据name 获取input 数据,返回Multipart 对象 | var data = form.getMultiPart("file") |
addText(name,str) | 添加一个文本类型的input 数据,name 为名称,str 为内容.根HttpClientRequest 向其他服务器发起请求的时候使用 | form.addText("111","111") |
addFile(name,filename,data,mime) | 添加一个文件类型的input 数据,name 为名称,filename 为文件名,data 为文件内容string 或ByteArray 对象,mime 为文件mime 类型,不传值会自动识别 | form.addFile("file1","222.txt","222") |
比如web前端提交的form表单结构如下:
<form method="post" action="form.cb" >
<input type="text" name="txt1">
<input type="text" name="txt2">
<input type="password" name="userpass"
<input type="radio" name="sex" value="man" checked>man
<input type="radio" name="sex" value="woman">woman
<input type="file" name="file" value="hiddenvalue" multiple="multiple"/>
<input type="submit" value="提交(提交按钮)">
</form>
网页展示效果如下:
因为这个表单没有指定enctype
,所以Content-Type
为application/x-www-form-urlencoded
,我们日常使用到的大部分表单都是这种格式。当前端post
提交后服务器使用如下方式获取表单数据
class FormAction
{
function DoAction(request,respon)
{
print request.getData(); //打印发送的数据
print "**********************分割线*******************************";
var formdata = request.getFormData();
if(formdata == null)
{
return; //只有Content-Type为application/x-www-form-urlencoded或者multipart/form-data时候才会返回FormData对象,否则返回null
}
var type = formdata.getType();
if(type == FORM_WWW_URLENCODED) //Content-Type为application/x-www-form-urlencoded类型的表单
{
var textCnt = formdata.getTextCnt();
for(var i = 0 ; i < textCnt ; i++)
{
print formdata.getTextName(i) + ":" + formdata.getText(i);
}
}
}
}
服务器输出结果:
txt1=111&txt2=222&userpass=333&sex=man&file=111.txt
**********************分割线*******************************
txt1:111
txt2:222
userpass:333
sex:man
file:111.txt
Multipart 类
这里需要学习一下form添加enctype=multipart/form-data时提交的报文格式
Multipart类来描述form表单在multipart/form-data数据类型下的一个input数据,这个类型的表单一般用在上传文件
函数 | 描述 | 用法 |
---|---|---|
getParm(name) | 获取Multipart 段落内的参数 | var parm = mulpart.getParm("name") |
getData(isByte) | 获取Multipart 的数据,isByte 不传值,默认返回字符串,传true 返回ByteArray 对象 | var data = mulpart.getData()var bytearry = mulpart.getData(true) |
getDataLen() | 获取数据长度 | var len = mulpart.getDataLen() |
isFile() | 如果是文件类型,返回true | var isfile = mulpart.isFile() |
getFileCount() | 获取这个input 上传了几个文件 | var cnt = mulpart.getFileCount() |
getFile(index) | 获取文件对应数据,返回一个Multipart 对象 | var filedata = mulpart.getFile(0) |
比如web前端提交的form表单结构如下:(只是添加了一个enctype="multipart/form-data"
)
<form method="post" action="form.cb" enctype="multipart/form-data">
<input type="text" name="txt1">
<input type="text" name="txt2">
<input type="password" name="userpass"
<input type="radio" name="sex" value="man" checked>man
<input type="radio" name="sex" value="woman">woman
<input type="file" name="file" value="hiddenvalue" multiple="multiple"/>
<input type="submit" value="提交(提交按钮)">
</form>
网页展示效果没有变化如下:
添加了enctype
,Content-Type
变成multipart/form-data
,服务器使用如下方式获取表单数据
class FormAction
{
function DoAction(request,respon)
{
print request.getData(); //打印发送的数据
print "**********************分割线*******************************";
var formdata = request.getFormData();
if(formdata == null)
{
return; //只有Content-Type为application/x-www-form-urlencoded或者multipart/form-data时候才会返回FormData对象,否则返回null
}
var type = formdata.getType();
if(type == FORM_MULTI_PART) //Content-Type为multipart/form-data类型的表单
{
var formcnt = formdata.getMultiPartCnt();
for(var i = 0 ; i < formcnt ; i++)
{
var muldata = formdata.getMultiPart(i);
if(muldata.isFile()) //如果是上传的文件
{
for(var j = 0 ; j < muldata.getFileCount() ; j++)
{
//上传的文件可以在这里通过File对象把数据保存到文件里,CBrother目录下sample/http/httpserver_form.cb里面有例子,这里只是把数据打印出来
var filedata = muldata.getFile(j);
print filedata.getParm("name") + " " + filedata.getParm("filename") + ": size=" + filedata.getDataLen() + " value=" + filedata.getData();
}
}
else
{
print muldata.getParm("name") + ":" + muldata.getData();
}
}
}
}
}
服务器运行结果如下:
------WebKitFormBoundaryw7KfcBx8f23zh8d4
Content-Disposition: form-data; name="txt1"
111
------WebKitFormBoundaryw7KfcBx8f23zh8d4
Content-Disposition: form-data; name="txt2"
222
------WebKitFormBoundaryw7KfcBx8f23zh8d4
Content-Disposition: form-data; name="userpass"
------WebKitFormBoundaryw7KfcBx8f23zh8d4
Content-Disposition: form-data; name="sex"
man
------WebKitFormBoundaryw7KfcBx8f23zh8d4
Content-Disposition: form-data; name="file"; filename="111.txt"
Content-Type: text/plain
i'am 111.txt file value!
------WebKitFormBoundaryw7KfcBx8f23zh8d4--
**********************分割线*******************************
txt1:111
txt2:222
userpass:
sex:man
file 111.txt: size=24 value=i'am 111.txt file value!
HttpClientRequest 主动发起请求
在开发过程中,我们经常会遇到与第三方服务器通信,这时候就需要主动请求第三方服务器接口,CBrother
提供了HttpClientRequest
来主动访问别人提供的http
和https
接口
var myReq = new HttpClientRequest();
函数 | 描述 | 用法 |
---|---|---|
setMethod(method) | 设置请求方式,"GET" 或者"POST" ,类型字符串 | myReq.setMethod("POST") |
setUrl(url) | 设置请求地址,参数地址全路径 | myReq.setUrl("http://127.0.0.1/hello.cb")myReq.setUrl("https://www.baidu.com") |
addProperty(key,value) | 添加http 头,必须都为字符串 | myReq.addProperty("HOST","127.0.0.1") |
addParm(key,value) | 在链接上添加参数,必须都为字符串。会在链接地址后面追加?k1=v1&k2=v2 | myReq.addParm("11","121") |
addData(data) | 添加要提交的数据,data 为要提交的数据,必须都为字符串 | myReq.addData("11221122") |
flush() | 发起请求,返回HttpClientResponse 对象 | var response = myReq.flush() |
setKeepAlive(isKeep) | 设置是否保持与服务器连接,不设置默认false 不保持 | myReq.setKeepAlive(true) |
reset() | 还原成一个新的请求对象,仅保留网络连接。开启keepalive 以此来复用网络 | myReq.reset() |
close() | 如果开启了keepalive ,则主动关闭与服务器链接,不开启没意义 | myReq.close() |
addFormData(enctype) | 本次请求添加form 表单数据
enctype 为FORM_WWW_URLENCODED 或者FORM_MULTI_PART ,定义在lib/httpdef 里,
返回FormDatad 对象 | var formdata = myReq.addFormData(FORM_WWW_URLENCODED)var formdata = myReq.addFormData(FORM_MULTI_PART) |
addCookie(cookie) | 添加一个cookie | myReq.addCookie(new Cookie("aaa","bbb")) |
getCookieCount() | 获取添加cookie 数量 | var cnt = myReq.getCookieCount() |
getCookie(index) | 根据索引获取cookie | var cookie = myReq.getCookie(index) |
getCookie(cookieName) | 根据名字获取cookie | var cookie = myReq.getCookie("cookieName") |
HttpClientResponse为主动请求后返回的结果,HttpClientRequest的flush方法会返回一个HttpClientResponse对象
var myReq = new HttpClientRequest();
myReq.setMethod("GET");
myReq.setUrl("https://www.baidu.com");
var myResponse = myReq.flush();
函数 | 描述 | 用法 |
---|---|---|
getStatus() | 获取状态码 | var staus = myResponse.getStatus() |
getProperty(name) | 获取HTTP 头里的参数,返回值为字符串 | var v = myResponse.getProperty("Content-Type") |
getAllProperty() | 获取HTTP 头里的所有的参数,返回一个Map 对象 | var proMap = myResponse.getAllProperty() |
getData() | 获取返回的数据 | var data = myResponse.getData() |
getCookieCount() | 获取cookie 数量 | var cnt = myResponse.getCookieCount() |
getCookie(index) | 根据索引获取cookie 对象 | var cookie = myResponse.getCookie(0) |
getCookie(cookieName) | 根据名字获取cookie 对象 | var cookie = myResponse.getCookie("cookieName") |
例子:
import CBHttp.code
function main(parm)
{
var myReq = new HttpClientRequest();
myReq.setMethod("GET");
myReq.setUrl("https://www.baidu.com");
var myRes = myReq.flush();
print myRes.getStatus();
print myRes.getData();
}
结果:
200
<html>
<head>
<script>
location.replace(location.href.replace("https://","http://"));
</script>
</head>
<body>
<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>
在开发过程中,为了降低服务器压力,经常需要用到keepalive来保持连接多次请求,看下面的例子:
import CBHttp.code
import lib/httpdef
function main(parm)
{
var myReq = new HttpClientRequest();
myReq.setMethod(HTTP_GET);
myReq.setUrl("http://www.cbrother.net");
myReq.setKeepAlive(true); //开启keepalive,如果没有这一句默认是请求完毕后自动关闭连接
var myRes = myReq.flush();
print myRes.getStatus();
print myRes.getData();
myReq.reset(); //重置请求对象,仅保留网络连接,如果因为超时连接被服务器主动关闭,那么第二次请求会重新创建连接
myReq.setMethod(HTTP_GET);
myReq.setUrl("http://www.cbrother.net/doc.html");
var myRes = myReq.flush(); //第二次请求没有开启keepalive,所以这句执行完后连接就会关闭了
print myRes.getStatus();
print myRes.getData();
}
客户端使用Cookie例子:
function main(parm)
{
var myReq = new HttpClientRequest();
myReq.setMethod("GET");
myReq.setUrl("https://www.baidu.com");
myReq.addCookie(new Cookie("aaa","bbb")); //本次请求添加cookie
var myRes = myReq.flush();
var cookieCnt = myRes.getCookieCount(); //服务器返回的cookie信息
for(var i = 0 ; i < cookieCnt ; i++)
{
var cookie = request.getCookie(i);
print cookie.getName();
print cookie.getValue();
}
}
客户端模拟form表单的例子:
import lib/httpdef
function main(parm)
{
var clientReq = new HttpClientRequest();
clientReq.setMethod(HTTP_POST);
clientReq.setUrl("http://127.0.0.1:8003/form.cb");
var formdata = clientReq.addFormData(FORM_MULTI_PART); //也可以用FORM_WWW_URLENCODED,FORM_WWW_URLENCODED类型不支持上传文件
formdata.addText("111","111");
formdata.addText("222","222");
formdata.addFile("file","111.txt","222");
formdata.addFile("file","222.txt","34567");
clientReq.flush();
}
HttpServer同一个端口支持多个不同内容的网站
如果需要在一台服务上同时布置多个网站,则需要在调用HttpServer
下面几个接口时第二个参数传入网站的域名即可
函数 | 描述 | 用法 |
---|---|---|
setRoot(path,domain) | 设置域名跟目录 | httpServer.setRoot(path,"www.cbrother.net") |
setNormalAction(actName,domain) | 设置域名默认响应接口 | httpServer.setNormalAction("hello.cb","www.cbrother.net") |
set404Action(actName,domain) | 设置域名错误界面接口,不设置有默认页面 | httpServer.set404Action("404.cb","www.cbrother.net") |
setHttpsCertFile(CRT_PATH,KEY_PATH,domain) | 设置https 证书,如果设置了证书,该域名才可支持https 协议 | httpServer.setHttpsCertFile("e:/a.crt","e:/a.key","www.cbrother.net") |
比如同一台服务器支持了www.a.com
,www.b.com
,www.c.com
3个域名的网站
function main(parm)
{
var httpServer = new HttpServer();
httpServer.setRoot("c:/web" ); //设置服务器默认根目录为c:/web
httpServer.addAction("hello.cb",new HelloAction());
httpServer.addAction("404.cb",new My404Action());
httpServer.setNormalAction("hello.cb"); //设置服务器默认响应为hello.cb
httpServer.set404Action("404.cb"); //设置服务器默认404页面
httpServer.addAction("a_hello.cb",new A_HelloAction());
httpServer.setRoot("c:/webA","www.a.com"); //www.a.com网站根目录变化为c:/webA, www.b.com与www.c.com根目录依旧为c:/web
httpServer.setNormalAction("a_hello.cb","www.a.com"); //www.a.com网站默认页面变化为a_hello.cb, www.b.com与www.c.com默认页依旧为hello.cb
//www.a.com,www.b.com,ww.c.com都没有设置404页面,所以都默认执行404.cb
httpServer.startServer(80); //启动http服务
//---------------------------再启动一个https服务,代码复制一遍,添加证书接口和端口
var httpServerHttps = new HttpServer();
httpServerHttps.setRoot("c:/web");
httpServerHttps.addAction("hello.cb",new HelloAction());
httpServerHttps.addAction("404.cb",new My404Action());
httpServerHttps.setNormalAction("hello.cb");
httpServerHttps.set404Action("404.cb");
httpServerHttps.setHttpsCertFile("e:/normal.crt","e:/normal.key"); //设置https服务默认证书
httpServerHttps.addAction("a_hello.cb",new A_HelloAction());
httpServerHttps.setRoot("c:/webA","www.a.com");
httpServerHttps.setNormalAction("a_hello.cb","www.a.com");
httpServerHttps.setHttpsCertFile("e:/AAA.crt","e:/AAA.key","www.a.com"); //www.a.com证书使用e:/AAA.crt和e:/AAA.key,www.b.com与www.c.com依旧使用默认证书e:/normal.crt和e:/normal.key
httpServer.startServer(443); //启动https服务
//-----------------------------https结束
while(1)
{
Sleep(1000);
}
}
如此便实现了同服务器同端口支持多个网站并且同时支持http
与https
协议