2017-10-18 23 views
0

我正在努力解决期望与功能之间的矛盾,希望有人能帮助我,或者至少证实我'我不疯了。POST正文没有填充PHP curl请求设置为应用程序/ json for TFS REST端点

我正尝试在本地Microsoft TFS REST端点上使用Node.js和PHP作为数据的主要处理器来构建双向Slack集成。我可以使用NTLM身份验证对本地TFS安装成功执行GET,并将数据解析为Slack。所以我知道(1)端点正在工作,并且(2)我能够对其进行身份验证。

但是,为了运行针对TFS REST端点的查询,您必须发送内容类型为“application/json”或“application/json + patch”的请求。无论我做什么,在PHP中使用curl或在Node.js应用程序中使用本地方法,我都无法将请求正文中的查询发送到端点。使用另一个页面来测试这一点,如果我将内容类型设置为“multipart/form-data”或其他标准类型,我可以发送主体,但TFS会拒绝这些请求,因为它们的内容类型错误。

有没有人有任何想法如何发送内容类型的“应用程序/ json”将包括正文使用PHP或Node.js的POST请求?

下面是我一直使用的确切PHP(不发布机构,但确实可以通过使用PHP的file_get_contents(读取数据后“的php://输入”)):

$ch = curl_init(); 
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setopt($ch, CURLOPT_POST, TRUE); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER,TRUE); 
curl_setopt($ch, CURLOPT_HEADER, TRUE); 
curl_setopt($ch, CURLOPT_URL,$baseURL);  
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM); 
curl_setopt($ch, CURLOPT_USERPWD, $userpwd); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json', 
    'Transfer-Encoding: chunked', 
    'x-metadata: testing', 
    'x-testing: This is a value' 
)); 
$result = curl_exec($ch); 

这里是来自TFS的错误响应:

“您必须在请求的正文中传递查询对象。”

如果我改变了删除的内容类型,标题完全,身体被发送(通过另一个PHP页面确认),但后来我得到这个错误从TFS:

“的请求指示的内容类型“application/x-www-form-urlencoded”为不支持的方法类型“POST”,此方法的有效内容类型为:application/json,application/json-patch + json。“

更新

这样我就可以得到一个请求,通过使用自定义请求主体传递给HTTP端点,但是当它试图连接到HTTPS端点托管TFS例如,所有的标题是下降,这将返回上面的最后一个错误。发送到https

页眉:

'request_header' => string 'POST /tfs/{PROJECT}/_apis/wit/wiql?api-version=2.0 HTTP/1.1 
Authorization: NTLM {TOKEN} 

页眉发送到http:

'request_header' => string 'POST /dev/tfs/post.php HTTP/1.1 
Host: {HOST} 
Accept: */* 
Transfer-Encoding: chunked 
x-metadata: testing 
x-testing: This is a value 
Content-Type: application/json 
40 
' (length=203) 

这里是更新PHP:

$ch = curl_init(); 
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
// curl_setopt($ch, CURLOPT_POST, TRUE); 
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER,TRUE); 
curl_setopt($ch, CURLOPT_HEADER, TRUE); 
curl_setopt($ch, CURLOPT_URL,$baseURL);  
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM); 
curl_setopt($ch, CURLOPT_USERPWD, $userpwd); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json', 
    'Transfer-Encoding: chunked', 
    'x-metadata: testing', 
    'x-testing: This is a value' 
)); 
$result = curl_exec($ch); 

更新#2

现在,头中的“Content-Type:application/json”更改为“Accept:application/json”使主体发布到http端点,但仍从https端点删除标题。

更新#3 我可以用我的Chrome浏览器中的Restlet这个端点成功的请求,所以它不会出现在PHP脚本和卷曲之间的传输与TFS端点的问题,而是事提出请求。

+0

尝试删除 '''curl_setopt($ CH,CURLOPT_POST,TRUE);''' 并添加 ' ''curl_setopt($ ch,CURLOPT_CUSTOMREQUEST,“POST”); curl_setopt($ ch,CURLOPT_POSTFIELDS,json_encode($ postBody));''' –

+0

刚刚尝试过,并由于某种原因连接到TFS端点(https)导致头完全放弃,而它似乎在工作标准http连接(到另一台服务器)。 'request_header'=>字符串 'POST /tfs/[project]/_apis/wit/wiql?api-version=2.0 HTTP/1.1 授权:NTLM [令牌] HTTP标题: 'request_header'=>字符串' POST /dev/tfs/post.php HTTP/1.1 主机:www.holyelvis.com 接受:*/* 传输编码:分块 的X的元数据:测试 的x测试:这是一个值 内容 - 类型:application/x-www-form-urlencoded '(length = 203) – ctgilley

+0

请确保将内容类型头中的分号更改为冒号。 这是我测试过的一个要点在本地生成一个有效的json请求。也许你可以从那里工作? https://gist.github.com/raddeus/a02c7fcb8ecec37c90f515dacc5fc506 –

回答

0

您可以通过添加以下捕获请求和响应头:

curl_setopt($ch, CURLOPT_ENCODING,""); 
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); 
curl_setopt($ch, CURLOPT_TIMEOUT,10); 
curl_setopt($ch, CURLOPT_FAILONERROR,true); 
curl_setopt($ch, CURLOPT_ENCODING,""); 

curl_setopt($ch, CURLOPT_VERBOSE, true); 
curl_setopt($ch, CURLINFO_HEADER_OUT, true); 
curl_setopt($ch, CURLOPT_HEADER, true); 

$data = curl_exec($ch); 
if (curl_errno($ch)){ 
    echo 'Retreive Base Page Error: ' . curl_error($ch); 
} 
else { 
    $info = rawurldecode(var_export(curl_getinfo($ch),true)); 
    $skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE)); 
    $responseHeader= substr($data,0,$skip); 

echo "<pre>$info\n================\n$responseHeader\n===============\n"; 
echo substr($data,$skip); 
相关问题