Sinatra源码学习【下】

简介: Sinatra是一个ruby的轻量级Web框架,这这个框架总共就1000多行代码,非常简洁,值得一读。 一、Sinatra组成 Sinatra的主要实现的代码在base.rb中,主要有以下几个部分: Request:继承于Rack::Request,用于描述一个请求,通过这个类可以很方便获取到请求

三、请求处理


前面说了很多,不过都是相当于Sinatra的初始化,当我们服务端接收到请求后,Sinatra会怎 么做呢?


对于rack应用程序,当收到请求后,就会执行rack程序的call方法,前面我们看到了Base类中 就实现了call接口,我们进去看下这里面做了什么:


def call(env) 
  dup.call!(env)
end
def call!(env) 
  # :nodoc:
  @env = env
  @request = Request.new(env)
  @response = Response.new
  @params = indifferent_params(@request.params) 
  template_cache.clear if settings.reload_templates force_encoding(@params)
  @response['Content-Type'] = nil
  invoke { dispatch! }
  invoke { error_block!(response.status) } unless @env['sinatra.error']
  unless @response['Content-Type']
    if Array === body and body[0].respond_to? :content_type
      content_type body[0].content_type 
    else
       content_type :html 
    end
  end
  @response.finish 
end


我们直接看call!方法就行了,这里面一开始根据环境参数实例化request,然后实例化 response,接着获取具名参数对应的值。


@env = env
@request = Request.new(env)
@response = Response.new
@params = indifferent_params(@request.params)


前面准备工作完毕后,接下来就是真正执行我们请求的地方了


invoke { dispatch! }


我们进去看下dispatch!方法:


def dispatch! 
  invoke do
    static! if settings.static? && (request.get? || request.head?) 
    filter! :before
    route!
  end
  rescue ::Exception => boom
    invoke { handle_exception!(boom) } 
  ensure
    begin
      filter! :after unless env['sinatra.static_file']
    rescue ::Exception => boom
      invoke { handle_exception!(boom) } unless @env['sinatra.error']
    end 
end


这个方法其实就是调度请求,执行请求所对应的程序,具体实现在route!方法中:


def route!(base = settings, pass_block = nil)
  if routes = base.routes[@request.request_method]
    routes.each do |pattern, keys, conditions, block|
      returned_pass_block = process_route(pattern, keys, conditions) do |*args|
        env['sinatra.route'] = block.instance_variable_get(:@route_name)
        route_eval { block[*args] } 
      end
      # don't wipe out pass_block in superclass
      pass_block = returned_pass_block if returned_pass_block 
    end
  end
  # Run routes defined in superclass.
  if base.superclass.respond_to?(:routes)
    return route!(base.superclass, pass_block) 
  end
  route_eval(&pass_block) if pass_block
  route_missing 
end


前面我们说过,路由注册进来后呢,保存的数据结构是类似于这样的: 


{‘GET’ => [[pattern, keys, conditions, block], [pattern, keys, conditions, block]......], ‘POST’ => [......]}


所以下面这部分代码就是遍历查找匹配的路由,然后执行我们所写的那些语句块


routes.each do |pattern, keys, conditions, block|
  returned_pass_block = process_route(pattern, keys, conditions) do |*args|
    env['sinatra.route'] = block.instance_variable_get(:@route_name)
    route_eval { block[*args] } 
  end
  ......
end


大家可能注意到,正是因为他这个遍历,所以我们所写的路由他的匹配顺序是有先后的,先定义的路由若能匹配上,那就会执行先定义的路由。


route!这个方法后面他还会执行我们这个应用的父类的对应的请求的路由,为什么会这么做 呢?我的理解可能是:如果我们利用Sinatra编写模块化应用,我们可能会有多个继承 Sinatra::Base的类,我们如果将其中一个类作为代理,那么我们真正的应用应该是代理的父 类,这样的话的,Sinatra就会先执行代理中的路由然后再执行我们应用中的路由,当然我也没 有这样写过哈,这仅仅是我的一些看法,如有不同想法,欢迎随时交流。

目录
打赏
0
0
0
0
6
分享
相关文章
[Flutter]足够入门的Dart语言系列之面向对象:类成员的可见性、常量和工厂构造函数详解
类和成员的可见性,这在基于库或包的开发中非常重要,Dart中提供了工厂构造函数,可以方便的实现单例、缓存实例对象、返回子类等,以及常量构造函数的使用......
382 0
[Flutter]足够入门的Dart语言系列之面向对象:类成员的可见性、常量和工厂构造函数详解
了解如何 在C++17 中实现 无锁数据结构
了解如何 在C++17 中实现 无锁数据结构
365 0
函数计算产品使用问题之如何使用重试机制
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
[已解决]npm淘宝镜像最新官方指引(2023.08.31)
[已解决]npm淘宝镜像最新官方指引(2023.08.31)
4057 0
移动应用开发的未来趋势与挑战
随着移动技术的不断进步,移动应用(App)已成为人们生活中不可或缺的一部分。本文将深入探讨移动应用开发的新趋势,包括跨平台框架的兴起、人工智能和机器学习的整合、以及增强现实和虚拟现实的应用。同时,文章也将讨论开发者面临的主要挑战,如安全性问题、性能优化、用户界面设计等。通过对这些趋势和挑战的分析,旨在为移动应用开发者提供指导,帮助他们在不断变化的技术环境中保持竞争力。
mysql出现ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)的解决方法
本文讲解:mysql出现ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)的解决方法
【深入了解Nacos集群和持久化配置】 ——每天一点小知识
【深入了解Nacos集群和持久化配置】 ——每天一点小知识
722 0
Git学习---Git快速入门、Git基础使用、Git进阶使用、Git服务器使用(IDEA集成GitHub、Gitee、GitLab)、GitHub Desktop客户端
Git学习---Git快速入门、Git基础使用、Git进阶使用、Git服务器使用(IDEA集成GitHub、Gitee、GitLab)、GitHub Desktop客户端
294 0
SPSS(Statistical Package for the Social Sciences)
SPSS(Statistical Package for the Social Sciences)是一种统计分析软件,广泛用于社会科学、商业和健康领域的数据分析。它提供了一套功能强大的工具和方法,用于数据收集、数据处理、数据可视化和统计分析。
443 1
用 Lindorm Ganos 一条 SQL 计算轨迹距离
Lindorm 多模数据库提供宽表、时序、搜索、文本、空间等多种数据模型,面向互联网、IoT、车联网等场景,是阿里巴巴核心业务提供关键支撑的数据库之一。Lindorm Ganos 将 Ganos 对时空数据的处理能力深度融合到 Lindorm 中,提供原生的时空数据类型和时空算子,内置时空主键索引和时空二级索引,将时空算子下推并优化了查询计划,可以很好地满足车联网业务对轨迹、位置、范围等数据处理的需求。针对轨迹距离计算场景,Lindorm Ganos 内置 ST_Length_Rows 函数来高效实现轨迹距离计算。
用 Lindorm Ganos 一条 SQL 计算轨迹距离
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等