使用pycu发布文件并传递参数

2024-04-29 14:14:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经知道了如何使用pycurl进行GET、PUTs、DELETEs和basic POST。

尽管如此,我还是搞不懂这个curl命令行与python的等价物是什么:

curl -u admin:geoserver -XPOST -H 'Content-type: application/vnd.ogc.sld+xml' 
-d @/Users/rburhum/src/calthorpe/calthorpe/server/calthorpe/media/styles/1_my-scenario
"http://127.0.0.1:8080/geoserver/rest/styles?name=1_my-scenario" -v

I have seen the samples at the repo。不过,传递一个参数(在本例中为name)和要上载的文件似乎不起作用。

对于PUT呼叫,我已成功使用:

filesize = path.getsize(sldFile)
f = open(sldFile,'rb')

c = pycurl.Curl()

c.setopt(pycurl.HTTPHEADER, ["Content-type: application/vnd.ogc.sld+xml"])
c.setopt(pycurl.USERPWD, GEOSERVER_USER + ':' + GEOSERVER_PASSWORD)    
c.setopt(pycurl.INFILESIZE, filesize)
c.setopt(c.URL, str(GEOSERVER_URL + '/rest/styles/' + path.basename(sldFile)))
c.setopt(pycurl.PUT, 1)
c.setopt(pycurl.INFILE, f)
c.perform()
f.close()

因此,我天真地认为,职位相当于:

filesize = path.getsize(sldFile)
f = open(sldFile,'rb')

c = pycurl.Curl()

c.setopt(c.URL, str(GEOSERVER_URL + '/rest/styles?name=' + path.basename(sldFile)))
c.setopt(pycurl.POST, 1)
c.setopt(pycurl.HTTPHEADER, ["Content-type: application/vnd.ogc.sld+xml"])
c.setopt(pycurl.USERPWD, GEOSERVER_USER + ':' + GEOSERVER_PASSWORD)    
c.setopt(pycurl.INFILESIZE, filesize)
c.setopt(pycurl.INFILE, f)
c.perform()
f.close()

curl命令的详细输出显示如下:

(calthorpe_env)rburhum@秘鲁本地~/src/calthorpe/calthorpe/server/calthorpe $calthorpe/server/calthorpe POST-H'内容类型:application/vnd.ogc.sld+xml' -d@/Users/rburhum/src/calthorpe/calthorpe/server/calthorpe/media/styles/1我的场景 “http://127.0.0.1:8080/geoserver/rest/styles?名称=我的情景“-v *即将连接()到127.0.0.1端口8080(#0) *正在尝试127.0.0.1。。。有联系的 *连接到127.0.0.1(127.0.0.1)端口8080(#0) *对用户“admin”使用Basic进行服务器身份验证

POST /geoserver/rest/styles?name=1_my-scenario HTTP/1.1 Authorization: Basic YWRtaW46Z2Vvc2VydmVy User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5 Host: 127.0.0.1:8080 Accept: / Content-type: application/vnd.ogc.sld+xml Content-Length: 28135 Expect: 100-continue

>; <;HTTP/1.1 100继续 <;HTTP/1.1 201已创建 <;日期:2012年3月5日星期一07:39:43 GMT <;位置:http://127.0.0.1:8080/geoserver/rest/styles/1_my-scenario <;服务器:Noelios Restlet引擎/1.0..8 <;传输编码:分块 &中尉; *0到主机127.0.0.1的连接保持完好 *闭合连接#0

我可以清楚地看到内容长度是正确的。

相反,当我对上面的POST代码进行详细输出时,我可以看到内容长度是-1(因此文件不会被传递,服务器会返回500)。我使用HTTPPOST变量进行了模拟,在某些组合下,HTTPPOST变量使内容长度正确,但我仍然无法获得与上面的CURL命令完全相同的值。


Tags: ltogcrestapplicationgeoservercontentpostvnd
1条回答
网友
1楼 · 发布于 2024-04-29 14:14:26

我不得不结合几个例子来找到正确的组合,当然,我也从IRC频道的一些好人那里得到了一些帮助。我唯一能让它工作的方法就是对这个pycurl sample做一个微小的改变,它并没有像我描述的那样工作。

class FileReader:
    def __init__(self, fp):
        self.fp = fp
    def read_callback(self, size):
        return self.fp.read(size)

然后,我会这样设置调用:

c = pycurl.Curl()
c.setopt(c.URL, str(GEOSERVER_URL + '/rest/styles?name=' + path.basename(sldFile)))
c.setopt(pycurl.POST, 1)
filesize = path.getsize(sldFile)
f = open(sldFile,'rb')
c.setopt(pycurl.POSTFIELDSIZE, filesize)
c.setopt(pycurl.READFUNCTION, FileReader(f).read_callback)
c.setopt(pycurl.HTTPHEADER, ["Content-type: application/vnd.ogc.sld+xml"])
c.setopt(pycurl.USERPWD, GEOSERVER_USER + ':' + GEOSERVER_PASSWORD)

c.perform()
f.close()

请注意,原始样本没有使用POSTFIELDSIZE(只有INFILESIZE),没有它,我就无法使用它。

顺便说一句,在我的例子中,sldFile已经被sligify了,所以不需要urlencode,否则,您可能需要这样做。

相关问题 更多 >