00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef ULXR_OMIT_TCP_STUFF
00036
00037 #define ULXR_NEED_EXPORTS
00038 #include <ulxmlrpcpp/ulxmlrpcpp.h>
00039
00040 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
00041 #include <unistd.h>
00042 #endif
00043
00044 #include <cctype>
00045 #include <stdio.h>
00046 #include <sys/stat.h>
00047
00048 #include <fstream>
00049
00050 #include <ulxmlrpcpp/ulxr_http_client.h>
00051 #include <ulxmlrpcpp/ulxr_except.h>
00052 #include <ulxmlrpcpp/ulxr_http_protocol.h>
00053
00054
00055 namespace ulxr {
00056
00057
00058 ULXR_API_IMPL(void) BodyProcessor::process(const char * , unsigned )
00059 {
00060 }
00061
00062
00063 ULXR_API_IMPL0 BodyProcessor::~BodyProcessor()
00064 {
00065 }
00066
00067
00069
00070
00071 ULXR_API_IMPL0 HttpClient::HttpClient (HttpProtocol* prot)
00072 {
00073 ULXR_TRACE(ULXR_PCHAR("HttpClient(HttpProtocol*)"));
00074 protocol = prot;
00075 protocol->setChunkedTransfer(false);
00076 }
00077
00078
00079 ULXR_API_IMPL(void) HttpClient::interpreteHttpHeader()
00080 {
00081 ULXR_TRACE(ULXR_PCHAR("interpreteHttpHeader"));
00082 head_version = ULXR_PCHAR("");
00083 head_status = 500;
00084 head_phrase = ULXR_PCHAR("Internal error");
00085 protocol->splitHeaderLine(head_version, head_status, head_phrase);
00086 protocol->setPersistent(!protocol->determineClosing(head_version));
00087 }
00088
00089
00090 ULXR_API_IMPL(void) HttpClient::receiveResponse(BodyProcessor &proc)
00091 {
00092 ULXR_TRACE(ULXR_PCHAR("receiveResponse"));
00093 protocol->resetConnection();
00094
00095 char buffer[ULXR_RECV_BUFFER_SIZE];
00096 char *buff_ptr;
00097
00098 bool done = false;
00099 long readed;
00100 while (!done && ((readed = protocol->readRaw(buffer, sizeof(buffer))) > 0) )
00101 {
00102 buff_ptr = buffer;
00103
00104 if (!protocol->hasBytesToRead())
00105 done = true;
00106
00107 while (readed > 0)
00108 {
00109 Protocol::State state = protocol->connectionMachine(buff_ptr, readed);
00110 if (state == Protocol::ConnError)
00111 throw ConnectionException(TransportError,
00112 ulxr_i18n(ULXR_PCHAR("network problem occured")), 500);
00113
00114
00115 else if ( state == Protocol::ConnSwitchToBody
00116 || state == Protocol::ConnBody)
00117 {
00118 interpreteHttpHeader();
00119 proc.process(buff_ptr, readed);
00120 readed = 0;
00121 }
00122 }
00123 }
00124 }
00125
00126
00129 class StringProcessor : public BodyProcessor
00130 {
00131 public:
00132 StringProcessor(Cpp8BitString &str_ref)
00133 : target(str_ref) {}
00134
00135 public:
00136 virtual void process(const char *buffer, unsigned len)
00137 {
00138 target.append(buffer, len);
00139 }
00140
00141 private:
00142 Cpp8BitString ⌖
00143 };
00144
00145
00146 ULXR_API_IMPL(void) HttpClient::msgPUT(const Cpp8BitString &msg, const CppString &type,
00147 const CppString &resource)
00148 {
00149 ULXR_TRACE(ULXR_PCHAR("msgPUT"));
00150
00151 if (!protocol->isOpen() )
00152 protocol->open();
00153
00154 sendAuthentication();
00155 protocol->sendRequestHeader(ULXR_PCHAR("PUT"), resource, type, msg.length());
00156 #ifdef ULXR_USE_WXSTRING
00157 protocol->writeBody(msg.data(), msg.length());
00158 #else
00159 protocol->writeBody(msg.data(), msg.length());
00160 #endif
00161
00162 BodyProcessor bp;
00163 receiveResponse(bp);
00164 if (getHttpStatus() != 200)
00165 throw ConnectionException(TransportError, getHttpPhrase(), getHttpStatus());
00166
00167 if (!protocol->isPersistent() )
00168 protocol->close();
00169 }
00170
00171
00172 ULXR_API_IMPL(void) HttpClient::filePUT(const CppString &filename,
00173 const CppString &type,
00174 const CppString &resource)
00175 {
00176 ULXR_TRACE(ULXR_PCHAR("filePUT"));
00177
00178 if (!protocol->isOpen() )
00179 protocol->open();
00180
00181 FILE *ifs = fopen (getLatin1(filename).c_str(), "rb");
00182 if (ifs == 0)
00183 throw Exception(SystemError,
00184 ulxr_i18n(ULXR_PCHAR("Cannot open file: "))+filename);
00185
00186 struct stat statbuf;
00187 if (0 != stat (getLatin1(filename).c_str(), &statbuf) )
00188 throw Exception(SystemError,
00189 ulxr_i18n(ULXR_PCHAR("Could not get information about file: "))+filename);
00190
00191 sendAuthentication();
00192 protocol->sendRequestHeader(ULXR_PCHAR("PUT"), resource, type, statbuf.st_size);
00193
00194 char buffer [ULXR_SEND_BUFFER_SIZE];
00195 long readed;
00196 try {
00197 while (!feof(ifs))
00198 {
00199 readed = fread(buffer, 1, sizeof(buffer), ifs);
00200 if (readed < 0)
00201 throw Exception(SystemError,
00202 ulxr_i18n(ULXR_PCHAR("Could not read from file: "))+filename);
00203 protocol->writeBody(buffer, readed);
00204 }
00205 }
00206 catch (...)
00207 {
00208 fclose(ifs);
00209 throw;
00210 }
00211
00212
00213 fclose(ifs);
00214
00215 BodyProcessor bp;
00216 receiveResponse(bp);
00217
00218 if (getHttpStatus() != 200)
00219 throw ConnectionException(TransportError,
00220 getHttpPhrase(), getHttpStatus());
00221
00222 if (!protocol->isPersistent() )
00223 protocol->close();
00224 }
00225
00226
00227 ULXR_API_IMPL(Cpp8BitString) HttpClient::msgGET(const CppString &resource)
00228 {
00229 ULXR_TRACE(ULXR_PCHAR("msgGET"));
00230 Cpp8BitString ret;
00231
00232 if (!protocol->isOpen() )
00233 protocol->open();
00234
00235 sendAuthentication();
00236 protocol->sendRequestHeader(ULXR_PCHAR("GET"), resource, ULXR_PCHAR(""), 0);
00237 StringProcessor sp (ret);
00238 receiveResponse(sp);
00239 if (getHttpStatus() != 200)
00240 throw ConnectionException(TransportError, getHttpPhrase(), getHttpStatus());
00241
00242 if (!protocol->isPersistent() )
00243 protocol->close();
00244
00245 return ret;
00246 }
00247
00248
00251 class FileProcessor : public BodyProcessor
00252 {
00253 public:
00254 FileProcessor(std::ostream &ostr_ref, const CppString &fn)
00255 : target(ostr_ref), name(fn) {}
00256
00257 public:
00258 virtual void process(const char *buffer, unsigned len)
00259 {
00260 target.write(buffer, len);
00261 if (!target.good() )
00262 throw Exception(SystemError, ulxr_i18n(ULXR_PCHAR("Cannot write to file: "))+name);
00263 }
00264
00265 private:
00266 std::ostream ⌖
00267 CppString name;
00268 };
00269
00270
00271 ULXR_API_IMPL(void) HttpClient::fileGET(const CppString &filename,
00272 const CppString &resource)
00273 {
00274 ULXR_TRACE(ULXR_PCHAR("fileGET"));
00275
00276 if (!protocol->isOpen() )
00277 protocol->open();
00278
00279 std::ofstream ofs (getLatin1(filename).c_str(), std::ios::out | std::ios::binary);
00280 if (!ofs.good() )
00281 throw Exception(SystemError, ulxr_i18n(ULXR_PCHAR("Cannot create file: "))+filename);
00282
00283 sendAuthentication();
00284 protocol->sendRequestHeader(ULXR_PCHAR("GET"), resource, ULXR_PCHAR(""), 0);
00285
00286 FileProcessor fp(ofs, filename);
00287 receiveResponse(fp);
00288
00289 if (getHttpStatus() != 200)
00290 throw ConnectionException(TransportError, getHttpPhrase(), getHttpStatus());
00291
00292 if (!protocol->isPersistent() )
00293 protocol->close();
00294 }
00295
00296
00297 ULXR_API_IMPL(Cpp8BitString) HttpClient::msgPOST(
00298 const Cpp8BitString &msg,
00299 const CppString &type,
00300 const CppString &resource)
00301 {
00302 ULXR_TRACE(ULXR_PCHAR("msgPOST"));
00303 Cpp8BitString ret;
00304
00305 if (!protocol->isOpen() )
00306 protocol->open();
00307
00308 sendAuthentication();
00309 protocol->sendRequestHeader(ULXR_PCHAR("POST"), resource, type, msg.length());
00310 protocol->writeBody(msg.data(), msg.length());
00311
00312 StringProcessor sp (ret);
00313 receiveResponse(sp);
00314
00315 if (getHttpStatus() != 200)
00316 throw ConnectionException(TransportError, getHttpPhrase(), getHttpStatus());
00317
00318 if (!protocol->isPersistent() )
00319 protocol->close();
00320
00321 return ret;
00322 }
00323
00324
00325 ULXR_API_IMPL(void) HttpClient::doDELETE(const CppString &resource)
00326 {
00327 ULXR_TRACE(ULXR_PCHAR("doDELETE"));
00328
00329 if (!protocol->isOpen() )
00330 protocol->open();
00331
00332 sendAuthentication();
00333 protocol->sendRequestHeader(ULXR_PCHAR("DELETE"), resource, ULXR_PCHAR(""), 0);
00334
00335 BodyProcessor bp;
00336 receiveResponse(bp);
00337
00338 if (getHttpStatus() != 200)
00339 throw ConnectionException(TransportError, getHttpPhrase(), getHttpStatus());
00340
00341 if (!protocol->isPersistent() )
00342 protocol->close();
00343 }
00344
00345
00346 ULXR_API_IMPL(void) HttpClient::setMessageAuthentication(const CppString &user,
00347 const CppString &pass)
00348 {
00349 ULXR_TRACE(ULXR_PCHAR("setMessageAuthentication"));
00350 http_user = user;
00351 http_pass = pass;
00352 }
00353
00354
00355 ULXR_API_IMPL(void) HttpClient::sendAuthentication()
00356 {
00357 ULXR_TRACE(ULXR_PCHAR("sendAuthentication"));
00358 if (http_user.length() != 0 && http_pass.length() != 0)
00359 protocol->setMessageAuthentication(http_user, http_pass);
00360 }
00361
00362
00363 ULXR_API_IMPL(int) HttpClient::getHttpStatus() const
00364 {
00365 return head_status;
00366 }
00367
00368
00369 ULXR_API_IMPL(CppString) HttpClient::getHttpPhrase() const
00370 {
00371 return head_phrase;
00372 }
00373
00374
00375 ULXR_API_IMPL(CppString) HttpClient::getHttpVersion() const
00376 {
00377 return head_version;
00378 }
00379
00380
00381 }
00382
00383 #endif // ULXR_OMIT_TCP_STUFF
00384