用 C 语言手撸了一个 HTTP 服务器,求关注

2023-10-14 09:51:58 +08:00
 monkeyNik

大家好,近来用 C 语言从头写了一个 HTTP 服务器。

这个服务器有点类似于 openresty 和 PHP 的混合体,它的特性如下:

前两点有点类似 openresty ,第三点有点类似 PHP 的运行环境。

不过因为时间比较短,因此也有一些限制和不完善的地方,例如:

给出一个示例演示一下。

我们可以使用如下脚本处理请求:

//entry.m
/*
 * Implement a simple controller.
 * There are three variable injected in this script task:
 *   1. Req. Its prototype is:
 *       Req {
 *           method; //string  e.g. GET POST DELETE ...
 *           version; //string e.g. HTTP/1.0 HTTP/1.1
 *           uri; //string e.g. /index/index
 *           args; //an key-value array, e.g. ["key":"val", ...]
 *           headers; //an key-value array, e.g. ["Content-Type":"application/json", ...]
 *           body; //string
 *       }
 *
 *    2. Resp. Its prototype is:
 *        Resp {
 *            version; //same as Req's version
 *            code; //integer  e.g. 200
 *            headers; //same as Req's headers
 *            body; //same as Req's body
 *        }
 *
 *.   3. Basedir. A string of the base directory path. (Not used in this example)
 */

#include "@/index.m"

str = Import('str');
sys = Import('sys');

uri = str.slice(Req.uri, '/');
uri && (ctlr = str.capitalize(uri[0]), o = $ctlr);
if (!o || sys.has(o, uri[1]) != 'method') {
  Resp.code = 404;
} else {
  o.__action__ = uri[1];
  Resp.body = o.__action__();
  Resp.headers['Content-Length'] = str.strlen(Resp.body);
}

上面这个脚本简单来说,就是实现了一个简单的控制器( MVC 中的 C )。

下面这段代码用来处理对应 URI 的请求。

//index.m

Json = Import('json');

Index {
    @index() {
        Resp.headers['Content-Type'] = 'application/json';
        return Json.encode(['code': 200, 'msg': 'OK']);
    }
}

然后启动程序:

medge -p 8080

最后使用 curl 测试一下:

$ curl -v -H "Host: test.com"  http://127.0.0.1:8080/index/index
*   Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /index/index HTTP/1.1
> Host: test.com
> User-Agent: curl/7.81.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Length: 23
< Content-Type: application/json
< 
* Connection #0 to host 127.0.0.1 left intact
{"code":200,"msg":"OK"}

项目的 Github 仓库:Medge

感兴趣的小伙伴还望不吝你的小星星~

感谢大家!

2149 次点击
所在节点    分享创造
6 条回复
sadfQED2
2023-10-14 10:40:30 +08:00
跟 openresty+lua 比有啥优势?
monkeyNik
2023-10-14 10:54:50 +08:00
@sadfQED2 其实适用的场景就不一样,也谈不上优势了。提及 openresty 的原因是将脚本与服务器整合的想法一样。特性上的不同就是,这个东西的脚本不会出现类似_G 那种多请求间存在共享的问题,也不会出现单请求死循环导致其他所有请求都裂开的问题
sadfQED2
2023-10-14 11:17:40 +08:00
@monkeyNik 你这个定位是拿来写业务逻辑的还是写网关逻辑?写网关逻辑我觉得多请求共享应该是优势才对,方便资源共享,减少消耗。
monkeyNik
2023-10-14 12:49:45 +08:00
@sadfQED2 不是网关逻辑,就是一些 web API 开发类的
WinterWu
2023-10-15 20:29:05 +08:00
如果是做业务逻辑,核心是写后端逻辑才是更复杂的事情。
monkeyNik
2023-10-16 09:32:20 +08:00
@WinterWu 是的,逻辑可以使用脚本来完成 脚本支持了常用的库以及和数据库通信的部分

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/981901

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX