1*2a97ec55SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*2a97ec55SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*2a97ec55SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*2a97ec55SAndrew Rist  * distributed with this work for additional information
6*2a97ec55SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*2a97ec55SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*2a97ec55SAndrew Rist  * "License"); you may not use this file except in compliance
9*2a97ec55SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*2a97ec55SAndrew Rist  *
11*2a97ec55SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*2a97ec55SAndrew Rist  *
13*2a97ec55SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*2a97ec55SAndrew Rist  * software distributed under the License is distributed on an
15*2a97ec55SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2a97ec55SAndrew Rist  * KIND, either express or implied.  See the License for the
17*2a97ec55SAndrew Rist  * specific language governing permissions and limitations
18*2a97ec55SAndrew Rist  * under the License.
19*2a97ec55SAndrew Rist  *
20*2a97ec55SAndrew Rist  *************************************************************/
21*2a97ec55SAndrew Rist 
22*2a97ec55SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir 
25cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
26cdf0e10cSrcweir #include "precompiled_extensions.hxx"
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include "soaprequest.hxx"
29cdf0e10cSrcweir #include "errormail.hxx"
30cdf0e10cSrcweir #include "config.hxx"
31cdf0e10cSrcweir #include <boost/shared_ptr.hpp>
32cdf0e10cSrcweir #include <com/sun/star/lang/XMultiComponentFactory.hpp>
33cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34cdf0e10cSrcweir #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
35cdf0e10cSrcweir #include <rtl/strbuf.hxx>
36cdf0e10cSrcweir #include <rtl/ustring.hxx>
37cdf0e10cSrcweir 
38cdf0e10cSrcweir 
39cdf0e10cSrcweir using namespace com::sun::star::uno;
40cdf0e10cSrcweir using namespace com::sun::star::lang;
41cdf0e10cSrcweir using namespace com::sun::star::io;
42cdf0e10cSrcweir using boost::shared_ptr;
43cdf0e10cSrcweir using com::sun::star::io::XOutputStream;
44cdf0e10cSrcweir using com::sun::star::ucb::XSimpleFileAccess;
45cdf0e10cSrcweir using rtl::OUString;
46cdf0e10cSrcweir using rtl::OString;
47cdf0e10cSrcweir using rtl::OStringBuffer;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir 
50cdf0e10cSrcweir namespace
51cdf0e10cSrcweir {
asUlong(sal_Int8 input)52cdf0e10cSrcweir     static unsigned long asUlong(sal_Int8 input)
53cdf0e10cSrcweir     {
54cdf0e10cSrcweir         return *reinterpret_cast<unsigned char *>(&input);
55cdf0e10cSrcweir     };
56cdf0e10cSrcweir 
base64_encode(const Sequence<sal_Int8> & input)57cdf0e10cSrcweir     static Sequence<sal_Int8> base64_encode(const Sequence<sal_Int8>& input)
58cdf0e10cSrcweir     {
59cdf0e10cSrcweir         static const char base64_tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
60cdf0e10cSrcweir         Sequence<sal_Int8> result(4);
61cdf0e10cSrcweir         unsigned long value = asUlong(input[0]) << 16;
62cdf0e10cSrcweir         if(input.getLength() > 1) value |= asUlong(input[1]) << 8;
63cdf0e10cSrcweir         if(input.getLength() > 2) value |= asUlong(input[2]);
64cdf0e10cSrcweir 
65cdf0e10cSrcweir         result[0] = static_cast<sal_Int8>(base64_tab[(value >> 18) & 0x3F]);
66cdf0e10cSrcweir         result[1] = static_cast<sal_Int8>(base64_tab[(value >> 12) & 0x3F]);
67cdf0e10cSrcweir         result[2] = static_cast<sal_Int8>('=');
68cdf0e10cSrcweir         result[3] = static_cast<sal_Int8>('=');
69cdf0e10cSrcweir 
70cdf0e10cSrcweir         if (input.getLength() > 1)
71cdf0e10cSrcweir         {
72cdf0e10cSrcweir             result[2] = base64_tab[(value >> 6) & 0x3F];
73cdf0e10cSrcweir             if (input.getLength() > 2)
74cdf0e10cSrcweir                  result[3] = base64_tab[(value >> 0) & 0x3F];
75cdf0e10cSrcweir         }
76cdf0e10cSrcweir         return result;
77cdf0e10cSrcweir     };
78cdf0e10cSrcweir 
replaceAll(const OString & str,sal_Char old,const OString & replacement)79cdf0e10cSrcweir     static OString replaceAll(const OString& str, sal_Char old, const OString& replacement)
80cdf0e10cSrcweir     {
81cdf0e10cSrcweir         OStringBuffer result;
82cdf0e10cSrcweir         sal_Int32 idx = 0;
83cdf0e10cSrcweir         do {
84cdf0e10cSrcweir             result.append(str.getToken(0, old, idx));
85cdf0e10cSrcweir             if(idx>=0) result.append(replacement);
86cdf0e10cSrcweir         } while(idx >= 0);
87cdf0e10cSrcweir         return result.makeStringAndClear();
88cdf0e10cSrcweir     };
89cdf0e10cSrcweir 
xmlEncode(const OString & input)90cdf0e10cSrcweir     static OString xmlEncode(const OString& input)
91cdf0e10cSrcweir     {
92cdf0e10cSrcweir         OString result = replaceAll(input, '&', OString("&amp;"));
93cdf0e10cSrcweir         result = replaceAll(result, '<', OString("&lt;"));
94cdf0e10cSrcweir         return replaceAll(result, '>', OString("&gt;"));
95cdf0e10cSrcweir     }
96cdf0e10cSrcweir 
createSequenceFromString(const OString & str)97cdf0e10cSrcweir     static shared_ptr<Sequence<sal_Int8> > createSequenceFromString(const OString& str)
98cdf0e10cSrcweir     {
99cdf0e10cSrcweir         const sal_Int32 size = str.getLength();
100cdf0e10cSrcweir         shared_ptr<Sequence<sal_Int8> > result(new Sequence<sal_Int8>(size));
101cdf0e10cSrcweir         for(sal_Int32 idx=0; idx < size; idx++)
102cdf0e10cSrcweir             (*result)[idx] = str[idx];
103cdf0e10cSrcweir         return result;
104cdf0e10cSrcweir     };
105cdf0e10cSrcweir 
writeString(const Reference<XOutputStream> & target,const OString & str)106cdf0e10cSrcweir     static void writeString(const Reference<XOutputStream>& target, const OString& str)
107cdf0e10cSrcweir     {
108cdf0e10cSrcweir         shared_ptr<Sequence<sal_Int8> > seq = createSequenceFromString(str);
109cdf0e10cSrcweir         target->writeBytes(*seq);
110cdf0e10cSrcweir     };
111cdf0e10cSrcweir 
writeFile(const Reference<XMultiServiceFactory> & sf,const Reference<XOutputStream> & target,const OUString & fileurl)112cdf0e10cSrcweir     static void writeFile(const Reference<XMultiServiceFactory>& sf, const Reference<XOutputStream>& target, const OUString& fileurl)
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir         Reference<XSimpleFileAccess> file_access(
115cdf0e10cSrcweir             sf->createInstance(OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess")),
116cdf0e10cSrcweir             UNO_QUERY);
117cdf0e10cSrcweir         Reference<XInputStream> file = file_access->openFileRead(fileurl);
118cdf0e10cSrcweir         const sal_Int32 bufsize = 3;
119cdf0e10cSrcweir         sal_Int32 bytes_read;
120cdf0e10cSrcweir         Sequence<sal_Int8> buf(bufsize);
121cdf0e10cSrcweir         do
122cdf0e10cSrcweir         {
123cdf0e10cSrcweir             bytes_read = file->readBytes(buf, bufsize);
124cdf0e10cSrcweir             if(bytes_read < buf.getLength()) buf.realloc(bytes_read);
125cdf0e10cSrcweir             if(bytes_read) target->writeBytes(base64_encode(buf));
126cdf0e10cSrcweir         } while(bytes_read == bufsize);
127cdf0e10cSrcweir     };
128cdf0e10cSrcweir 
129cdf0e10cSrcweir     static const OString SOAP_START(
130cdf0e10cSrcweir         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
131cdf0e10cSrcweir         "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\n"
132cdf0e10cSrcweir         "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\n"
133cdf0e10cSrcweir         "xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"\n"
134cdf0e10cSrcweir         "xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\"\n"
135cdf0e10cSrcweir         "xmlns:rds=\"urn:ReportDataService\"\n"
136cdf0e10cSrcweir         "xmlns:apache=\"http://xml.apache.org/xml-soap\"\n"
137cdf0e10cSrcweir         "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
138cdf0e10cSrcweir         "<SOAP-ENV:Body>\n"
139cdf0e10cSrcweir         "<rds:submitReport>\n");
140cdf0e10cSrcweir     static const OString SOAP_ITEMS_START("<hash xsi:type=\"apache:Map\">\n");
141cdf0e10cSrcweir     static const OString SOAP_ITEMS_END("</hash>\n");
142cdf0e10cSrcweir     static const OString SOAP_END(
143cdf0e10cSrcweir         "</rds:submitReport>\n"
144cdf0e10cSrcweir         "</SOAP-ENV:Body>\n"
145cdf0e10cSrcweir         "</SOAP-ENV:Envelope>\n");
146cdf0e10cSrcweir     static const OString SOAP_ITEM_END("]]></value></item>\n");
147cdf0e10cSrcweir 
getSoapOfficeversion(const Reference<XMultiServiceFactory> & sf)148cdf0e10cSrcweir     static const OString getSoapOfficeversion(const Reference<XMultiServiceFactory>& sf)
149cdf0e10cSrcweir     {
150cdf0e10cSrcweir         return ::rtl::OUStringToOString(oooimprovement::Config(sf).getCompleteProductname(), RTL_TEXTENCODING_ASCII_US);
151cdf0e10cSrcweir     };
152cdf0e10cSrcweir 
getSoapSoapId(const Reference<XMultiServiceFactory> & sf,const OString & soap_id)153cdf0e10cSrcweir     static const OString getSoapSoapId(const Reference<XMultiServiceFactory>& sf, const OString& soap_id)
154cdf0e10cSrcweir     {
155cdf0e10cSrcweir         OStringBuffer buf;
156cdf0e10cSrcweir         buf.append("<body xsi:type=\"xsd:string\">");
157cdf0e10cSrcweir         buf.append(xmlEncode(soap_id)).append("\n");
158cdf0e10cSrcweir         buf.append(xmlEncode(getSoapOfficeversion(sf))).append("\n");
159cdf0e10cSrcweir         buf.append("</body>\n");
160cdf0e10cSrcweir         return buf.makeStringAndClear();
161cdf0e10cSrcweir     };
162cdf0e10cSrcweir 
getSoapItemStart(const OString & key)163cdf0e10cSrcweir     static const OString getSoapItemStart(const OString& key)
164cdf0e10cSrcweir     {
165cdf0e10cSrcweir         OStringBuffer buf =
166cdf0e10cSrcweir             "<item>\n"
167cdf0e10cSrcweir             "<key xsi:type=\"xsd:string\">" + key + "</key>\n"
168cdf0e10cSrcweir             "<value xsi:type=\"xsd:string\"><![CDATA[";
169cdf0e10cSrcweir         return buf.makeStringAndClear();
170cdf0e10cSrcweir     };
171cdf0e10cSrcweir }
172cdf0e10cSrcweir 
173cdf0e10cSrcweir namespace oooimprovement
174cdf0e10cSrcweir {
SoapRequest(const Reference<XMultiServiceFactory> & sf,const OUString & soap_id,const OUString & logfile)175cdf0e10cSrcweir     SoapRequest::SoapRequest(const Reference<XMultiServiceFactory>& sf, const OUString& soap_id, const OUString& logfile)
176cdf0e10cSrcweir         : m_ServiceFactory(sf)
177cdf0e10cSrcweir         , m_SoapId(soap_id)
178cdf0e10cSrcweir         , m_Logfile(logfile)
179cdf0e10cSrcweir     {}
180cdf0e10cSrcweir 
writeTo(const Reference<XOutputStream> & target) const181cdf0e10cSrcweir      void SoapRequest::writeTo(const Reference<XOutputStream>& target) const
182cdf0e10cSrcweir     {
183cdf0e10cSrcweir         writeString(target, SOAP_START);
184cdf0e10cSrcweir             writeString(
185cdf0e10cSrcweir                 target,
186cdf0e10cSrcweir                 getSoapSoapId(m_ServiceFactory, rtl::OUStringToOString(m_SoapId, RTL_TEXTENCODING_ASCII_US)));
187cdf0e10cSrcweir             writeString(target, SOAP_ITEMS_START);
188cdf0e10cSrcweir                 writeString(target, getSoapItemStart("reportmail.xml"));
189cdf0e10cSrcweir                     writeString(target, Errormail(m_ServiceFactory).getXml());
190cdf0e10cSrcweir                 writeString(target, SOAP_ITEM_END);
191cdf0e10cSrcweir                 writeString(target, getSoapItemStart("data.zip"));
192cdf0e10cSrcweir                     writeFile(m_ServiceFactory, target, m_Logfile);
193cdf0e10cSrcweir                 writeString(target, SOAP_ITEM_END);
194cdf0e10cSrcweir             writeString(target, SOAP_ITEMS_END);
195cdf0e10cSrcweir         writeString(target, SOAP_END);
196cdf0e10cSrcweir     }
197cdf0e10cSrcweir }
198