【问题标题】:Opscode Chef REST API invalid JSONOpscode Chef REST API 无效 JSON
【发布时间】:2014-06-20 19:53:57
【问题描述】:

我正在尝试通过PHPChef 集成

我使用库https://github.com/dv1r/php-chefHosted Enterprise Chef 进行通信。当我从Chef 检索信息时,一切都很好。我也可以删除客户之类的。

当我尝试向服务器发送数据时,问题就开始了。我总是收到错误“无效的 JSON”。 我发送的 JSON 根据http://jsonlint.com/ 是有效的。

有人知道我是否需要向json_encode() 添加和编码类型以解决此问题?

代码示例:

    try{
        // Gets current data in Data-Bad `evns` Item `dev` (works)
        $res = $this->chef->get('/data/envs/dev');
    } catch (Exception $e){
        echo("Exception: ".$e->getMessage());
    }
    // Alter Data
    $res->testtt = "testess";
    try{
        // Set's new data to Data-bag `envs` Item `dev` (FAILS)
        $ret = $this->chef->put("/data/envs/dev",$res);
    } catch (Exception $e){
        die("Exception: <br>".$e->getMessage());
    }

图书馆的有趣部分:

    // json encode data
    if ($data && !is_string($data)) {
        $data = json_encode($data,JSON_UNESCAPED_UNICODE);
        $this->debug("data encoded to json: {$data}");
    }

    // sign the request
    $this->sign($endpoint, $method, $data, $header);
    $this->debug("request URL: {$url}");
    // initiate curl
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);

    // most people are using self-signed certs for chef, so its easiest to just
    // disable ssl verification
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

    // add data to post and put requests
    if ($method == 'POST' || $method == 'PUT')
    {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    // execute
    $raw_response = curl_exec($ch);

如果我遗漏了一些重要信息,请发表评论,我会补充。

谢谢。

编辑:更多调试信息 -

原始响应:

第一次调用 API (GET) raw_response: {"name":"name","id":"dev"}

第二次调用(PUT)raw_response: {"error":["invalid JSON"]}

curl_getinfo($ch) [PUT] 的输出:

    Array
    (
        [url] => https://api.opscode.com/organizations/MY_ORG/data/envs/dev
        [content_type] => text/html
        [http_code] => 400
        [header_size] => 426
        [request_size] => 1665
        [filetime] => -1
        [ssl_verify_result] => 0
        [redirect_count] => 1
        [total_time] => 0.175739
        [namelookup_time] => 2.0E-5
        [connect_time] => 0.02709
        [pretransfer_time] => 0.093261
        [size_upload] => 0
        [size_download] => 26
        [speed_download] => 147
        [speed_upload] => 0
        [download_content_length] => 26
        [upload_content_length] => 0
        [starttransfer_time] => 0.126115
        [redirect_time] => 0.049605
        [certinfo] => Array()
        [primary_ip] => 184.106.28.81
        [primary_port] => 443
        [local_ip] => xxx.xxx.xxx.50
        [local_port] => 33329
        [redirect_url] => 
        [request_header] => PUT /organizations/MY_ORG/data/envs/dev HTTP/1.1
    Host: api.opscode.com
    Accept: application/json
    Content-Type: application/json
    X-Chef-Version: 11.8.2
    X-Ops-Sign: algorithm=sha1;version=1.0
    X-Ops-UserId: USER
    X-Ops-Timestamp: 2014-05-07T13:39:55Z
    X-Ops-Content-Hash: qk8fSIReFrOMJ+Wk2y8yoe3EAgk=
    X-Ops-Authorization-1: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    X-Ops-Authorization-2: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    X-Ops-Authorization-3: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    X-Ops-Authorization-4: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    X-Ops-Authorization-5: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    X-Ops-Authorization-6: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    )

【问题讨论】:

  • $data = json_encode($data,JSON_UNESCAPED_UNICODE); 你玩过这条线吗?更改内容类型等?
  • 是的,我试过JSON_HEX_TAGJSON_HEX_APOSJSON_HEX_QUOTJSON_HEX_AMPJSON_UNESCAPED_UNICODE。 (JSON_UNESCAPED_UNICODE 对我来说似乎最合乎逻辑。)
  • 我认为该错误具有误导性 - 也许您的有效负载解析为 JSON 就好了,但它不是有效的 Chef JSON。你能粘贴更多的调试输出吗?您发送的实际有效负载是什么?查看请求中的响应代码也很有帮助。该方法的 API 响应代码:docs.opscode.com/api_chef_server.html#data-name-item
  • @Christopher Armstrong,我添加了一些信息,但我不确定如何在请求有效负载发出之前检查它。在此处添加到请求中curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  • 你想PUT做什么?因为您发送的标头是您要发送的 JSON,那是您真正要发送的吗?尝试发送 POST 而不是 PUT

标签: php json api rest chef-infra


【解决方案1】:

$res->testtt 将是您的主要问题。

“神奇”转换在某种程度上是错误的。 投射到数组中,您将最安全地完成操作

即:

try{
    // Gets current data in Data-Bad `evns` Item `dev` (works)
    $res = (array) $this->chef->get('/data/envs/dev');
} catch (Exception $e){
    echo("Exception: ".$e->getMessage());
}
// Alter Data
$res['testtt'] = "testess";
try{
    // Set's new data to Data-bag `envs` Item `dev` (FAILS)
    $ret = $this->chef->put("/data/envs/dev",$res);
} catch (Exception $e){
    die("Exception: <br>".$e->getMessage());
}

希望它会有所帮助。

编辑一个工作示例

<?php
 $envs = unserialize($_POST['envs']);
 foreach($_POST["datas"] as $env => $items) {
  ksort($items,SORT_NATURAL);
  $old = (array) $chef->get("/data/livraisons/".$env);
  $new = array_merge($old,$items);
  ksort($new,SORT_NATURAL);
  $chef->put("/data/livraisons/".$env,$new);
 }
?>

希望对你有所帮助..

警告:

  1. 我在一个开源厨师服务器 (11.0.10) 上,也许就是这样 点(即使我对此表示怀疑)
  2. 我使用的是稍微不同的 不使用带有 json_encode 的常量的库版本...请参见此处: https://github.com/jenssegers/php-chef

【讨论】:

  • 还是Invalid JSON
猜你喜欢
  • 1970-01-01
  • 2016-03-29
  • 1970-01-01
  • 2012-04-04
  • 2012-04-14
  • 2019-12-14
  • 1970-01-01
  • 1970-01-01
  • 2016-06-28
相关资源
最近更新 更多