http_server
简介
组件接口
http_server.gs
函数原型 | 函数作用 |
---|---|
object create_server(int port, object router, map ssl_context = nil) | 创建服务器实例 |
request.gs
HTTP请求
函数原型 | 函数作用 |
---|---|
string get_header(Request self, string field) | 返回指定的HTTP请求头部字段,匹配不考虑大小写 |
object get_session(Request self, bool create_if_not_exists = false) | 取得会话 |
array _push_parse(Request self, buffer buf) | 流式解析 |
response.gs
响应对象
router.gs
路由器
函数原型 | 函数作用 |
---|---|
void add_route(string method, string path, function handler) | 添加路由 |
mixed resolve(string path, string method = nil) | 路由解析 |
bool fixup() | 冻结路由器 |
server.gs
函数原型 | 函数作用 |
---|---|
int get_port() | 获取监听端口号 |
void serve() | 启动服务器,监听指定端口 |
void add_filter(object filter) | 添加过滤器 |
void set_static_dir(string static_dir) | 设置静态资源根目录 |
void set_max_header_size(int max_header_size) | 设置头部长度限值 |
void enable_debug(bool enable) | 启用调试信息 |
utility.gs
实用函数
函数原型 | 函数作用 |
---|---|
string urlencode(string str) | URL编码(rfc1738) |
string urldecode(string str) | URL解码 |
枚举
HttpMethod
HTTP_DELETE,
HTTP_GET,
HTTP_HEAD,
HTTP_POST,
HTTP_PUT,
/* pathological */
HTTP_CONNECT,
HTTP_OPTIONS,
HTTP_TRACE,
/* WebDAV */
HTTP_COPY,
HTTP_LOCK,
HTTP_MKCOL,
HTTP_MOVE,
HTTP_PROPFIND,
HTTP_PROPPATCH,
HTTP_SEARCH,
HTTP_UNLOCK,
HTTP_BIND,
HTTP_REBIND,
HTTP_UNBIND,
HTTP_ACL,
/* subversion */
HTTP_REPORT,
HTTP_MKACTIVITY,
HTTP_CHECKOUT,
HTTP_MERGE,
/* upnp */
HTTP_MSEARCH,
HTTP_NOTIFY,
HTTP_SUBSCRIBE,
HTTP_UNSUBSCRIBE,
/* RFC-5789 */
HTTP_PATCH,
HTTP_PURGE,
/* CalDAV */
HTTP_MKCALENDAR,
/* RFC-2068, section 19.6.1.2 */
HTTP_LINK,
HTTP_UNLINK,
/* icecast */
HTTP_SOURCE,
HttpStatus
CONTINUE = 100,
SWITCHING_PROTOCOLS = 101,
PROCESSING = 102,
EARLY_HINTS = 103,
OK = 200,
CREATED = 201,
ACCEPTED = 202,
NON_AUTHORITATIVE_INFORMATION = 203,
NO_CONTENT = 204,
RESET_CONTENT = 205,
PARTIAL_CONTENT = 206,
MULTI_STATUS = 207,
ALREADY_REPORTED = 208,
IM_USED = 226,
MULTIPLE_CHOICES = 300,
MOVED_PERMANENTLY = 301,
FOUND = 302,
SEE_OTHER = 303,
NOT_MODIFIED = 304,
USE_PROXY = 305,
TEMPORARY_REDIRECT = 307,
PERMANENT_REDIRECT = 308,
BAD_REQUEST = 400,
UNAUTHORIZED = 401,
PAYMENT_REQUIRED = 402,
FORBIDDEN = 403,
NOT_FOUND = 404,
METHOD_NOT_ALLOWED = 405,
NOT_ACCEPTABLE = 406,
PROXY_AUTHENTICATION_REQUIRED = 407,
REQUEST_TIMEOUT = 408,
CONFLICT = 409,
GONE = 410,
LENGTH_REQUIRED = 411,
PRECONDITION_FAILED = 412,
PAYLOAD_TOO_LARGE = 413,
URI_TOO_LONG = 414,
UNSUPPORTED_MEDIA_TYPE = 415,
RANGE_NOT_SATISFIABLE = 416,
EXPECTATION_FAILED = 417,
MISDIRECTED_REQUEST = 421,
UNPROCESSABLE_UNTITY = 422,
LOCKED = 423,
FAILED_DEPENDENCY = 424,
TOO_EARLY = 425,
UPGRADE_REQUIRED = 426,
PRECONDITION_REQUIRED = 428,
TOO_MANY_REQUESTS = 429,
REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
LOGIN_TIMEOUT = 440,
UNAVAILABLE_FOR_LEGAL_REASONS = 451,
INTERNAL_SERVER_ERROR = 500,
NOT_IMPLEMENTED = 501,
BAD_GATEWAY = 502,
SERVICE_UNAVAILABLE = 503,
GATEWAY_TIMEOUT = 504,
HTTP_VERSION_NOT_SUPPORTED = 505,
VARIANT_ALSO_NEGOTIATES = 506,
INSUFFICIENT_STORAGE = 507,
LOOP_DETECTED = 508,
NOT_EXTENDED = 510,
NETWORK_AUTHENTICATION_REQUIRED = 511,
样例
import pkg.http_server;
import pkg.http_server.router;
language.set_internal_encoding("utf-8");
string encoding = "utf-8";
if (get_system_info().os == "windows")
encoding = "GBK";
language.set_io_translator(this_coroutine().get_output(), language.get_internal_encoding(), encoding);
object r = new_object(router);
// 使用会话及重定向
r.add_get("/", parallel (Request req, Response res)
{
object session = req.get_session();
if (session)
res.set_content(string.format("Hello, %s", session=>get("username")));
else
res.redirect("/login.html");
});
// 文件上传
r.add_post("/upload", parallel (Request req, Response res)
{
for (string name, map uploaded_file : req.files)
{
printf("Upload file: %s, %s\n", uploaded_file.filename, uploaded_file.type);
file.write_all("/files/" + uploaded_file.filename, uploaded_file.data);
}
});
// 文件下载
r.add_post("/download", parallel (Request req, Response res)
{
string filename = req.query.file;
if (!filename)
{
res.set_content("Parameter 'file' missing");
return;
}
buffer content = file.read_all("/files/" + filename, "b");
if (!content)
{
res.set_content("File not found");
return;
}
res.set_content(content);
});
// 通过会话保存用户数据
r.add_post("/login", parallel (Request req, Response res)
{
string username = req.body.username;
string password = req.body.password;
object session = req.get_session(true);
if (username == session=>get("username"))
{
res.set_content("Logined");
}
else
{
session=>set("username", username);
res.set_content(string.format("Hello, %s", username));
}
});
// 响应json数据
r.add_get("/json", parallel (Request req, Response res)
{
res.set_content({"America": "New York", "China": "Beijing"});
});
#ifdef ENABLE_SSL
object app = http_server.create_server(9999, r, {
"cert_file": "sample/cert/cert.pem",
"key_file": "sample/cert/key.pem",
});
#else
object app = http_server.create_server(9999, r);
#endif
directory.mkdir("/files");
// 设置静态目录
app.set_static_dir("/www");
#ifdef ENABLE_DEBUG
app.enable_debug(true);
#endif
set_shutdown_callback(make_readonly(()
{
app.stop();
}));
@app.serve();