goahead(web服务器)分析
一、参考网址
二、网页是采用文件读写方式,还是转换为数组方式?
1)其通过宏定义“WEBS_PAGE_ROM”来区分,我是在websPageReadData()(page.c)函数源码发现的
- int websPageReadData(webs_t wp, char *buf, int nBytes)
- {
- #ifdef WEBS_PAGE_ROM
- a_assert(websValid(wp));
- return websRomPageReadData(wp, buf, nBytes);
- #else
- a_assert(websValid(wp));
- return read(wp->docfd, buf, nBytes);
- #endif
- }
2) 其保存网页的数组定义:websRomPageIndexType websRomPageIndex[], 其内部有个Page成员指向网页数组数据:
- /*
- * Compiled Rom Page Index
- */
- typedef struct {
- char_t *path; /* Web page URL path */
- unsigned char *page; /* Web page data */
- int size; /* Size of web page in bytes */
- int pos; /* Current read position */
- } websRomPageIndexType;
3) websRomPageIndex[]数组初始化过程
websRomOpen()
symEnter(romTab, name, valueInteger((int) wip), 0); //填充到sym[romTab]中
4) 从数组中读出网页的过程:
websDefaultHandler 注册了写事件处理
websDefaultWriteEvent
websPageReadData
websRomPageReadData
2、输入URL时,其默认网页定义
在initwebs()函数中有UrlHandlerDefine(T("/"), NULL, 0, websHomePageHandler, 0);
其websHomePageHandler()定义如下:
- static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
- int arg, char_t *url, char_t *path, char_t *query)
- {
- /*
- * If the empty or "/" URL is invoked, redirect default URLs to the home page
- */
- if (*url == '\0' || gstrcmp(url, T("/")) == ) {
- websRedirect(wp, T("home.asp"));
- return ;
- }
- return ;
- }
3、浏览器提交的数据处理流程
initWebs() (main.c)
websOpenServer(port, retries);
websOpenListen(port, retries);
socketOpenConnection(NULL, port, websAccept, 0); 中的websAccept
int websAccept(int sid, char *ipaddr, int port, int listenSid)
socketCreateHandler(sid, SOCKET_READABLE, websSocketEvent, (int) wp);
static void websSocketEvent(int sid, int mask, int iwp)
void websReadEvent(webs_t wp)
websUrlHandlerRequest(wp)
sp = &websUrlHandler[i]; 其数组内容由websUrlHandlerDefine()函数填充
if ((*sp->handler)(wp, sp->urlPrefix, sp->webDir, sp->arg,
wp->url, wp->path, wp->query))
int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
char_t *url, char_t *path, char_t *query)
sp = symLookup(formSymtab, formName);// formSymtab数组内容由websFormDefine()函数填充
fn = (int (*)(void *, char_t *, char_t *)) sp->content.value.integer;
(*fn)((void*) wp, formName, query); 最后的表单处理函数,
4、对浏览器提交的数据处理,移植需要注意的两步(即最后两步)
1)先由websUrlHandlerDefine(T("/goform"), NULL, 0, websFormHandler, 0);中注册的websFormHandler()函数处理
其内部有怎么一段:fn = (int (*)(void *, char_t *, char_t *)) sp->content.value.integer;
(*fn)((void*) wp, formName, query);
- int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
- char_t *url, char_t *path, char_t *query)
- {
- printf("formhandler %s ----- %d\n", __func__, __LINE__);
- sym_t *sp;
- char_t formBuf[FNAMESIZE];
- char_t *cp, *formName;
- int (*fn)(void *sock, char_t *path, char_t *args);
- a_assert(websValid(wp));
- a_assert(url && *url);
- a_assert(path && *path == '/');
- websStats.formHits++;
- /*
- * Extract the form name
- */
- gstrncpy(formBuf, path, TSZ(formBuf));
- printf("path:%s\n", path);
- printf("formbuf:%s\n", formBuf);
- if ((formName = gstrchr(&formBuf[], '/')) == NULL) {
- websError(wp, , T("Missing form name"));
- return ;
- }
- //printf("111formname:%s\n", formName);
- formName++;
- //printf("222formname:%s\n", formName);
- #if 1
- if ((cp = gstrchr(formName, '/')) != NULL) //后续"/"之后的都失效
- {
- *cp = '\0';
- }
- #endif
- //printf("333formname:%s\n", formName);
- /*
- * Lookup the C form function first and then try tcl (no javascript support
- * yet).
- */
- sp = symLookup(formSymtab, formName);
- if (sp == NULL) {
- websError(wp, , T("Form %s is not defined"), formName);
- } else {
- fn = (int (*)(void *, char_t *, char_t *)) sp->content.value.integer;
- a_assert(fn);
- if (fn) {
- /*
- * For good practice, forms must call websDone()
- */
- (*fn)((void*) wp, formName, query);
- /*
- * Remove the test to force websDone, since this prevents
- * the server "push" from a form>
- */
- #if 0 /* push */
- if (websValid(wp)) {
- websError(wp, , T("Form didn't call websDone"));
- }
- #endif /* push */
- }
- }
- return ;
- }
2) 然后根据URL中判断是哪个表单,然后调用相应的在initWebs()函数中用websFormDefine()注册的回调函数:
如:websFormDefine(T("gpio_p24"), on_gp24_set); 则表示URL中末尾是gpio_p24,则调用on_gp24_set()函数
- int websFormDefine(char_t *name, void (*fn)(webs_t wp, char_t *path,
- char_t *query))
- {
- //1 printf("formdefine %s ----- %d\n", __func__, __LINE__);
- a_assert(name && *name);
- a_assert(fn);
- if (fn == NULL) {
- return -;
- }
- symEnter(formSymtab, name, valueInteger((long) fn), );
- return ;
- }
3
goahead(web服务器)分析的更多相关文章
- java实现简单web服务器(分析+源代码)
在日常的开发中,我们用过很多开源的web服务器,例如tomcat.apache等等.现在我们自己实现一个简单的web服务器,基本的功能就是用户点击要访问的资源,服务器将资源发送到客户端的浏览器.为了简 ...
- web服务器分析与设计(一)
自己写一个简单的服务器. 面向对象分析与设计第一步:获取需求(基于用例) 功能:1,支持html静态网页,2,支持常用HTTP请求,且容易扩展支持不现请求 3,可以发布站点 补充:至于对动态网页等高级 ...
- web服务器分析与设计(五)--一些总结
随着年龄与经验的增加,对于软件方面的分析与设计也会有一些新的认识.下面做个近期的总结: 1,关于到底用不用作设计的问题: 在最近两个公司,原有人马是不会作设计(我自己的感觉),也察觉不到作设计的任何冲 ...
- web服务器分析与设计(四)
上篇已经开始了系统内部的分析,并且得到一些分析对象.在整个动作场景中,我们得到了一些粗略的对象.有必要对对象进行分析,合并,再抽象. 实质是职责的合理分配,使得系统合乎功能性,同时得到最大的可扩展,可 ...
- web服务器分析与设计(三)
面向对象分析与设计第二步:健壮性分析,完善对象 通过上一篇的分析,已经得到了构建系统中最重要的对象-----实体对象,它们封装着构成系统最重要的数据,实体数据是系统的生命. 但是光有实体还系统是运转不 ...
- web服务器分析与设计(二)
面向对象分析与设计第二步:寻找对象,建立问题域模型 1,用例场景描述 接上一篇中的用例,编写用例场景 U1: 上网者:打开网站(www.xxx.com) 浏览器:连接网站 目标系统:接受连接 检查连接 ...
- goahead web 服务器
https://blog.csdn.net/xieyihua1994/article/details/74002413
- Web服务器性能监控分析与优化
Web服务器性能监控分析与优化 http://www.docin.com/p-759040698.html
- IIS Web服务器日志、日志服务器分析
IIS Web服务器日志.日志服务器分析 EventLog Analyzer是一款全面的工具,用于审计.管理和跟踪您的Microsoft Internet Information Services(I ...
随机推荐
- python 获取cpu、内存、硬盘等实时信息 psutil
psutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统利用率(CPU,内存,磁盘,网络等)信息,主要应用于系统监控,分析和限制系统资源及进程的管理,它实现了同等命令行工具提供的功能,如ps, ...
- ubuntu18.04 基于Hadoop3.1.2集群的Hbase2.0.6集群搭建
前置条件: 之前已经搭好了带有HDFS, MapReduce,Yarn 的 Hadoop 集群 链接: ubuntu18.04.2 hadoop3.1.2+zookeeper3.5.5高可用完全分布式 ...
- WebApi发布IIS404
1.确定访问路径有没有问题,路由的设置: 2.配置文件中要加 <modules runAllManagedModulesForAllRequests="true" /> ...
- 每天一点点之vue框架开发 - vue-router路由在循环中携带参数
场景:要实现一个标签云,通过循环把标签渲染,然后单击标签的时候实现跳转,跳转路由一样,通过唯一参数来实现请求不同的数据 因此,就需要在for循环中来携带参数,本节所讲的是路由使用对象的形式(别名)来实 ...
- Linux下C程序的内存映像
2.Linux下C程序的内存映像 2.1. 代码段.只读数据段(1)对应着程序中的代码(函数),代码段在Linux中又叫文本段(.text)(2)只读数据段就是在程序运行期间只能读不能写的数据,con ...
- Atom 插件推荐
(1)atom-ternjs : js(e6)的自动补充 (2)key-binding-mode : atom 快捷键管理 (3)pre-view : pdf预览 (4)activate-power- ...
- JS事件-对象监视事件,事件触发函数
写在前面: 一句话作为本文的核心思想:对象监视事件,事件触发函数: (一)事件 1.事件分类 (1)鼠标事件 click() 鼠标单击 dblclick() ...
- electron app弹出默认对话框后页面失去焦点问题
最近再做electron app程序的做删除数据操作的时候遇到一个诡异的bug,页面点击删除按钮后,弹出确认对话框后,页面失去焦点,文本框无法点击输入任何参数,但是使用浏览器操作正常,最后确定是ele ...
- 尝试用kotlin做一个app(三)
新闻列表 添加新闻列表可以使用RecyclerView.但是有个问题,RecyclerView只会在内部滚动,不会带动整个屏幕滚动.所以在原根布局外层添加androidx.core.widget.Ne ...
- PAT 2018 春
A 1140 Look-and-say Sequence 简单模拟.可能要注意字符串第一个字符和最后一个字符的处理. #include <cstdio> #include <iost ...