跳转至

httpd_plugin

TSL语言的跨平台实现的内建HTTP服务器插件。

安装

(已集成到mytsl发行版中)

动态库文件:Windows: httpd_plugin.dll 或者 Linux: libhttpd_plugin.so,把动态库文件拷贝TSL目录的plugin目录。

使用指南

提供的TSL函数:

httpd_create

httpd_create(port, [address], [doc_root]): 创建HTTP服务器。

  • 参数列表

    参数 描述
    port 侦听的端口,整数类型
    address 侦听地址,可选参数
    doc_root 静态文件根目录,可选参数。如果请求的URL最后是'/',会返回对应目录的index.html文件。
  • 返回值

    HTTP服务器句柄。

  • 例子

httpd := httpd_create(8000,"0.0.0.0","d:/temp");

httpd_destroy

httpd_destroy(handle): 销毁HTTP服务器。

  • 参数列表

    参数 描述
    handle HTTP服务器句柄
  • 返回值 无

  • 例子

httpd := httpd_create(8000,"0.0.0.0","d:/temp");
httpd_destroy(httpd);

httpd_config_ssl

httpd_config_ssl(handle, cert_file, private_key_file, [password]): 设置https相关的证书,配置了将会启用https。

  • 参数列表

    参数 描述
    handle HTTP服务器句柄
    cert_file 证书文件名
    private_key_file 私钥文件名
    password 私钥的密码,可选参数
  • 返回值

  • 例子

httpd_config_ssl(h, "test.crt", "test.key");

httpd_route

httpd_route(handle, pattern, func):注册URL路由,根据模式匹配调用相应处理函数。

  • 参数列表

    参数 描述
    handle HTTP服务器句柄
    pattern 模式
    func 函数名
  • 返回值

    数组类型,如果发生错误:

    下标
    0 错误代码
    1 错误信息

    没有错误:

    下标
    0 0
    1
  • 例子

httpd_route(httpd, "foo/<int:pk>/", "foo");
httpd_route(httpd, "data/<str:stock>/<int:date>/", "get_stock_data");

模式说明

  • 用尖括号从URL中提取值。
  • 捕获的值可以选择性地包含转换器类型。比如,使用 <int:name> 来捕获整型参数。如果没有指定转换器,则会匹配除了 / 外的任何字符。
  • 开头不需要添加反斜杠,因为每个URL都有。比如,应该是 articles 而不是 /articles

转换器说明

  • str - 匹配除了 '/' 之外的非空字符串。如果表达式内不包含转换器,则会默认匹配字符串。
  • int - 匹配 0 或任何正整数。返回一个 int
  • slug - 匹配任意由 ASCII 字母或数字以及连字符和下划线组成的短标签。
  • uuid - 匹配一个格式化的 UUID 。为了防止多个URL映射到同一个页面,必须包含破折号并且字符都为小写。
  • path - 匹配非空字段,包括路径分隔符 '/' 。它允许你匹配完整的 URL 路径而不是像 str 那样匹配URL的一部分。

请求处理函数说明

  • 函数的第一个参数是HttpRequest对象,接下来的参数按捕获的值的顺序传递。
  • 例子
function foo(request, pk);
begin
    println("pk={}",pk);
    return new httpresponse(200, "ok");
end;

httpd_middleware

httpd_middleware(handle, request_func, response_func): 注册中间件,可以对请求和回应进行额外处理。

  • 参数列表

    参数 描述
    handle HTTP服务器句柄
    request_func 处理请求的函数名。函数第一个参数request。如果返回NIL会继续处理,可以修改request添加需要的信息。如果返回任何其他内容都会中止处理,返回给用户。
    response_func 处理回应的函数名。函数第一个参数request, 第二个参数是response。可以修改response。
  • 返回值

    数组类型,如果发生错误:

    下标
    0 错误代码
    1 错误信息

    没有错误:

    下标
    0 0
    1
  • 例子

httpd_middleware(httpd, 'session_process_request', 'session_process_response');
httpd_middleware(httpd, 'cache_process_request', 'cache_process_response');

function session_process_request(request);
begin
    // check user login and set sesssion...
    request.session_id := "user1";

    // 如果返回HttpResponse,将会终止后续处理,立即返回给用户
    //     例如如果用户没登录,重定向到登录页面
    // 返回不是NIL的都会中止后续处理
    return nil;
end;

function session_process_response(request, response);
begin
    // 可以修改response
    response.set("X-MYTAG", "Hello!");
    // 也可以做一些其他处理,例如缓存,清理...
end;

httpd_run_forever

httpd_run_forever(handle, threads): 运行HTTPD服务器。

  • 参数列表

    参数 描述
    handle HTTP服务器句柄
    threads 线程数,整数类型,可选参数,默认是1,也就是单线程。
  • 返回值

    数组类型,如果发生错误:

    下标
    0 错误代码
    1 错误信息

    没有错误:

    下标
    0 0
    1
  • 例子

httpd := httpd_create(8000,"0.0.0.0","d:/temp");
httpd_run_forever(httpd);

关于多线程的说明

  • 多线程模式可以同时处理多个请求,在有大量高并发请求的场景下会相当有用。
  • 对请求处理函数的调用都是独立的,没办法共享变量。
  • TODO 提供变量的共享机制。

httpd_shutdown

httpd_shutdown(handle): 关闭HTTPD服务器。

  • 参数列表

    参数 描述
    handle HTTP服务器句柄
  • 返回值

    数组类型,如果发生错误:

    下标
    0 错误代码
    1 错误信息

    没有错误:

    下标
    0 0
    1

httpd_wss

httpd_wss(handle, func1, func2, func3): 启用websocket服务。

  • 参数列表

    参数 描述
    handle HTTP服务器句柄
    func1 websocket消息处理方法
    func2 新增websocket连接处理方法
    func3 websocket连接断开处理方法
  • 返回值

    数组类型,如果发生错误:

    下标
    0 错误代码
    1 错误信息

    没有错误:

    下标
    0 0
    1
  • 例子

h := httpd_create(8000,"0.0.0.0","d:/temp");

// 配置websocket支持
httpd_wss(h, "wss", "wss_join", "wss_leave");

// 同时还可以处理正常的请求
httpd_route(h, "foo/<int:pk>/", "foo");
httpd_run_forever(h);
httpd_destroy(h);

// 收到websocket消息的处理方法
function wss(session, msg)
begin
    println("msg={}", msg);
    return exportjsonstring(array("msg":msg)); // 返回的消息将会发送出去
end;

// 新增websocket连接处理方法
function wss_join(session, msg)
begin
    println("{} join", session);
    return exportjsonstring(array("msg":"Welcome!"));
end;

// 断开websocket连接处理方法
function wss_leave(session, msg)
begin
    println("{} leave", session);
end;

function foo(request, pk);
begin
    println("pk={}",pk);
      return new httpresponse(200, fmt("Hello, {}!", pk));
end;

如何编写处理请求的函数

第一个参数是HttpRequest对象,可以通过这个对象获得相关请求的信息。必须返回HttpResponse对象。

HttpRequest对象

属性

属性名 说明
scheme 请求协议的字符串(通常是 http 或 https)。
body 原始的 HTTP 请求体。
path URL。
method 请求中使用的 HTTP 方法的字符串。例如‘GET’。
encoding 编码的字符串。
content_type 请求的 MIME 类型。
headers 请求头,数组类型。
cookies cookie列表,数组类型
自定义属性 允许用户设置任何自定义的属性。

方法

方法名 说明 返回值
search_params() URL中的查询参数。 数组类型,例如array('name1':array('value1'))。
form_data() 返回表单的内容,只适用POST请求。 数组类型,例如array('name1' : array('value' : array('1'), 'filename' : ... ), ...)。以变量名作为下标,value是数组类型,因为表单可以有多重选项。如果是上传文件,才会有filename这个字段。例如array('name1' : array('filename' : 'a.zip', 'value' : array('PK\x0...))), ...)。

HttpResponse对象

属性

属性名 说明
status HTTP状态码,默认是200。
content 内容。
content_type MIME 类型,默认是'text/html'。
headers 头。

方法

方法名 说明 返回值
set(field, value) 设置字段,参数field是字段名,value是值,都是字符串类型。例如,res.set("Server", "MyHTTPServer")。支持的字段名参见附录。 无返回值
set_cookie(value) 设置cookie,参数是字符串类型,如"name=value" 无返回值

派生类

用户可以通过继承HttqResponse类来实现自定义的Response,例如HttpResponseRedirect来重定向,JsonResponse来返回Json格式的数据。

范例

httpd := httpd_create(8000,"0.0.0.0","d:/temp");
httpd_route(httpd, "foo/<int:pk>/", "foo");
httpd_run_forever(httpd);
httpd_destroy(httpd);

function foo(request, pk);
begin
    println("pk={}",pk);
    println("headers={}", request.headers);
    if request.method() = 'POST' then
        println("form={}", request.form_data());
    return new HttpResponse(200, "ok");
end;

用浏览器访问地址 http://127.0.0.1:8000/foo/1/ ,浏览器会显示ok。

如何从mod_tsl移植应用

  • <?tslx>可以赋值给变量
  • echo->var

例子:

function myApp(request, name);
begin
    s := <?tslx>Hello, <?=name?>!<br></?tslx>;
    for x in array(1,2,3).iter() do
        echo->s '<br>', 'x=', x, '<br>'; 
    return new HttpResponse(200, s);
end;

附录

Response可以设置的字段

字段名 说明 例子 状态
Access-Control-Allow-Origin 指定哪些网站可参与到跨来源资源共享过程中 Access-Control-Allow-Origin: * 临时
Accept-Patch 指定服务器支持的文件格式类型。 Accept-Patch: text/example;charset=utf-8 常设
Accept-Ranges 这个服务器支持哪些种类的部分内容范围 Accept-Ranges: bytes 常设
Age 这个对象在代理缓存中存在的时间,以秒为单位 Age: 12 常设
Allow 对于特定资源有效的动作。针对HTTP/405这一错误代码而使用 Allow: GET, HEAD 常设
Cache-Control 向从服务器直到客户端在内的所有缓存机制告知,它们是否可以缓存这个对象。其单位为秒 Cache-Control: max-age=3600 常设
Connection 针对该连接所预期的选项 Connection: close 常设
Content-Disposition 一个可以让客户端下载文件并建议文件名的头部。文件名需要用双引号包裹。 Content-Disposition: attachment; filename="fname.ext" 常设
Content-Encoding 在数据上使用的编码类型。参考 超文本传输协议压缩 。 Content-Encoding: gzip 常设
Content-Language 内容所使用的语言 Content-Language: da 常设
Content-Length 回应消息体的长度,以 字节 (8位为一字节)为单位 Content-Length: 348 常设
Content-Location 所返回的数据的一个候选位置 Content-Location: /index.htm 常设
Content-MD5 回应内容的二进制 MD5 散列,以 Base64 方式编码 Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ== 过时的
Content-Range 这条部分消息是属于某条完整消息的哪个部分 Content-Range: bytes 21010-47021/47022 常设
Content-Type 当前内容的类型 Content-Type: text/html; charset=utf-8 常设
Date 此条消息被发送时的日期和时间(按照 RFC 7231 中定义的“超文本传输协议日期”格式来表示) Date: Tue, 15 Nov 1994 08:12:31 GMT 常设
ETag 对于某个资源的某个特定版本的一个标识符,通常是一个 消息散列 ETag: "737060cd8c284d8af7ad3082f209582d" 常设
Expires 指定一个日期/时间,超过该时间则认为此回应已经过期 Expires: Thu, 01 Dec 1994 16:00:00 GMT 常设: 标准
Last-Modified 所请求的对象的最后修改日期(按照 RFC 7231 中定义的“超文本传输协议日期”格式来表示) Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT 常设
Link 用来表达与另一个资源之间的类型关系,此处所说的类型关系是在 RFC 5988 中定义的 常设
Location 用来 进行重定向,或者在创建了某个新资源时使用。 Location: http://www.w3.org/pub/WWW/People.html 常设
P3P 用于支持设置策略,标准格式为“P3P:CP="your_compact_policy"”。然而P3P规范并不成功,大部分现代浏览器没有完整实现该功能,而大量网站也将该值设为假值,从而足以用来欺骗浏览器的P3P插件功能并授权给第三方Cookies。 P3P: CP="This is not a P3P policy! ``See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info." 常设
Pragma 与具体的实现相关,这些字段可能在请求/回应链中的任何时候产生多种效果。 Pragma: no-cache 常设
Proxy-Authenticate 要求在访问代理时提供身份认证信息。 Proxy-Authenticate: Basic 常设
Public-Key-Pins 用于缓解,声明网站认证使用的证书的散列值 Public-Key-Pins: max-age=2592000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; 常设
Refresh 用于设定可定时的重定向跳转。右边例子设定了5秒后跳转至“http://www.w3.org/pub/WWW/People.html”。 Refresh: 5; url=http://www.w3.org/pub/WWW/People.html 专利并非标准Netscape实现的扩展,但大部分网页浏览器也支持。
Retry-After 如果某个实体临时不可用,则,此协议头用来告知客户端日后重试。其值可以是一个特定的时间段(以秒为单位)或一个超文本传输协议日期。 Example 1: Retry-After: 120Example 2: Retry-After: Fri, 07 Nov 2014 23:59:59 GMT 常设
Server 服务器的名字 Server: Apache/2.4.1 (Unix) 常设
Set-Cookie Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 常设: 标准
Status 通用网关接口 协议头字段,用来说明当前这个超文本传输协议回应的 状态 。普通的超文本传输协议回应,会使用单独的“状态行”("Status-Line")作为替代,这一点是在 RFC 7230 中定义的。 Status: 200 OK Not listed as a
Strict-Transport-Security HTTP 严格传输安全这一头部告知客户端缓存这一强制 HTTPS 策略的时间,以及这一策略是否适用于其子域名。 Strict-Transport-Security: max-age=16070400; includeSubDomains 常设: 标准
Trailer 这个头部数值指示了在这一系列头部信息由由编码。 Trailer: Max-Forwards 常设
Transfer-Encoding 用来将实体安全地传输给用户的编码形式。当前定义的方法包括:分块(chunked)、compress、deflate、gzip和identity。 Transfer-Encoding: chunked 常设
Upgrade 要求客户端升级到另一个协议。 Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 常设
Vary 告知下游的代理服务器,应当如何对未来的请求协议头进行匹配,以决定是否可使用已缓存的回应内容而不是重新从原始服务器请求新的内容。 Vary: * 常设
Via 告知代理服务器的客户端,当前回应是通过什么途径发送的。 Via: 1.0 fred, 1.1 example.com (Apache/1.1) 常设
Warning 一般性的警告,告知在实体内容体中可能存在错误。 Warning: 199 Miscellaneous warning 常设
WWW-Authenticate 表明在请求获取这个实体时应当使用的认证模式。 WWW-Authenticate: Basic 常设
X-Frame-Options 保护:deny:该页面不允许在 frame 中展示,即使是同域名内。sameorigin:该页面允许同域名内在 frame 中展示。allow-from *uri*:该页面允许在指定uri的 frame 中展示。allowall:允许任意位置的frame显示,非标准值。 X-Frame-Options: deny 过时的

更多请参见HTTP标准。