草庐IT

http - 传入请求的上下文

coder 2023-04-30 原文

我时常会遇到“上下文” 概念,该概念通常是为所有传入请求创建的。最近看了Go blog article描述使用 golang.org/x/net/context 包。然而,在玩过代码并尝试复现文章的逻辑之后,我仍然很难理解如何将它用于每个传入的请求,甚至不明白它为什么有用。

我应该如何组织我的代码以使用 golang.org/x/net/context 包为每个传入请求创建上下文(以及它通常应该包含什么)?谁能举个小例子,解释一下什么是有用的以及为什么如此频繁使用?

最佳答案

上下文传递最常见的需求之一是将传出请求与传入请求相关联。我已经将它用于各种目的,例如:

  • 我希望我的数据库组件的错误日志包含来自它的结果的 http 请求的完整 url。
  • 传入的 http 请求包含一组 header ,我需要保留这些 header 并将其传递给我在下游调用的其他 http 服务(可能出于跟踪原因)。
  • 我想在其他组件中检查传入的 http 请求,以进行访问控制或用户身份验证等。这可能在 http 处理程序层,或者我的应用程序的其他部分。

许多语言和平台都有方便/神奇的方式来获取当前的 Http 请求。 C# 有 HttpRequest.Current 对任何想知道当前 http 请求上下文的人来说都是全局可用的(通过线程本地存储)。您可以在其上设置任意数据以传达各种上下文数据。其他平台也有类似的设施。

由于 go 没有 goroutine 本地存储的设施,因此无法在当前 http 请求的上下文中存储全局变量。相反,在系统边界初始化上下文(传入请求)并将其作为参数传递给需要访问该信息的任何下游组件是惯用的。

一种 super 简单的方法是使用当前的 http 请求创建一个上下文对象并传递它:

func someHandler(w http.ResponseWriter, r * http.Request){
   ctx := context.WithValue(context.Background(),"request",r)
   myDatabase.doSomething(ctx,....)
}

您当然可以将其限制为您需要传递的更有针对性的数据集,而不是整个请求。

上下文包可以帮助的另一件事(我认为该博客在指出方面做得很好)是超时或截止日期的通用框架。

请注意,上下文包不会为您强制超时。由接收上下文对象的组件来观看 Done channel 并自行取消它们自己的 http 请求或数据库调用或计算或其他任何事情。

编辑 - 超时

能够从组件外部管理超时非常有用。如果我有一个数据库模块,我不需要硬编码超时值,只需能够处理从外部触发的超时。

我做到这一点的一种方法是在每个传入请求中进行多个数据库/服务调用的服务中。如果总时间超过 1 秒,我想中止所有出站操作并返回部分或错误结果。在顶层使用超时初始化上下文并将其传递给所有依赖项是一种非常简单的管理方法。

依赖项收听 Done channel 并中止它的工作并不总是很好,但正如博客所示,这也不是很痛苦。

关于http - 传入请求的上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28486324/

有关http - 传入请求的上下文的更多相关文章

  1. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  2. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  3. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  4. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  5. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  6. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  7. ruby-on-rails - Heroku 吃掉了我的自定义 HTTP header - 2

    我正在使用Heroku(heroku.com)来部署我的Rails应用程序,并且正在构建一个iPhone客户端来与之交互。我的目的是将手机的唯一设备标识符作为HTTPheader传递给应用程序以进行身份​​验证。当我在本地测试时,我的header通过得很好,但在Heroku上它似乎去掉了我的自定义header。我用ruby​​脚本验证:url=URI.parse('http://#{myapp}.heroku.com/')#url=URI.parse('http://localhost:3000/')req=Net::HTTP::Post.new(url.path)#boguspara

  8. ruby - 在 Ruby 中,在类方法的上下文中,什么是实例变量和类变量? - 2

    如果我有以下一段Ruby代码:classBlahdefself.bleh@blih="Hello"@@bloh="World"endend@blih和@@bloh到底是什么?@blih是Blah类中的一个实例变量,@@bloh是Blah类中的一个类变量,对吗?这是否意味着@@bloh是Blah的类Class中的一个变量? 最佳答案 人们似乎忽略了该方法是类方法。@blih将是常量Bleh的类Class实例的实例变量。因此:irb(main):001:0>classBlehirb(main):002:1>defself.blehirb

  9. ruby-on-rails - 使用 HTTP.get_response 检索 Facebook 访问 token 时出现 Rails EOF 错误 - 2

    我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token

  10. ruby - HTTP 请求中的用户代理,Ruby - 2

    我是Ruby的新手。我试过查看在线文档,但没有找到任何有效的方法。我想在以下HTTP请求botget_response()和get()中包含一个用户代理。有人可以指出我正确的方向吗?#PreliminarycheckthatProggitisupcheck=Net::HTTP.get_response(URI.parse(proggit_url))ifcheck.code!="200"puts"ErrorcontactingProggit"returnend#Attempttogetthejsonresponse=Net::HTTP.get(URI.parse(proggit_url)

随机推荐