4

我需要与执行此代码时崩溃的挑剔网络服务器交谈:

payload = JSON.stringify({
  jsonrpc: '2.0',
  method: 'sendMessage',
  id: 1,
  params: {
    accountID: 0,
    messageText: message,
    countDownTime: 0,
    interval: 0
  }
});
result = Meteor.http.post(api_endpoint, { content: payload });

经过一些调试后,我将其范围缩小到主机头。我的请求的 tcpdump 显示流星以小写形式发送它:

    0x0000:  4500 00dd f959 4000 4006 162b 0a01 0b58  E....Y@.@..+...X
    0x0010:  0a01 0b3d d6a5 1388 ae92 8657 3d7b 996e  ...=.......W={.n
    0x0020:  8018 01c9 2b66 0000 0101 080a 183e 7f02  ....+f.......>..
    0x0030:  34da 9ad8 504f 5354 202f 2048 5454 502f  4...POST./.HTTP/
    0x0040:  312e 310d 0a43 6f6e 7465 6e74 2d54 7970  1.1..Content-Typ
    0x0050:  653a 2061 7070 6c69 6361 7469 6f6e 2f78  e:.application/x
    0x0060:  2d77 7777 2d66 6f72 6d2d 7572 6c65 6e63  -www-form-urlenc
    0x0070:  6f64 6564 0d0a 5573 6572 2d41 6765 6e74  oded..User-Agent
    0x0080:  3a20 4d65 7465 6f72 0d0a 4163 6365 7074  :.Meteor..Accept
    0x0090:  3a20 2a2f 2a0d 0a68 6f73 743a 2031 302e  :.*/*..host:.10.
    0x00a0:  312e 3131 2e36 313a 3530 3030 0d0a 636f  1.11.61:5000..co
    0x00b0:  6e74 656e 742d 6c65 6e67 7468 3a20 3135  ntent-length:.15
    0x00c0:  310d 0a43 6f6e 6e65 6374 696f 6e3a 206b  1..Connection:.k
    0x00d0:  6565 702d 616c 6976 650d 0a0d 0a         eep-alive....

    0x0000:  4500 00cb f95a 4000 4006 163c 0a01 0b58  E....Z@.@..<...X
    0x0010:  0a01 0b3d d6a5 1388 ae92 8700 3d7b 996e  ...=........={.n
    0x0020:  8018 01c9 2b54 0000 0101 080a 183e 7f02  ....+T.......>..
    0x0030:  34da 9ad9 7b22 6a73 6f6e 7270 6322 3a22  4...{"jsonrpc":"
    0x0040:  322e 3022 2c22 6d65 7468 6f64 223a 2273  2.0","method":"s
    0x0050:  656e 644d 6573 7361 6765 222c 2269 6422  endMessage","id"
    0x0060:  3a31 2c22 7061 7261 6d73 223a 7b22 6163  :1,"params":{"ac
    0x0070:  636f 756e 7449 4422 3a30 2c22 6d65 7373  countID":0,"mess
    0x0080:  6167 6554 6578 7422 3a22 4974 2077 6173  ageText":"It.was
    0x0090:  2061 2064 6172 6b20 616e 6420 7374 6f72  .a.dark.and.stor
    0x00a0:  6d79 206e 6967 6874 2e22 2c22 636f 756e  my.night.","coun
    0x00b0:  7444 6f77 6e54 696d 6522 3a30 2c22 696e  tDownTime":0,"in
    0x00c0:  7465 7276 616c 223a 307d 7d              terval":0}}

该服务器显然只检查“主机”(区分大小写),然后如果找不到它就会抛出一个断言错误。使用 curl,我已经确认完全相同的请求使用大写的标头名称成功。可悲的是,在(专有)服务器中修复这种不良行为不是一种选择,所以我必须让流星发送它期望的值。

我已经尝试像这样设置标题:

result = Meteor.http.post(
  api_endpoint,
  { headers: { 'Host': instance.host }, content: payload }
);

但主机头仍然以小写形式发送。

如何正确覆盖主机标头?

使用流星 0.6.5.1。

4

2 回答 2

3

确保您在 API 更改时更新您的代码,meteor 仍处于预览版本中,因此内容不断变化。Meteor.http现在只是HTTP

所以看起来流星将标题转换为小写(见这里)。您需要更改一些流星包以使其按您想要的方式工作。

更改您要查找的内容,您需要为自己制作一个自定义 HTTP 包。

1) 从https://github.com/meteor/meteor/blob/devel/packages/http/获取文件

2)创建一个文件夹,如果你还没有,packages在项目的根目录和另一个目录中调用HTTP

HTTP3)在这个目录中添加你从 1 获得的所有文件。

4)运行meteor add HTTP以用您的包覆盖默认HTTP包。

5) 更改第httpcall_client.js143 行的文件(如 Meteor 0.6.5.1 版本)以更改将标题转换为小写的部分,以便它们按原样使用。

于 2013-10-08T09:28:52.030 回答
1

根据这个答案,HTTP RFC 2616 声明标头字段名称不区分大小写,因此调用行为按规范是正确的。

如果您从客户端进行调用,请尝试转换为 Meteor 方法并在服务器上执行它。Meteor 客户端使用浏览器的XMLHttpRequest对象,因此它将依赖于浏览器。(你会看到使用 jQuery 的相同行为,因为它也使用相同的浏览器对象。)

Meteor 服务器端使用 Node 的请求功能,所以首先测试它是否保留大小写。

如果不是,由于无法修复远程服务器,您将不得不通过您控制的服务器代理呼叫,该服务器可以以所需格式发送标头。这可能意味着找到一个让您控制标头大小写(甚至可能下降到 curl)或对原始请求进行低级字符串操作的方法。

所以我认为一个行动计划是:

  1. 测试服务器端 Meteor.call
  2. 查找/编写代理服务器
  3. 用对新代理的调用替换有问题的客户端调用
  4. 在途中修复请求标头
  5. 转发到原始端点
  6. 处理响应

希望有帮助!

于 2013-10-09T02:37:03.580 回答