2

我正在尝试使用 Python 2.4 发送 HTTP 发布请求。我用wireshark分析了post请求,请求在数据中只包含"options=user:jo"而不是"options=user:john"。为什么 python 切断最后两个字符的任何建议。这也发生在较短和较长的字符串中。我必须使用这些库和 Python 2.4。

谢谢您的回复

我的脚本:

import base64
import httplib

data_string = urllib.urlencode({'options':'user:john'})

authheader =  'Basic ' + base64.encodestring("restuser:restbpm")

headers = {"Content-type": "application/x-www-form-urlencoded", "Authorization": authheader}

h = httplib.HTTPConnection('localhost:8080')

h.request('POST', '/bonita-server-rest/API/runtimeAPI/instantiateProcess/Leitungsauskunft--1.9', data_string, headers)

r = h.getresponse()

print r.read()

摘自wireshark

TCP

TCP segment data (17 bytes)  ..options=user:jo

TCP segment data (2 bytes)   hn

HTTP

Line-based text data: application/x-www-form-urlencoded

\r\n

options=user:jo

Е摘自服务器日志

Mai 07, 2013 4:29:41 PM org.apache.catalina.valves.RequestDumperValve invoke
INFO:             header=authorization=Basic cmVzdHVzZXI6cmVzdGJwbQ==
Mai 07, 2013 4:29:41 PM org.apache.catalina.valves.RequestDumperValve invoke
INFO:             locale=de_DE
Mai 07, 2013 4:29:41 PM org.apache.catalina.valves.RequestDumperValve invoke
INFO:             method=POST
Mai 07, 2013 4:29:41 PM org.apache.catalina.valves.RequestDumperValve invoke
INFO:          parameter=
options=user:jo 
Mai 07, 2013 4:29:41 PM org.apache.catalina.valves.RequestDumperValve invoke
INFO:           pathInfo=/API/runtimeAPI/instantiateProcess/Leitungsauskunft--1.9
Mai 07, 2013 4:29:41 PM org.apache.catalina.valves.RequestDumperValve invoke
INFO:           protocol=HTTP/1.1
Mai 07, 2013 4:29:41 PM org.apache.catalina.valves.RequestDumperValve invoke
INFO:        queryString=null

来自 Python 脚本的错误

<java.lang.IllegalArgumentException>
  <detailMessage>The options are null or not well set.</detailMessage>
<stackTrace>
    <trace>org.ow2.bonita.facade.impl.AbstractRemoteRuntimeAPIImpl.getAPI(AbstractRemoteRuntimeAPIImpl.java:62)</trace>
    <trace>org.ow2.bonita.facade.impl.AbstractRemoteRuntimeAPIImpl.instantiateProcess(AbstractRemoteRuntimeAPIImpl.java:178)</trace>
    <trace>sun.reflect.GeneratedMethodAccessor50.invoke(Unknown Source)</trace>
    <trace>sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)</trace>
    <trace>java.lang.reflect.Method.invoke(Method.java:601)</trace>
    <trace>org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:124)</trace>
    <trace>org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:247)</trace>
    <trace>org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:212)</trace>
    <trace>org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:202)</trace>
    <trace>org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:441)</trace>
    <trace>org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:418)</trace>
    <trace>org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:111)</trace>
    <trace>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:217)</trace>
    <trace>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:159)</trace>
    <trace>javax.servlet.http.HttpServlet.service(HttpServlet.java:717)</trace>
    <trace>org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)</trace>
    <trace>org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)</trace>
    <trace>org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)</trace>
    <trace>org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)</trace>
    <trace>org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:563)</trace>
    <trace>org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)</trace>
    <trace>org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)</trace>
    <trace>org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:615)</trace>
    <trace>org.bonitasoft.console.security.SessionFixationValve.invoke(SessionFixationValve.java:77)</trace>
    <trace>org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)</trace>
    <trace>org.apache.catalina.valves.RequestDumperValve.invoke(RequestDumperValve.java:156)</trace>
    <trace>org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)</trace>
    <trace>org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)</trace>
    <trace>org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)</trace>
    <trace>org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)</trace>
    <trace>java.lang.Thread.run(Thread.java:722)</trace>
  </stackTrace>
  <suppressedExceptions class="java.util.Collections$UnmodifiableRandomAccessList" resolves-to="java.util.Collections$UnmodifiableList">
    <c class="list"/>
    <list reference="../c"/>
  </suppressedExceptions>

将 Content Length 添加到 Header 后的服务器日志

Mai 08, 2013 2:03:19 PM org.apache.catalina.valves.RequestDumperValve invoke
INFO:          parameter=
options=user:john

带有 urllib2 代码的 Python

import urllib2
import urllib
import base64
import sys

url = "http://localhost:8080/bonita-server-rest/API/runtimeAPI/instantiateProcess/Leitungsauskunft--1.9"
data_string = urllib.urlencode({'options':'user:john'})

request_object = urllib2.Request(url, data_string)


authheader =  'Basic ' + base64.encodestring("restuser:restbpm")

request_object.add_header('Authorization', authheader)
request_object.add_header('Content-Type','application/x-www-form-urlencoded')
request_object.add_header('Content-length','21')


try: response = urllib2.urlopen(request_object).read()
except IOError, e: 
    print e.code
    print e.headers
4

2 回答 2

2

只是为了补充Bräd Wurst的答案。

来自 base64 文档:

base64.encodestring(s) 对可以包含任意二进制数据的字符串 s 进行编码,并返回包含一行或多行 base64 编码数据的字符串。encodestring() 返回一个字符串,其中包含一行或多行 base64 编码数据,始终包含一个额外的尾随换行符 ('\n')。

但是,base64.standard_b64encode(s)在这种情况下使用应该会有所帮助:

import base64
authheader = 'Basic ' + base64.standard_b64encode("restuser:restbpm")
authheader
'Basic cmVzdHVzZXI6cmVzdGJwbQ=='
于 2013-10-01T19:43:50.783 回答
1

我找到了问题的答案。在这条线后面

authheader =  'Basic ' + base64.encodestring("restuser:restbpm")

你必须添加这个[:-1]

在此示例中,您会看到原因。

import base64
authheader =  'Basic ' + base64.encodestring("restuser:restbpm")
authheader
'Basic cmVzdHVzZXI6cmVzdGJwbQ==\n'
authheader =  'Basic ' + base64.encodestring("restuser:restbpm")[:-1]
authheader
'Basic cmVzdHVzZXI6cmVzdGJwbQ=='

通过编码,他把它放在最后\n,这会在 http 请求中创建换行符并[:-1]切断这个字符。

非常感谢您的帮助;-)

于 2013-05-13T12:43:55.917 回答