我已经找到了如何使用pycurl进行GET,PUT,DELETE和基本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()
因此,我天真地认为POST等价物将是:
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@peru.local~ / src / calthorpe / calthorpe / server / calthorpe $ calthorpe / server / calthorpe POST -H'Content-type:application / vnd.ogc.sld + xml' -d @ /用户/ rburhum / src目录/卡索普/卡索普/服务器/卡索普/媒体/风格/ 1_my情景 “http://127.0.0.1:8080/geoserver/rest/styles?name=1_my-scenario”-v *即将连接()到127.0.0.1端口8080(#0) *尝试127.0.0.1 ...已连接 *连接到127.0.0.1(127.0.0.1)端口8080(#0) *服务器使用Basic使用'admin'
进行身份验证POST / geoserver / rest / styles?name = 1_my-scenario HTTP / 1.1 授权:基本YWRtaW46Z2Vvc2VydmVy User-Agent:curl / 7.21.4(universal-apple-darwin11.0)libcurl / 7.21.4 OpenSSL / 0.9.8r zlib / 1.2.5 主持人:127.0.0.1:8080 接受: / 内容类型:application / vnd.ogc.sld + xml 内容长度:28135 期待: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-Engine / 1.0..8 <转移编码:分块 < *连接#0到主机127.0.0.1保持不变 *关闭连接#0
我可以清楚地看到内容长度是正确的。
相反,当我对上面的POST代码进行详细输出时,我可以看到内容长度为-1(因此文件未被传递,服务器返回500)。我已经使用HTTPPOST变量进行了模拟,在某些组合下使内容长度正确,但我仍然无法获得上面的CURL命令的完全等效工作。
答案 0 :(得分:6)
我必须结合几个例子才能找到正确的组合,当然,我在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已经被软件化,所以不需要urlencode,否则,你可能想要这样做。