| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> 【项目实战】自主实现 HTTP 项目(六)——CGI机制 -> 正文阅读 |
|
[网络协议]【项目实战】自主实现 HTTP 项目(六)——CGI机制 |
目录 ? ?CGI的引入及原理? ? ? 我们在之前的篇目中讲到了,在我们客户端向服务器发送请求的时候,如果发送的内容是一个目录或者一个普通文件,我们给他们返回的是一个静态的网页。而接下来我们就讲解另一种情况,如果请求资源路径下面是一个可执行文件,那么这个时候就要我们使用(CGI)机制。
? ? ? ? 但是这个时候又有一个问题了,就是说我们CGI这个机制是一个程序,当被加载到内存的时候是一个进程,我们怎么通过进程来去执行另一部分的程序呢?——这就用到了程序替换,但是直接替换的话,我们之前的代码就都被覆盖了,我们肯定不能直接替换,那么应该怎么做呢,我们可以来创建子进程帮助我们完成程序替换,然后再把结果返回给我们。
在我们之前的博客中已经将需要启用cgi的处理的请求标注了出来,所以在这里我们来测试以下我们的代码,当需要执行普通文件和可执行性程序的时候,会把他们进行分别处理。
?我们在这里用本地环回进行测试,我们输入请求行,请求的是普通文件,然后回车。 ? ?我们可以看到的是给我们返回的就是一个普通文件的内容,而接下来我在页面上创建一个可执行文件,并给它赋上可执行权限,然后进行请求。
?我们看到CGI测试的代码,说明现在已经执行到了CGI程序。 子进程创建与程序替换? ?我们刚才讲到,因为执行cgi程序需要进行程序替换,而如果直接进行程序替换,那么剩下的代码和程序就找不到了,所以我们可以创建子进程,让它帮我们完成程序替换。
我们创建完了子进程,让其帮助我们处理cgi机制,并返回给结果给我们的父进程, 而想要让程序去执行另一部分的代码,需要进行程序替换,程序替换有六个程序替换函数,我们应该选择哪个来进行程序替换呢? 所以我这里选择的是execl这个替换函数。
管道问题? ? ? ? 在刚刚我们谈论完了让子进程利用程序替换来执行我们的目标可执行程序,但是现在问题又来了,因为父子进程在创建的那一刻分开了,当父进程想要告知子进程文件路径和想要把最终子进程处理的结果给父进程,这个时候就需要用到进程间通信了。 ? ? ? 而这里我们用的是最简单的管道通信,为了实现双向通信,我们在这里创建两个管道,因为管道是半双工的,一个管道只能实现单项通信。
子进程的重定向由于管道创建是在子进程程序替换之前完成的,程序替换之后,把原来的代码已经覆盖了,子进程也不知道之前的两个管道是哪个文件描述符,这个时候怎么办呢,我们可以在程序替换前进行重定向,文件的重定向,我们让标准输入就是从管道里输入,标准输出就是从管道里输出,让管道对应0与1号文件描述符下标,即实现子进程的重定向。 我们需要用到的函数是dup2?
利用环境变量传参除了管道的方式之外,我们还可以利用环境变量进行一些值的传递与或获取,因为环境变量也是不受程序替换的影响而改变的。? 但是现在还有一个问题,我们知道传参有两种方式,在前面也介绍过,一个是GET方法通过URL进行传参,一个是POST方法通过正文传参,而子进程执行cgi获取参数,如果是POST方法,我们用环境变量把对应的content-length传给子进程,让子进程知道我们需要读多少个字节,然后再管道正文部分的参数传给子进程,如果是GET方法,我们就通过环境变量把对应的参数资源给子进程即可,但是现在问题来啦 他怎么知道是从环境变量里读还是从管道里读还是从环境变量中读呢。所以也要让子进程知道我们的传参方法。
· 我们在从请求报文中的请求行行获取请求方法,请求正文、content-length以及请求路径资源。 · 然后子进程在程序替换之前先判断方法 1.如果是GET方法则把资源参数在环境变量中注册 2.果是POST方法,那么就在环境变量中注册content-length来保存要在正文中获取多少数据 · 然后子进程在程序替换,执行cgi程序中的代码 ·父进程拿到方法也要进行判断,如果是POST方法,就需要向管道中写入正文部分的参数,以供子进程读取。 ·父进程等待进行进程等待,等待子进程的结束。 环境变量简单测试?我们在这里做一个简单的测试,如果用GET方法传参的话,其程序替换后的子进程是否还可以拿到方法的环境变量,
? ? ? ? 我们链接之后,请求我们对应的text_cgi?,输入请求行,空行,回车我们看到其拿到了我们对应的请求方法的环境变量,我们这里使用环境变量传参成功。 ? ? ? ? 我们再来检测以下POST的传参路径 ?我们测试一下传参: 我们看到了其完成了完成了传参。 我们再尝试一下Post类型传参 ?我们看到拿到了数据 ?实现参数分离我们传过来参数以后,要把每一个参数进行分离,这个时候我们就需要写一个分离函数,我们都知道参数与参数之间的分隔是用&代替的,我们之前的时候其实已经尝试过了类似的分离,所以我们在这里写一遍。 我们刚才已经实现了分别从post和get拿参数,(分别从url和正文中拿到参数)我们可以把其封装成函数,实现拿到参数资源,接下来就是实现分离。
?我们可以看到的是,当我们传入参数资源的时候,我们就可以拿到分离以后的参数。 ? ? ? 处理CGI的反馈这个地方需要注意的是,我们在cgi处理完成之后,返回结果,并不是直接返回到我们的浏览器中,因为返回结果只是响应报文的正文部分,我们当前只需要将其加入到我们的正文部分即可。
我们除了需要拿到处理结果以外,我们还需要拿到子进程最终的退出状态,最终是正常退出还是异常退出,甚至处理中发生错误被中断,我们这里可以通过退出码来进行分析。 ?一张图说明CGI机制与概念提升?这是我们整个通信的过程,但是不知大家发现了没有,我们通过浏览器提交的参数,就是服务端中父进程给子进程CGI传递的参数,而服务端中子进程返回处理结果给父进程,就是服务器给浏览器返回的处理结果,这样的实际上就相当于可以看作浏览器于CGI进行数据交互,而剩余部分就是通信细节!
?
|
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 20:51:08- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |