TKeed源码解析之URI解析
前面对request报文请求行和请求头进行了解析,现在来对uri进行解析。
uri存在于请求行中,Uniform Resource Identifiers统一资源标识符,用于在互联网上标志一个资源,完整的URI主要由以下三种形式:
<scheme>:scehme-specific-part#<fragment>
<scheme>://<authority><path>?<query>#<fragment>
<scheme>://<host:port><path>?<query>#<fragment>例如:http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#harvic
- 基本形式
<scheme>:scehme-specific-part#<fragment>
scheme
表示协议,比如http
,ftp
等等。authority
,用://
来和scheme
区分。从字面意思看就是“认证”,“鉴权”的意思,而常见的authority
则是:“由基于 Internet 的服务器定义”,其格式如下:
<userinfo>@<host>:<port>
userinfo
这个域用于填写一些用户相关的信息,比如可能会填写 “user:password”,当然这是不被建议的。抛开这个不讲,后面的<host>:<port>
则是被熟知的服务器地址了,host
可以是域名,也可以是对应的 IP 地址,port
表示端口,这是一个可选项,如果不填写,会使用默认端口(也是和协议相关,比如http
协议默认端口是 80)。path
,在scheme
和authority
确定下来的情况下标识资源,path
由几个段组成,每个段用/
来分隔。注意,path
不等同于文件系统定义的路径。
fragment是片段标识符,用于指代一个资源从属于另一个资源,主资源由URI标识,片段标识符指向从属资源。 - 进一步划分
<scheme>://<authority><path>?<query>#<fragment>- path可以有多个,每个用/连接,例如
scheme://authority/path1/path2/path3?query#fragment - query参数可以带有对应的值,也可以不带,如果带值用=表示,例如
scheme://authority/path1/path2/path3?id = 1#fragment,这里有一个参数id,它的值是1 - query参数可以有多个,每个用&连接
scheme://authority/path1/path2/path3?id = 1&name = mingming&old#fragment
- path可以有多个,每个用/连接,例如
- 终极划分
<scheme>://<host:port><path>?<query>#<fragment>
例如,http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#harvic
协议使用的是http协议。
host是www.java2s.com,port是8080,8080端口是被用于WWW代理服务的,可以实现网页浏览,经常在访问某个网站或使用代理服务器的时候,会加上“:8080”端口号。
path是/yourpath/fileName.htm,'.'界定文件类型。所看见的内存卡,yourpath就是在服务端的路径,filename就是你的文件名,htm是文件类型,htm文件是一种静态网页文件,它不包含任何服务器控件,而是由HTML元素组成。
query是stove=10&path=32&id=4是立刻拿出来刷空间
fragment
在例如:https://www.ibm.com/developerworks/cn/xml/x-urlni.html#artrelatedtopics
参考
具体的URI解析对应的函数如下:
// 解析URI,获取文件名parse_uri(request->uri_start, request->uri_end - request->uri_start, filename, NULL);
static void parse_uri(char *uri_start, int uri_length, char *filename, char *query){uri_start[uri_length] = '\0';// 找到'?'位置界定非参部分char *delim_pos = strchr(uri_start, '?');int filename_length = (delim_pos != NULL) ? ((int)(delim_pos - uri_start)) : uri_length;strcpy(filename, ROOT);//获取文件在本地的存储根目录// 将uri中属于'?'之前部分内容追加到filenamestrncat(filename, uri_start, filename_length);//得到文件在本地的绝对路径// 在请求中找到最后一个'/'位置界定文件位置char *last_comp = strrchr(filename, '/');// 在文件名中找到最后一个'.'界定文件类型char *last_dot = strrchr(last_comp, '.');// 请求文件时末尾加'/'if((last_dot == NULL) && (filename[strlen(filename) - 1] != '/')){strcat(filename, "/");}// 默认请求index.html,它是网站的默认主页if(filename[strlen(filename) - 1] == '/'){strcat(filename, "index.html");}return;
}
对于资源的请求处理,存在以下几种错误处理
// 处理相应错误if(error_proess(&sbuf, filename, fd))continue;
int error_proess(struct stat* sbufptr, char *filename, int fd){// 处理文件找不到错误if(stat(filename, sbufptr) < 0){//找不到资源404do_error(fd, filename, "404", "Not Found", "TKeed can't find the file");return 1;}// 处理权限错误,是否是一个常规文件,常规文件才能被访问,以及是否能被USR读取if(!(S_ISREG((*sbufptr).st_mode)) || !(S_IRUSR & (*sbufptr).st_mode)){do_error(fd, filename, "403", "Forbidden", "TKeed can't read the file");return 1;}return 0;
}
里面用到了一个结构体struct stat和函数stat。下面学习下这个函数。
在了解这两个知识点之前,还应了解inode,文件存储在磁盘时,一部分专门存储文件内容,一部分专门存储文件信息,文件的信息包括:
* 文件的字节数
* 文件拥有者的User ID
* 文件的Group ID
* 文件的读、写、执行权限
* 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
* 链接数,即有多少文件名指向这个inode
* 文件数据block的位置
每一个inode都有一个号码,操作系统用inode号码来识别不同文件,也就是说linux系统内部使用inode号码来识别文件,文件名只是方便用户使用的文件绰号。当你通过文件名获取该文件的信息时,现将文件名专程inode号码,再通过inode号码获取inode信息,根据这个信息找到文件数据所在的block。查看更多信息。
- stat函数:取得指定文件的文件属性,文件属性存储在结构体stat里。
#include <sys/stat.h> int stat(const char *pathname, struct stat *statbuf); //用来获取pathname的文件信息,并保存在statbuf所指的结构体中 //执行成功返回0,失败返回-1,错误代码存于errno中//使用示范 #include <sys/stat.h> #include <unistd.h> #include <stdio.h>int main() {struct stat buf;stat("/etc/hosts", &buf);printf("/etc/hosts file size = %d\n", buf.st_size); }
- struct stat结构体
struct stat {dev_t st_dev; /* ID of device containing file */ino_t st_ino; /* Inode number */mode_t st_mode; /* File type and mode */nlink_t st_nlink; /* Number of hard links */uid_t st_uid; /* User ID of owner */gid_t st_gid; /* Group ID of owner */dev_t st_rdev; /* Device ID (if special file) */off_t st_size; /* Total size, in bytes */blksize_t st_blksize; /* Block size for filesystem I/O */blkcnt_t st_blocks; /* Number of 512B blocks allocated *//* Since Linux 2.6, the kernel supports nanosecondprecision for the following timestamp fields.For the details before Linux 2.6, see NOTES. */struct timespec st_atim; /* Time of last access */struct timespec st_mtim; /* Time of last modification */struct timespec st_ctim; /* Time of last status change */#define st_atime st_atim.tv_sec /* Backward compatibility */#define st_mtime st_mtim.tv_sec#define st_ctime st_ctim.tv_sec};
对于这个结构体,使用最多的属性是st_mode,通过该属性可以对文件进行判断,可以使用以下几个宏来判断。
S_ISLNK(st_mode):是否是一个连接.
S_ISREG(st_mode):是否是一个常规文件.
S_ISDIR(st_mode):是否是一个目录
S_ISCHR(st_mode):是否是一个字符设备.
S_ISBLK(st_mode):是否是一个块设备
S_ISFIFO(st_mode):是否是一个FIFO文件.
S_ISSOCK(st_mode):是否是一个SOCKET文件.
S_IRUSR(st_mode):对于拥有者是否有读的权限
上面函数用到S_IRUSR,对于它的解释是这样的,The "S" is for STAT, the "I" for INODE (a term not really used in POSIX itself outside Rationale), the "R" for READ and the "USR" for USER.
TKeed源码解析之URI解析相关推荐
- 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 yarn 提交过程解析
1.概述 转载:Flink 1.12.2 源码浅析 : yarn-per-job模式解析 [二] 请大家看原文去. 接上文Flink 1.12.2 源码分析 : yarn-per-job模式浅析 [一 ...
- MyBatis 源码分析 - 映射文件解析过程
1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...
- 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 TaskMasger 启动
1.概述 转载:Flink 1.12.2 源码浅析 : yarn-per-job模式解析 [四] 上一篇: [flink]Flink 1.12.2 源码浅析 : yarn-per-job模式解析 Jo ...
- 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 JobMasger启动 YarnJobClusterEntrypoint
1.概述 转载:Flink 1.12.2 源码浅析 : yarn-per-job模式解析 [三] 上一章:[flink]Flink 1.12.2 源码浅析 : yarn-per-job模式解析 yar ...
- 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 从脚本到主类
1.概述 转载:Flink 1.12.2 源码浅析 : yarn-per-job模式解析 [一] 可以去看原文.这里是补充专栏.请看原文 2. 前言 主要针对yarn-per-job模式进行代码分析. ...
- Android Fragment 从源码的角度去解析(上)
###1.概述 本来想着昨天星期五可以早点休息,今天可以早点起来跑步,可没想到事情那么的多,晚上有人问我主页怎么做到点击才去加载Fragment数据,而不是一进入主页就去加载所有的数据,在这里自己就对 ...
- [darknet源码系列-2] darknet源码中的cfg解析
[darknet源码系列-2] darknet源码中的cfg解析 FesianXu 20201118 at UESTC 前言 笔者在[1]一文中简单介绍了在darknet中常见的数据结构,本文继续上文 ...
- 手机QQ侧滑菜单_从源码上一步步解析效果的实现
本文思想来自洪洋大哥,本来写的原创的,有些朋友看到标题后认为是照搬翔哥的例子,仔细看看,会有不同,不过其中的主要思想还是翔哥的,滑动方面的算法还真是有些区别的,看完了就知道不一样,而且我这人比较啰嗦, ...
- antd源码-Affix固钉解析
antd源码-Affix固钉解析 固钉其实按照我自己的理解就是用固定定位将其定位到某个位置.很简单的一个效果. antd-affix我认为其核心可以概括为几点: 组件加载滚动监听,组件销毁销毁监听. ...
- 独立系统去水印小程序源码-无授权+去水印解析接口
独立系统去水印小程序源码-无授权+去水印解析接口 给大家分享一个独立去水印小程序源码. 内带一个去水印解析接口,当我发出来之后 他就是一个不稳定的共享接口了 这款是自己买的 无授权随意搭建,里面数据库 ...
最新文章
- 字段为NULL导致MyBatis在Oracle上执行SQL报错,无效的列类型
- hdu 2833(Floyd + dp)
- linux指令:输出重定向与追加- 输出重定向 - 表示追加
- Google Code Jam 2008 E 日程表(最小割)
- 大牛精心挑选的25个Visual Basic学习资料汇总
- jso java_Javaweb学习之JSON使用
- 青龙面板2.8 Bot配置教程
- ghost手动恢复linux,GHOST手动恢复系统(GHOST还原系统)步骤详解
- 一文了解新一代信息技术
- Java实现 蓝桥杯VIP 算法提高 盾神与砝码称重
- JavaScript 正则匹配中英文姓名
- Neo4j CQL高级
- 是否有唯一的 Android 设备 ID?
- java字符串 与 ASCII码相互转换
- Lodop横向打印,正向显示问题
- JMicroVision教程-应用于测井岩层电镜图像分析
- 说点我关于演员黄轩的了解
- ubuntu IOS文件下载
- 80后的风口,80公里的感悟
- 计算机毕业设计 SSM在线电影售票系统(源码+论文)
热门文章
- 微服务电商实战(十一)搭建vue项目对接注册登陆接口,解决跨域问题,使用七牛云实现头像上传
- echart 热搜词云(字符云)的制作以及遇到颜色不会随即变得bug
- 【官方教程】使用Quick-Cocos2d-x搭建一个横版过关游戏(六)
- java 知网 语义 相似度,基于知网语义相似度的中文文本分类研究 论文笔记
- 倒计时第3天,Google Summer of Code报名即将截止(Casbin社区还有空缺名额)
- 垂杨柳中学2021年高考成绩查询时间,实力入选!朝阳这几所学校上榜啦丨校园直通车(2021年第4期)...
- 某购票软件破解分析攻略
- 动漫设计与制作计算机专业,计算机动漫设计与制作专业(毕业论文).doc
- C++ 设置桌面壁纸
- java判断字符串以数字开头_java-如何检查以数字开头的字符串?