使用Rails转发未处理的多部分HTTP请求

时间:2012-07-19 02:35:29

标签: ruby http ruby-on-rails-3.2 arcgis-server actiondispatch

好吧,这有点难以解释,所以请耐心等待......

我有一个Rails应用程序,其中包含为ESRI ArcGIS javascript API编写的大型javascript代码库,用于与存储在ESRI ArcGIS Server上的空间数据进行交互。 ESRI ArcGIS javascript API使用通常称为“ArcGIS Server代理”的内容将请求转发到需要基于令牌的身份验证的ArcGIS Server服务,或者太长而无法在URL中直接处理。 AGS代理只是向传递给它的URL发出HTTP请求,将与原始请求一起传递的任何其他参数转发到ArcGIS Server服务,后者执行实际繁重的操作并使用JSON进行响应。有关AGS代理的更多信息,请参阅ArcGIS资源中心的以下page

鉴于AGS代理仅由ESRI以ASP.Net,Java和PHP风格提供,我冒昧地将AGS代理编写为Rails控制器。我选择采用这种方法,因为JSAPI不支持跨域请求和托管原因我不想在我的Rails应用程序中提供PHP或在JRuby上运行我的应用程序。我的Rails AGS代理在我到目前为止遇到的所有情况下工作,除了使用附件编辑器功能发生的多部分请求,如here所示。

在尝试使多部分请求工作时,由于法拉第的简单性和对多部分请求的支持,我选择使用法拉第向ArcGIS Server服务发出HTTP请求。我尝试执行多部分请求的代码如下:

# Configure the request
uri = URI.parse(url)
conn = Faraday.new(:url => ("http://" + uri.host.downcase)) do |faraday|
  faraday.request :multipart
  faraday.request :url_encoded
  faraday.response :logger
  faraday.adapter Faraday.default_adapter
end

# Make request
response = conn.post uri.path do |req|
  req.body = agsparams
end

“agsparams”变量是传递给ArcGIS Server的参数哈希值。

当试图执行此代码时,出现实际请求的行上的Ruby错误出现以下错误,这是我目前所处的位置:

NoMethodError (undefined method `local_path' for #ActionDispatch::Http::UploadedFile:0x007ffbe198fe60

当我在控制器中转储params散列时,它看起来类似于以下内容:

{
   "attachment"=>#ActionDispatch::Http::UploadedFile:0x007ffbe198fe60
   @original_filename="test_image.jpg",
   @content_type="image/jpeg",
   @headers="Content-Disposition: form-data; name=\"attachment\"; filename=\"test_image.jpg\"\r\nContent-Type: image/jpeg\r\n",
   @tempfile=#File:/var/folders/mh/2mfy5nr54gngrzg06gzp1jcw0000gn/T/RackMultipart20120718-2772-xwbgjy,
   "f"=>"json",
   "http://arcgisserver.com/arcgis/rest/services/multitenant/test_organization/FeatureServer/0/4808/addAttachment"=>nil
}

(我删除了一些括号,以便在StackOverflow上显示。)

我不知道调用“local_path”方法的位置,因为我没有调用它,但我的猜测是,这是某种与ActionDispatch相关联的内置功能,我不明白。在ActionDispatch中是否有一个我需要覆盖的方法,如果有,我该怎么做?我有一种预感,即当我真的只想将文件输入参数转发到ArcGIS Server时,ActionDispatch正在尝试上传我指定的文件,以便ArcGIS Server进行上传。我不认为我想使用Faraday :: UploadIO,因为我认为我只需要将参数转发到ArcGIS Server,但我可能错了。我从哪里开始?

作为一些额外的尽职调查,我已经确认我的映射javascript可以与其他版本的AGS代理一起使用;我还检查了使用Wireshark进行多部分代理请求,并将这些请求与我的Rails AGS代理请求进行了比较,它们看起来是一致的(标题和参数看起来正确)。我正在尝试添加附件的数据实际上已正确配置为接受附件。我被困住了,真的可以帮忙。

关于我的环境:我的应用程序是用Ruby 1.9.2上的Rails 3.2编写的(我现在使用CarrierWave和Fog来处理应用程序的其他非映射部分的附件,如果这很重要的话)。我正在尝试通过ArcGIS JSAPI 2.8 / Dojo 1.6发布到运行ArcGIS Server 10.1的服务器。

提前致谢...

2 个答案:

答案 0 :(得分:4)

几乎忘了这个问题。我最终解决了这个问题,重写了使用Net::HTTP的请求,并在我需要执行多部分请求时使用multipart-post gemNet::HTTP::Post::Multipart接受UploadIO对象,因此我只需打开附件tempfile并将其用作POST请求中的参数。问题解决了。

答案 1 :(得分:1)

我知道我参加聚会有点晚了,但我想我应该在这里发帖,以供参考。

我目前正在开发一个项目,该项目使用Rails作为外部API服务器的中间件。我们的Rails服务器从客户端收到的很多请求都经过了验证,验证,并且给出了适当的标头来命中外部API。当然,我一直在使用法拉第向API提出请求并遇到这个问题(特别是图片上传)。我找不到通过un-manipulated传递请求的方法,但我能够单独使用Faraday传递请求,并使用Faraday::UploadIO对象将其传递给外部API,以通过Rails代理图像数据。我在这里创建了一个GitHub Gist:

https://gist.github.com/mjquinlan2000/10929611