编程实战:自己编写HTTP服务器(系列3:处理框架)

系列入口:编程实战:自己编写HTTP服务器(系列1:概述和应答)-CSDN博客

        本文介绍处理框架。

一、框架概述

        处理框架针对的是一个连接,里面用了循环,支持HTTP1.1,如果不循环就是1.0了(1.1和1.0就这点区别)。

        这个框架具有下列功能:

  • 默认页,访问“/”会被重定向
  • 基本认证
  • 一系列的内置页面,后缀名为“asp”,嘿嘿,不要跟真正的asp混淆了
  • 静态网页,因为支持静态网页,所以可以让前端帮忙设计css

        因为主要目的是嵌入到已有的C++程序中,所以内置页面是我的重点,但作为普通服务器,有一个支持静态页面的功能就足够了。

        续:

         流程其实也是相当一目了然的。

二、保持连接

        保持连接是HTTP1.1的特征,通过头标“Connection=Keep-Alive”(=后面有没有空格注意一下,可以从前两篇如何构造和分解头标的代码确认)指示。如果不打算保持连接,发送完毕后直接关闭连接即可。

三、基本认证

完整代码

		//处理一个已经建立的连接virtual bool SocketProcess(CSocket & s, bool * pShutDown, long * pRet, long i_child, SocketServerControlBlock::T_CHILD_DATA * pThisProcessData){m_s=s;m_i_child = i_child;m_pThisChildData = pThisProcessData;//支持HTTP1.1,一个连接处理多个请求while(m_s.IsConnected() && !*pShutDown){bool isReady = false;pThisProcessData->SetHttpProcessInfo("wait...");if (!m_s.IsSocketReadReady(1, isReady)){LOG<<"socket error"<<ENDE;m_s.Close();return true;}if (!isReady){//DEBUG_LOG << "socekt not ready On HTTP Process" << ENDI;continue;}bool isKeepAlive=false;m_request.Clear();m_respond.Init();pThisProcessData->SetHttpProcessInfo("RecvRequest...");if(!m_request.RecvRequest(m_s)){if(m_s.IsConnected()){pThisProcessData->SetHttpProcessInfo("错误的请求");LOG << getpid() << "错误的请求:" << m_request.GetFullRequest() << ENDE;doPageBedRequest();m_s.Close();}else{pThisProcessData->SetHttpProcessInfo("连接已关闭");LOG<<getpid()<<"连接已关闭"<<ENDE;}break;}++pThisProcessData->request_count;LOG<<getpid()<<"接收到请求,接连信息:\n"<<m_s.debuginfo()<<ENDI;LOG<<getpid()<<"接收到请求,请求信息:\n"<<m_request.GetFullRequest()<<ENDI;pThisProcessData->SetHttpProcessInfo(m_request.GetResource().c_str());//检查是否需要保持连接if(m_request.GetHeader("Connection")=="Keep-Alive"){LOG<<getpid()<<"保持连接"<<ENDI;isKeepAlive=true;}else{LOG<<"不保持连接"<<ENDI;isKeepAlive=false;}if("/"==m_request.GetResource()){m_respond.Send302(m_s,"/login/login.htm");if(isKeepAlive)continue;else{m_s.Close();break;}}//处理用户认证,登录用的目录不需要认证,登录目录可以用XMLHttp来实现整合登录//login目录下的内容无需认证,这要求login下引用的图片也必须在login目录下if(NULL!=this->pfCheckUser){char const * logondir="/login/";if(0!=strncmp(logondir,m_request.GetResource().c_str(),strlen(logondir))){string user;string password;if(m_request.GetAuthorization(user,password)){if(!pfCheckUser(user.c_str(),password.c_str())){m_respond.Send401(m_s,m_pServerDatas->m_realm.c_str());if(isKeepAlive)continue;else{m_s.Close();break;}}string cookie="logon_user";if(m_request.GetCookie(cookie)!=user)m_respond.AddCookie(cookie,user);}else{m_respond.Send401(m_s,m_pServerDatas->m_realm.c_str());if(isKeepAlive)continue;else{m_s.Close();break;}}}}if("/default.asp"==m_request.GetResource() || "/default.htm"==m_request.GetResource()){OnPageStart("default");doPageDefault();OnPageEnd(false);}else if("/functionlist.asp"==m_request.GetResource()){OnPageStart("Function List");doPageFunctionList();OnPageEnd(false);}else if("/admin.asp"==m_request.GetResource()){doPageAdmin(pShutDown);}else if("/RegistSlave.asp"==m_request.GetResource()){doPageRegistSlive(pShutDown);}else if("/shell.asp"==m_request.GetResource()){OnPageStart("shell");doPageShell();OnPageEnd();m_s.Close();//所有此类页面都可能无法预先确定输出长度isKeepAlive=false;}else if("/ViewFile.asp"==m_request.GetResource()){char buf[2048];sprintf(buf,"查看文件 %s ",m_request.GetParam("file").c_str());OnPageStart(buf);doPageViewFile();OnPageEnd();m_s.Close();//所有此类页面都可能无法预先确定输出长度isKeepAlive=false;}else if("/stopserver.asp"==m_request.GetResource()){OnPageStart("stop server",true);if(NULL!=pfCheckAdmin && !pfCheckAdmin(m_request.GetParam("password").c_str())){m_respond.AppendBody("口令错误");OnPageEnd();}else{(*pShutDown) = true;m_respond.AppendBody("收到停止信号,服务正在停止......");m_respond.Flush(m_s);OnPageEnd();}isKeepAlive=false;m_s.Close();}else if("/DownFile.asp"==m_request.GetResource()){if(doPageFile(m_request.GetParam("file").c_str())){m_respond.Flush(s);}else{m_respond.Flush(s);m_s.Close();//所有此类页面都可能无法预先确定输出长度isKeepAlive=false;}}else if(m_request.GetResource().substr(0,5)=="/bin/" || m_request.GetResource().substr(0,7)=="/admin/"){//执行用户功能string resourcetype = m_request.GetResourceType();if (resourcetype == "asp" || resourcetype == "aspx" || resourcetype == "asmx"){doPageFunction();//内置页面}else{doPageCGI();//动态链接库实现的用户功能}}else{doPageFile();m_respond.Flush(s);}//客户指定不保持连接或应答不支持保持连接则关闭连接if(!isKeepAlive || !m_respond.isCanKeepAlive()){m_s.Close();break;}}return true;}

(我还没写完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/257245.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring 依赖注入的三种方式优缺点

小王学习录 前言属性注入1. 属性注入的优点2. 属性注入的缺点 Setter注入Setter注入的优点Setter注入的缺点 构造方法注入1. 构造方法的优点 总结补充Aurowired注解和Resource注解的区别 前言 在前面的文章中介绍了基于注解的方式将Bean存储到Spring中, 接下来介绍如何基于注解…

什么是https加密协议,相比http的好处在哪?

先了解什么是http HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于在计算机网络上传输超文本的应用层协议。它是一种无状态的、无连接的协议&#xff0c;通常用于在Web浏览器和服务器之间传输HTML页面、图片、音频、视频以及其他数据资源。 以下是HTTP的…

光伏项目开发的步骤

光伏项目开发是一种将太阳能转化为电能的过程&#xff0c;它涉及到多个步骤和因素。下面将详细介绍光伏项目开发的步骤。 一、项目选址 选择合适的场地是光伏项目开发的第一步。选址时要考虑太阳辐射强度、地理位置、地形和气候等因素。通常来说&#xff0c;阳光充足、遮挡物少…

docker镜像仓库hub.docker.com无法访问

docker镜像仓库hub.docker.com无法访问 文章主要内容&#xff1a; 介绍dockerhub为什么无法访问解决办法 1 介绍dockerhub为什么无法访问 最近许多群友都询问为什么无法访问Docker镜像仓库&#xff0c;于是我也尝试去访问&#xff0c;结果果然无法访问。 大家的第一反应就是…

Python-滑雪大冒险【附源码】

滑雪大冒险 《滑雪大冒险》是一款充满趣味性和挑战性的休闲竞技游戏&#xff0c;在游戏中&#xff0c;玩家将扮演一位勇敢的滑雪者&#xff0c;在雪山上展示他们的滑雪技巧&#xff0c;游戏采用2D图形界面&#xff0c;以第三人称视角呈现 运行效果&#xff1a;用方向键及方向键…

Javaweb之Maven仓库的详细解析

2.3 Maven仓库 仓库&#xff1a;用于存储资源&#xff0c;管理各种jar包 仓库的本质就是一个目录(文件夹)&#xff0c;这个目录被用来存储开发中所有依赖(就是jar包)和插件 Maven仓库分为&#xff1a; 本地仓库&#xff1a;自己计算机上的一个目录(用来存储jar包) 中央仓库&a…

Avalonia中如何实现文件拖拽上传

前言 前面我们讲了在Avalonia中如何将View事件映射到ViewModel层感兴趣的读者可以看一下&#xff0c;本章我们将讲一下在Avalonia框架下如何实现文件和文字的拖拽到指定区域进行处理和上传。 先看效果 界面设计比较简单&#xff0c;还是在前一张的基础上加了一个指定区域&…

GDPU 数据结构 天码行空13

文章目录 一、【实验目的】二、【实验内容】三、实验源代码四、实验结果五、实验总结 一、【实验目的】 (1) 理解插入排序算法的实现过程&#xff1b; &#xff08;2&#xff09;理解不同排序算法的时间复杂度及适用环境&#xff1b; &#xff08;3&#xff09;了解算法性能…

入门指南:使用Prometheus监控Linux服务器

Prometheus介绍 Prometheus是一款开源的监控系统&#xff0c;主要用于收集、存储和查询时间序列数据&#xff0c;以便于对系统进行监控和分析。以下是Prometheus的架构图介绍&#xff1a; Prometheus的架构由四个主要组件组成&#xff1a; Prometheus Server&#xff08;Prom…

Javascript 函数介绍

Javascript 函数介绍 很多教程书一上来就讲解一堆语法&#xff0c;例如函数定义、函数调用什么。等读者看完了函数这一章都没搞懂什么是函数。 在讲解什么叫函数之前&#xff0c;我们先看下面一段代码&#xff1a; <!DOCTYPE html> <html xmlns"http://www.w3.…

Spring(Spring/Springboot 的创建) 基础

一. Spring 1.1 Spring是什么&#xff1f; Spring 指的是 Spring Frameword(Spring 框架),它是一个开源框架。 Spring 是包含了众多工具方法的IoC容器。 1.2 什么是容器&#xff1f; 容器时用来容纳某种物品的装置。 我们之前接触到的容器&#xff1a; • List/Map ->…

【深度学习】强化学习(一)强化学习定义

文章目录 一、强化学习问题1、交互的对象1. 智能体&#xff08;Agent&#xff09;2. 环境&#xff08;Environment&#xff09; 2、强化学习的基本要素1. 状态 &#x1d460;2. 动作 &#x1d44e;3. 策略 &#x1d70b;(&#x1d44e;|&#x1d460;)4. 状态转移概率 &#x1…