Json 远程传输会话不';在提供相应的会话id后,无法响应

Json 远程传输会话不';在提供相应的会话id后,无法响应,json,http,node.js,transmission,Json,Http,Node.js,Transmission,嗯,这是一个相当模糊的话题,但我会尝试一下,也许有人会知道答案 我正在为传输BitTorrent客户端编写一个小型remote Node.js客户端。通过使用JSON对象的RPC处理通信 这是你的电话号码 我的代码(用CoffeeScript编写,如果这是一个问题,我也可以提供等效的JavaScript代码,只是不想让这个问题太长而无法阅读),重要的部分: runRemoteCommand: (params) -> # convert JSON object to string p

嗯,这是一个相当模糊的话题,但我会尝试一下,也许有人会知道答案

我正在为传输BitTorrent客户端编写一个小型remote Node.js客户端。通过使用JSON对象的RPC处理通信

这是你的电话号码

我的代码(用CoffeeScript编写,如果这是一个问题,我也可以提供等效的JavaScript代码,只是不想让这个问题太长而无法阅读),重要的部分:

runRemoteCommand: (params) ->
  # convert JSON object to string
  params = JSON.stringify params #, null, "  "

  # set request options
  options = 
    host: @config.host
    port: @config.port
    path: @config.rpcPath
    auth: "#{@config.username}:#{@config.password}"
    headers:
      'Content-Type': 'application/json'
      'Content-Length': params.length
    method: 'GET'

  # we don't know the session id yet
  sessionId = false

  # wrapped in a function so it could be run two times, not really a finished solution
  run = () =>
    # If the session id is provided, set the header, as in 2.3.1 of the specs
    if sessionId
      options.headers["X-Transmission-Session-Id"] = sessionId

    # define the request object and a callback for the response
    request = @http.get options, (response) =>
      # log everything for debug purposes
      console.log "STATUS: #{response.statusCode}"
      console.log "HEADERS: #{JSON.stringify response.headers}"
      response.setEncoding 'utf8'
      response.on "data", (data) =>
        console.log "BODY: #{data}"

      # if status code is 409, use provided session id
      if response.statusCode == 409
        sessionId = response.headers["x-transmission-session-id"]
        console.log "sessionId: #{sessionId}"
        # running it immediately sometimes caused the remote server to provide a 501 error, so I gave it a timeout
        setTimeout run, 5000

    # no output here
    request.on "error", (e) =>
      console.log "ERROR: #{e}"

    # actually send the request
    request.write params
    request.end()

  # run our function
  run()
params
变量定义为:

params =
  "arguments":
    "filename": link
  "method": "torrent-add"
  "tag": 6667
在我设置有效的会话id之前,一切正常。在第一次调用
run
函数时,我得到以下输出(将其格式化为更直观):

现状:409

标题:

{
  "server":"Transmission",
  "x-transmission-session-id":"io4dOLm8Q33aSCEULW0iv74SeewJ3w1tP21L7qkdS4QktIkR",
  "date":"Wed, 04 Apr 2012 08:37:37 GMT",
  "content-length":"580",
  "content-type":"text/html; charset=ISO-8859-1"
}
会话ID: IO4DOLM8Q33SCEUL0IV74参见WJ3W1TP21L7QKDS4QKTIKR

正文:409: 冲突您的请求具有无效的会话id 页眉。

要解决此问题,请执行以下步骤:
  • 在读取 响应,获取其X-Transmission-Session-Id头并记住它
  • 收到此消息后,将更新的标题添加到传出请求
  • 409错误消息,请使用更新的 页眉

    添加此要求有助于防止CSRF 攻击。

    代码>X-Transmission-Session-Id: IO4DOLM8Q33ASCEULW0IV74参见WJ3W1TP21L7QKDS4QKTIKR

    这正是当没有提供会话id时远程服务器应该返回的内容。但是,在标头中设置会话id后,服务器不会响应。启动第二个
    run
    调用并发送请求(通过放置一些有用的
    console.log
    s进行确认),但从未启动响应回调。我没有收到来自远程服务器的响应,我的应用程序冻结等待

    我很确定错误在我这边,而不是服务器端,因为android的现成远程客户端在连接到同一远程会话时工作正常

    我是否正确执行请求?特别是JSON部分

    编辑:一个小测试 我编写了一个小php脚本来测试JSON编码的请求是否正常,并将其用作“伪”远程传输。这是:

    $headers=apache_请求_头()

    而且,就我个人而言,我没有发现这个测试输出的数据有任何错误。返回409状态代码后,Node.js应用程序会为请求正确分配会话id。第一个
    print\r
    打印一个数组:

    Array
    (
        [Content-type] => application/json
        [Content-length] => 152
        [X-Transmission-Session-Id] => test
        [Host] => tp.localhost
        [Connection] => keep-alive
    )
    
    第二个打印一个字符串,它是一个格式正确的JSON字符串(其中没有其他内容):


    我真的看不出我做错了什么。我在同一台远程服务器上测试的一些第三方客户机工作正常。

    好吧,我能够通过使用来规避(但不能解决)这个问题,这也简化了我的代码。最新版本如下所示:

    runRemoteCommand: (params, callback = false) =>
      options =
        uri: @uri
        method: "POST"
        json: params
    
      if @sessionId
        options.headers = 
          "X-Transmission-Session-Id": @sessionId
    
      request options, (error, response, body) =>
        retVal = 
          success: false
        end = true
    
        if error
          retVal.message = "An error occured: #{error}"
        else
          switch response.statusCode
            when 409
              if response.headers["x-transmission-session-id"]
                @sessionId = response.headers["x-transmission-session-id"]
                end = false
                @.runRemoteCommand params, callback
              else
                retVal.message = "Session id not present"
            when 200
              retVal.success = true
              retVal.response = body
            else retVal.message = "Error, code: #{response.statusCode}"
    
         callback retVal if end && callback
    

    我暂时不接受这个答案,因为我仍然不知道“原始”版本出了什么问题。

    好吧,我能够绕过问题,但没有解决问题,使用,这也简化了我的代码。最新版本如下所示:

    runRemoteCommand: (params, callback = false) =>
      options =
        uri: @uri
        method: "POST"
        json: params
    
      if @sessionId
        options.headers = 
          "X-Transmission-Session-Id": @sessionId
    
      request options, (error, response, body) =>
        retVal = 
          success: false
        end = true
    
        if error
          retVal.message = "An error occured: #{error}"
        else
          switch response.statusCode
            when 409
              if response.headers["x-transmission-session-id"]
                @sessionId = response.headers["x-transmission-session-id"]
                end = false
                @.runRemoteCommand params, callback
              else
                retVal.message = "Session id not present"
            when 200
              retVal.success = true
              retVal.response = body
            else retVal.message = "Error, code: #{response.statusCode}"
    
         callback retVal if end && callback
    

    我暂时不接受这个答案,因为我仍然不知道“原始”版本出了什么问题。

    与我上过这门课的问题相同。我在想一个更好的方法来获取数据,方法。但它是有效的

    http = require "http"
    _ = require "underscore"
    
    class Connect
      constructor: (@login, @password, @host='127.0.0.1', @port=9091, @headers={}) ->
    
      getData: (params)->
        key = "x-transmission-session-id"
    
        options = {
          host: @host
          port: @port
          path: '/transmission/rpc',
          method: 'POST',
          headers: @headers || {},
          auth: "#{ @login }:#{ @password }"  
        }
    
        _.extend options, params || {}
    
        req = http.request(options, (res)=>
          if res.statusCode == 401
            console.log "Auth errror"
    
          else if res.statusCode == 409
            auth_header={}
            auth_header[key] = res.headers[key]
    
            _.extend @headers, auth_header
            @getData(params)
    
          else if res.statusCode == 200
            res.setEncoding 'utf8'
            res.on('data', (chunk)->
              #here should be an emmit of data
              console.log chunk
            )
    
          else
            console.log "Error #{ res.statusCode }"
    
        )
        req.write('data\n')
        req.write('data\n')
        req.end()
    
    connector = new Connect "transmission", "password"
    
    connector.getData()
    

    这门课我也上过同样的课。我在想一个更好的方法来获取数据,方法。但它是有效的

    http = require "http"
    _ = require "underscore"
    
    class Connect
      constructor: (@login, @password, @host='127.0.0.1', @port=9091, @headers={}) ->
    
      getData: (params)->
        key = "x-transmission-session-id"
    
        options = {
          host: @host
          port: @port
          path: '/transmission/rpc',
          method: 'POST',
          headers: @headers || {},
          auth: "#{ @login }:#{ @password }"  
        }
    
        _.extend options, params || {}
    
        req = http.request(options, (res)=>
          if res.statusCode == 401
            console.log "Auth errror"
    
          else if res.statusCode == 409
            auth_header={}
            auth_header[key] = res.headers[key]
    
            _.extend @headers, auth_header
            @getData(params)
    
          else if res.statusCode == 200
            res.setEncoding 'utf8'
            res.on('data', (chunk)->
              #here should be an emmit of data
              console.log chunk
            )
    
          else
            console.log "Error #{ res.statusCode }"
    
        )
        req.write('data\n')
        req.write('data\n')
        req.end()
    
    connector = new Connect "transmission", "password"
    
    connector.getData()
    

    我真的不知道这对我有什么用处。我在使用标准库在Node.js中编写客户端时遇到了问题,而根本没有编写客户端。我又写了两个,一个在php中,一个在Node.js中,使用mikeal的请求库,以供参考,它们工作得非常好。我的问题是,我不知道是什么原因使这个特定的代码冻结,而不是从远程传输接收响应。我真的不知道这对我有什么用处。我在使用标准库在Node.js中编写客户端时遇到了问题,而根本没有编写客户端。我又写了两个,一个在php中,一个在Node.js中,使用mikeal的请求库,以供参考,它们工作得非常好。我的问题是,我不知道是什么让这个特定的代码冻结,而不是从远程传输接收响应。
    http = require "http"
    _ = require "underscore"
    
    class Connect
      constructor: (@login, @password, @host='127.0.0.1', @port=9091, @headers={}) ->
    
      getData: (params)->
        key = "x-transmission-session-id"
    
        options = {
          host: @host
          port: @port
          path: '/transmission/rpc',
          method: 'POST',
          headers: @headers || {},
          auth: "#{ @login }:#{ @password }"  
        }
    
        _.extend options, params || {}
    
        req = http.request(options, (res)=>
          if res.statusCode == 401
            console.log "Auth errror"
    
          else if res.statusCode == 409
            auth_header={}
            auth_header[key] = res.headers[key]
    
            _.extend @headers, auth_header
            @getData(params)
    
          else if res.statusCode == 200
            res.setEncoding 'utf8'
            res.on('data', (chunk)->
              #here should be an emmit of data
              console.log chunk
            )
    
          else
            console.log "Error #{ res.statusCode }"
    
        )
        req.write('data\n')
        req.write('data\n')
        req.end()
    
    connector = new Connect "transmission", "password"
    
    connector.getData()