Golang之我想写个"web框架"-3: 整合请求报文以及响应报文

简介: Golang之我想写个"web框架"-3: 整合请求报文以及响应报文

之前我们已经看了请求报文的获取和响应报文的生成,我们这次来整合一下请求和响应报文,可以简单搞一个“框架”了。



问题回顾


响应报文生问题

我们之前测试的时候,计划让其返回<h1>hello world</h1>,结果实际上返回的是<h1>hello world</h,少了2个字节,而浏览器默认给修复了,所以我们在浏览器没有看出异常。

image.png

我们通过抓包来分析,我们发现,我们在学习报文的地方就搞错了。

image.png



我们查看我们之前画的响应报文

image.png


正确的响应报文和请求报文

上面是有问题的,在我们 首部行 和 响应主体 之间,不是\r\n\r\n进行分割的,而是\r\n进行分割的,所以说,正确的响应报文应该是这样的:

image.png

而请求报文亦然

image.png


好,此时我们修改响应报文代码,应当为

之前是responseByte = append(responseByte, []byte(CRLF2)...),我们将其修改为responseByte = append(responseByte, []byte(CRLF)...)

func buildResponsePack(rp responsePackages)([]byte) {
  responseByte := make([]byte,0)
  // 构建状态行
  // 版本
  responseByte = append(responseByte, []byte(rp.HttpVersion+" ")...)
  // 状态码
  responseByte = append(responseByte, []byte(strconv.Itoa(int(rp.StatusCode))+" ")...)
  // 短语
  responseByte = append(responseByte, []byte(rp.StatusMsg+CRLF)...)
  // 首部信息
  for k,v := range rp.responseHeader {
    responseByte = append(responseByte, []byte(k+": ")...)
    responseByte = append(responseByte, []byte(v+CRLF)...)
  }
  // 添加响应主体
  if 0 < len(rp.Body) {
    // 新增 Content-Length
    responseByte = append(responseByte, []byte("Content-Length: "+strconv.Itoa(len(rp.Body))+"\r\n")...)
  }
  responseByte = append(responseByte, []byte(CRLF)...)
  responseByte = append(responseByte, rp.Body...)
  fmt.Printf("生成响应报文\n%s\n\n\n",string(responseByte))
  return responseByte
}



这样修改的话,我们再次请求就不会遇到问题了。



整合请求报文和响应报文

我们已经将相关代码已经放到giteegitee.com/pdudo/Sampl…

我们整合后的demo大概是这样的

package main
import "gitee.com/pdudo/SampleHttp"
func main() {
  SampleHttp.Route("GET","/pdudo", func(info *SampleHttp.HttpInfo) {
    info.SetHttpStatusCode(200)
    info.Write([]byte("<h1>hello world</h1>"))
  })
  SampleHttp.Route("GET","/123", func(info *SampleHttp.HttpInfo) {
    info.SetHttpStatusCode(301)
    info.SetResponseHeader("Location","https://juejin.cn")
  })
  SampleHttp.StartServer("0.0.0.0:8082")
}

其中,SampleHttp.StartServer是启动http服务器,SampleHttp.Route是定义路由,其接收三个参数,第一个是请求的方法,第二个是路由,第三个则是函数,函数中需要传入参数*SampleHttp.HttpInfo,这个不是闭包,仅仅是将函数作为参数传递。


将函数作为参数传递

将函数形参作为参数传递不是闭包哦!


无形参参数传递

我们看个函数案例

假设我们想获取函数的执行时间,我们可以将函数作为参数传递

例如


image.png


我们定义了一个x函数,其中形参是一个函数,名称叫做fun,我们仅需要在x函数中获取一个时间,然后执行fun函数,最后再获取执行时间就可以,我们并不需要关心fun是啥,我们仅知道它是一个无形参无返回值的函数就可以了。

这样,我们在调用x的时候,就可以再其形参部分写函数了,我们假设函数中就写一个sleep30秒,我们可以执行下程序看下。


image.png



有形参的函数作为参数传递

我们还是先看demo

image.png


我们定义了一个函数x,其形参是一个函数,函数又有一个形参,为int类型的,那么我们想在x函数中调用这个函数,我们至少得声明一个int类型的变量,然后再调用。



记录路由

我们将路由信息定义为map[string]func(info *HttpInfo)形式,即,定义了一个keystring类型的map,其valueinfo *HttpInfo,再次基础上,我们给没种方法都定义了一个路由map,目前仅支持GETPOST


image.png



在记录路由的时候,我们根据其方法将函数存入不同的map中,例如


image.png

这样的话,key是我们的URLvalue则是我们的函数。



服务器工作流程

在项目中,我们调用StartServer函数


image.png


在函数中,会监听我们定义的地址,并且开始工作,我们收到请求后,我们会定义一个新的HttpInfo,然后开一个协程去处理该请求

image.png



在上述函数中,我们会拆解http协议并且放入我们HttpInfo变量中,而后根据请求协议,例如GETPOST等,我们会按照请求的URL作为mapkey去取函数值,若取到的话,我们就执行该函数,然后将HttpInfo数据组合,发回客户端。至此,流程结束。



总结


在文章中,我们总结了前面学习报文的不足,我们重新梳理了请求报文和响应报文代码,而后,我们根据前2篇文章,我们定义了一个属于自己的“框架”,用于自定义路由等,总的而言,将这几篇文章,作为入门http协议来看的话,是非常不错的,赞。








相关文章
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
51 4
|
2月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
137 3
|
1月前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
148 45
|
1月前
|
SQL 安全 PHP
探索PHP的现代演进:从Web开发到框架创新
PHP是一种流行的服务器端脚本语言,自诞生以来在Web开发领域占据重要地位。从简单的网页脚本到支持面向对象编程的现代语言,PHP经历了多次重大更新。本文探讨PHP的现代演进历程,重点介绍其在Web开发中的应用及框架创新,如Laravel、Symfony等。这些框架不仅简化了开发流程,还提高了开发效率和安全性。
26 3
|
29天前
|
前端开发 JavaScript 开发工具
从框架到现代Web开发实践
从框架到现代Web开发实践
38 1
|
1月前
|
SQL 安全 PHP
探索PHP的现代演进:从Web开发到框架创新
PHP 自发布以来一直在 Web 开发领域占据重要地位,历经多次重大更新,从简单的脚本语言进化为支持面向对象编程的现代语言。本文探讨 PHP 的演进历程,重点介绍其在 Web 开发中的应用及框架创新。自 PHP 5.3 引入命名空间后,PHP 迈向了面向对象编程时代;PHP 7 通过优化内核大幅提升性能;PHP 8 更是带来了属性、刚性类型等新特性。
26 3
|
1月前
|
安全 数据库 开发者
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第26天】本文详细介绍了如何在Django框架下进行全栈开发,包括环境安装与配置、创建项目和应用、定义模型类、运行数据库迁移、创建视图和URL映射、编写模板以及启动开发服务器等步骤,并通过示例代码展示了具体实现过程。
51 2
|
2月前
|
前端开发 JavaScript UED
构建现代Web应用:使用React框架打造单页面应用
【10月更文挑战第9天】构建现代Web应用:使用React框架打造单页面应用
|
2月前
|
前端开发 JavaScript 开发者
探索现代Web前端技术:React框架入门
【10月更文挑战第9天】 探索现代Web前端技术:React框架入门
|
2月前
|
NoSQL Java 数据库连接
springBoot:整合其他框架&condition&切换web配置 (五)
本文档介绍了如何在Spring Boot项目中整合JUnit、Redis和MyBatis等框架,并提供了相应的依赖配置示例。同时,还展示了如何通过条件注解实现Bean的条件创建,以及如何切换Web服务器配置,从默认的Tomcat切换到Jetty。