【问题标题】:Can libcurl.net be used to post a new page to confluence?可以使用 libcurl.net 将新页面发布到 Confluence 吗?
【发布时间】:2016-05-21 19:51:48
【问题描述】:

我刚刚开始使用 REST API 创建页面。

我正在尝试配置一个基本示例,我想使用 libcurl.net 来完成它。

有没有人知道为什么这不起作用?

更新:

到目前为止,这是我从 curllib.net “书帖”示例中改编的内容

 Option Explicit On
Imports System.IO
Imports System.Net
Imports SeasideResearch.LibCurlNet

Public Class CurlOperations

Public Shared Sub CurlPost()

    Try

        Dim credUserName As String = "username"
        Dim credPassword As String = "password"

        Dim response As String = Nothing
        Dim outputStdErr As Stream = Nothing

        Curl.GlobalInit(CURLinitFlag.CURL_GLOBAL_ALL)

        Dim easy As Easy
        easy = New Easy

        ' Set up write delegate
        Dim wf As Easy.WriteFunction
        wf = New Easy.WriteFunction(AddressOf OnWriteData)
        easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf)

        'Authentication
        easy.SetOpt(CURLoption.CURLOPT_HTTPAUTH, CURLhttpAuth.CURLAUTH_BASIC)
        easy.SetOpt(CURLoption.CURLOPT_USERPWD, credUserName & ":" & credPassword)

        'disable ssl peer verification
        easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER, False)

        'Header
        easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER, "Content-Type: application/json; charset=utf-8")

        ' Simple post - with a string
        easy.SetOpt(CURLoption.CURLOPT_POSTFIELDS, WikiTools.CommREST.WebToCF.PostCurl())

        ' and the rest of the cURL options
        easy.SetOpt(CURLoption.CURLOPT_USERAGENT, ".NET Framework Client")
        easy.SetOpt(CURLoption.CURLOPT_URL, "https://domain.com/confluence/rest/api/content/")
        easy.SetOpt(CURLoption.CURLOPT_POST, True)

        response = easy.Perform().ToString
        LoggingAndActivites.WriteLog("Response: " & response, GetFunctionName.GetCallerName, True, True)

    Catch ex As Exception

        LoggingAndActivites.WriteLog("Exception: " & ex.ToString, GetFunctionName.GetCallerName, True, True)

    End Try

    Curl.GlobalCleanup()

End Sub

' Called by libcURL.NET when it has data for your program
Public Shared Function OnWriteData(ByVal buf() As Byte, ByVal size As Int32, ByVal nmemb As Int32, ByVal extraData As Object) As Int32

    LoggingAndActivites.WriteLog(System.Text.Encoding.UTF8.GetString(buf), GetFunctionName.GetCallerName, True, True)

    Return size * nmemb

End Function

 End Class

我正在连接,因为如果我删除用户名和密码,我会通过“onWriteData”函数得到如下响应:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head>
<title>401 Unauthorized</title>
</head>
<body>
<h1>Unauthorized</h1>
<p>This server could not verify that you
are authorized to access the document
requested.  Either you supplied the wrong
credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.</p>
<hr>
<address>Apache Server at domain.com Port 7080</address>
</body>
</html>

现在的问题是,如果我正确登录,除了来自“easy.Perform()”函数的“CURLE_OK”之外,我没有得到任何响应。

这很好,因为我知道它在某种程度上有效。

【问题讨论】:

    标签: confluence-rest-api libcurl.net


    【解决方案1】:

    根据 libcurl.net 文档:http://www.libcurl.org/

    libcurl 还支持 HTTPS 证书、HTTP POST、HTTP PUT、FTP 上传、基于 HTTP 表单的上传、代理、cookie 和用户+密码身份验证。

    所以我想你应该能够用它进行 REST API 调用。我使用 curl(linux 版本)来创建和更新页面,使用如下:

    curl --globoff --insecure --silent -u username:password -X PUT -H 'Content-Type: application/json' --data @body.json confluenceRestAPIURL/pageId
    

    body.json 是一个包含更新页面数据的文件。

    我在这里写了一篇关于这个的博客:https://javamemento.blogspot.no/2016/05/jira-confluence-3.html

    您可以在这里获取代码:https://github.com/somaiah/jira-confluence-graphs

    【讨论】:

    • 感谢 Somaiah,这会派上用场的!
    【解决方案2】:

    它确实有效

    这是我添加/更改以使上述代码正常工作的内容

    'I added an Slist to store the header items (I only had one)            
    Dim slistHeaders As New Slist
    slistHeaders.Append("Content-Type: application/json")
    
    'Then I added the slist to the HTTPHEADER
    easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER, slistHeaders)
    

    注意事项:

    (1) URL 当然是第一件事

    在我的例子中,我使用的是 https://domain.com/confluence/rest/api/content/,因为 Confluence 文档假定您将使用根域名(就像我一样)

    然而,我不知道的是,给我测试的 URL 已经将我引导到“confluence”文件夹。

    所以我的 URI 需要改为 https://domain.com/rest/api/content/

    (2) 您的 HTTPHEADER 需要放入 Slist 的指示符是服务器返回的:415 Unsupported Media Type

    (3) 确保使用 CURLOPT_HEADER 属性。如果您在回复中看到此标头,则需要确保它未被使用:

    HTTP/1.1 500 Internal Server Error
    Date: Sun, 22 May 2016 17:50:32 GMT
    Server: Apache
    Content-Location: 500.en-GB.html
    Vary: negotiate,accept-language
    TCN: choice
    Accept-Ranges: bytes
    Content-Length: 7575
    Connection: close
    Content-Type: text/html; charset=UTF-8
    Content-Language: en-gb
    

    请参阅我的帖子了解原因:CURLOPT_HEADER

    (4) 最后,如果您在构建应用时收到此错误:

    An unhandled exception of type 'System.AccessViolationException' occurred in libcurl.NET.dll
    
    Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    

    这是由于 libcurl.net 进程未清理造成的。

    “cleanup()”方法在 DLL 中不可用,尽管已在示例中找到。

    因此,请在您的程序结束时使用 EASY.Dispose(),此错误将停止。 (我保留了“GlobalCleanup()”方法只是为了更好地衡量)

    (5) 具有讽刺意味的是,我选择了使用 CURL,因为我认为 Confluence 界面可能需要它。

    但现在看来并非如此,您只需使用 .NET 中的“HttpWebRequest”类即可获得相同的结果。

    但是,由于我被分配到的“轻量级”测试服务器崩溃了,我正在等待他们修复它,以便我可以验证这一点。

    无论如何,我希望这一切对某人有所帮助

    M

    【讨论】:

    • 另一个注意事项,不要在您的内容类型中使用“charset = utf-8”。有时有效,有时无效,但无论如何我都不需要。
    猜你喜欢
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 2017-03-10
    • 2022-10-13
    • 1970-01-01
    相关资源
    最近更新 更多