0

特定の制限内でファイルをシステムにアップロードできる開発者の 1 人が作成した Web サービスを使用しようとしています。

SUDS を使用して、次の情報を取得します。

Suds ( https://fedorahosted.org/suds/ ) version: 0.4 GA  build: R699-20100913

Service ( ConnectToEFS ) tns="http://tempuri.org/"
   Prefixes (3)
      ns0 = "http://schemas.microsoft.com/2003/10/Serialization/"
      ns1 = "http://schemas.microsoft.com/Message"
      ns2 = "http://tempuri.org/"
   Ports (1):
      (BasicHttpBinding_IConnectToEFS)
         Methods (2):
            CreateContentFolder(xs:string FileCode, xs:string FolderName, xs:string ContentType, xs:string MetaDataXML, )
            UploadFile(ns1:StreamBody FileByteStream, )
         Types (4):
            ns1:StreamBody
            ns0:char
            ns0:duration
            ns0:guid

UploadFile を使用する私の方法は次のとおりです。

def webserviceUploadFile(self, targetLocation, fileName, fileSource):
    fileSource = './test_files/' + fileSource
    ntlm = WindowsHttpAuthenticated(username=uname, password=upass)
    client = Client(webservice_url, transport=ntlm)
    client.set_options(soapheaders={'TargetLocation':targetLocation, 'FileName': fileName})
    body = client.factory.create('AIRDocument')
    body_file = open(fileSource, 'rb')
    body_data = body_file.read()
    body.FileByteStream = body_data
    return client.service.UploadFile(body)

これを実行すると、次の結果が得られます。

Traceback (most recent call last):
  File "test_cases.py", line 639, in test_upload_file_invalid_extension
    result_string = self.HM.webserviceUploadFile('9999', 'AD-1234-5424__44.exe',
 'test_data.pdf')
  File "test_cases.py", line 81, in webserviceUploadFile
    return client.service.UploadFile(body)
  File "build\bdist.win32\egg\suds\client.py", line 542, in __call__
    return client.invoke(args, kwargs)
  File "build\bdist.win32\egg\suds\client.py", line 595, in invoke
    soapenv = binding.get_message(self.method, args, kwargs)
  File "build\bdist.win32\egg\suds\bindings\binding.py", line 120, in get_message
    content = self.bodycontent(method, args, kwargs)
  File "build\bdist.win32\egg\suds\bindings\document.py", line 63, in bodycontent
    p = self.mkparam(method, pd, value)
  File "build\bdist.win32\egg\suds\bindings\document.py", line 105, in mkparam
    return Binding.mkparam(self, method, pdef, object)
  File "build\bdist.win32\egg\suds\bindings\binding.py", line 287, in mkparam
    return marshaller.process(content)
  File "build\bdist.win32\egg\suds\mx\core.py", line 62, in process
    self.append(document, content)
  File "build\bdist.win32\egg\suds\mx\core.py", line 75, in append
    self.appender.append(parent, content)
  File "build\bdist.win32\egg\suds\mx\appender.py", line 102, in append
    appender.append(parent, content)
  File "build\bdist.win32\egg\suds\mx\appender.py", line 243, in append
    Appender.append(self, child, cont)
  File "build\bdist.win32\egg\suds\mx\appender.py", line 182, in append
    self.marshaller.append(parent, content)
  File "build\bdist.win32\egg\suds\mx\core.py", line 75, in append
    self.appender.append(parent, content)
  File "build\bdist.win32\egg\suds\mx\appender.py", line 102, in append
    appender.append(parent, content)
  File "build\bdist.win32\egg\suds\mx\appender.py", line 198, in append
    child.setText(tostr(content.value))
  File "build\bdist.win32\egg\suds\sax\element.py", line 251, in setText
    self.text = Text(value)
  File "build\bdist.win32\egg\suds\sax\text.py", line 43, in __new__
    result = super(Text, cls).__new__(cls, *args, **kwargs)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 10: ordinal
 not in range(128)

多くの調査と Web サービスの開発者との話し合いの後、body_data = body_file.read() を body_data = body_file.read().decode("UTF-8") に変更すると、次のエラーが発生します。

Traceback (most recent call last):
  File "test_cases.py", line 639, in test_upload_file_invalid_extension
    result_string = self.HM.webserviceUploadFile('9999', 'AD-1234-5424__44.exe', 'test_data.pdf')
  File "test_cases.py", line 79, in webserviceUploadFile
    body_data = body_file.read().decode("utf-8")
  File "C:\python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe2 in position 10: invalid
continuation byte

これはあまり役に立ちません。

この問題をさらに調査した後、'errors='ignore'' を UTF-8 エンコードに追加してみました。結果は次のとおりです。

<TransactionDescription>Error in INTL-CONF_France_PROJ_MA_126807.docx: An exception has been thrown when reading the stream.. Inner Exception: System.Xml.XmlException: The byte 0x03 is not valid at this location.  Line 1, position 318.
    at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
    at System.Xml.XmlUTF8TextReader.Read()
    at System.ServiceModel.Dispatcher.StreamFormatter.MessageBodyStream.Exhaust(XmlDictionaryReader reader)
    at System.ServiceModel.Dispatcher.StreamFormatter.MessageBodyStream.Read(Byte[] buffer, Int32 offset, Int32 count). Source: System.ServiceModel</TransactionDescription>

これは、何をすべきかについて私をかなり困惑させます。Web サービスによる結果のスタック トレースに基づくと、UTF-8 が必要なようですが、Python または SUDS が適合しない限り、またはエンコーディングの問題を無視しない限り、Web サービスに到達できないようです。私が取り組んでいるシステムは、MicroSoft オフィス タイプのファイル (doc、xls など)、PDF、および TXT ファイルしか取り込めないため、エンコーディングをより細かく制御できるものを使用することはできません。また、サンプル PDF とサンプル DOCX で使用されているエンコードを検出しようとしましたが、それが示唆するもの (Latin-1、ISO8859-x、およびいくつかの Windows XXXX) を使用すると、すべて Python と SUDS で受け入れられましたが、Web サービスでは受け入れられませんでした。

また、示されている例では、最も頻繁に無効な拡張子へのテストを参照していることにも注意してください。このエラーは、アップロードが成功したことをテストする必要がある場合でも適用されます。これは、最終的なスタック トレースが実際に表示される唯一の時間です。

4

1 に答える 1

2

これを使用するbase64.b64encode(body_file.read())と、base64文字列値が返されます。したがって、リクエスト変数は文字列である必要があります。

于 2012-07-18T08:47:10.453 に答える