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 #ifndef __XRD_CL_MESSAGE_UTILS_HH__
00026 #define __XRD_CL_MESSAGE_UTILS_HH__
00027
00028 #include "XrdCl/XrdClXRootDResponses.hh"
00029 #include "XrdCl/XrdClURL.hh"
00030 #include "XrdCl/XrdClMessage.hh"
00031 #include "XrdCl/XrdClUglyHacks.hh"
00032
00033 namespace XrdCl
00034 {
00035 class LocalFileHandler;
00036
00037
00039
00040 class SyncResponseHandler: public ResponseHandler
00041 {
00042 public:
00043
00045
00046 SyncResponseHandler():
00047 pStatus(0),
00048 pResponse(0),
00049 pCondVar(0) {}
00050
00051
00053
00054 virtual ~SyncResponseHandler()
00055 {
00056 }
00057
00058
00059
00061
00062 virtual void HandleResponse( XRootDStatus *status,
00063 AnyObject *response )
00064 {
00065 XrdSysCondVarHelper scopedLock(pCondVar);
00066 pStatus = status;
00067 pResponse = response;
00068 pCondVar.Broadcast();
00069 }
00070
00071
00073
00074 XRootDStatus *GetStatus()
00075 {
00076 return pStatus;
00077 }
00078
00079
00081
00082 AnyObject *GetResponse()
00083 {
00084 return pResponse;
00085 }
00086
00087
00089
00090 void WaitForResponse()
00091 {
00092 XrdSysCondVarHelper scopedLock(pCondVar);
00093 while (pStatus == 0) {
00094 pCondVar.Wait();
00095 }
00096 }
00097
00098 private:
00099 SyncResponseHandler(const SyncResponseHandler &other);
00100 SyncResponseHandler &operator = (const SyncResponseHandler &other);
00101
00102 XRootDStatus *pStatus;
00103 AnyObject *pResponse;
00104 XrdSysCondVar pCondVar;
00105 };
00106
00107
00108
00109
00110
00111 class NullResponseHandler: public XrdCl::ResponseHandler
00112 {
00113 public:
00114
00115
00116
00117 virtual void HandleResponseWithHosts( XrdCl::XRootDStatus *status,
00118 XrdCl::AnyObject *response,
00119 XrdCl::HostList *hostList )
00120 {
00121 delete this;
00122 }
00123 };
00124
00125
00126
00127
00128 struct MessageSendParams
00129 {
00130 MessageSendParams():
00131 timeout(0), expires(0), followRedirects(true), chunkedResponse(false),
00132 stateful(true), hostList(0), chunkList(0), redirectLimit(0) {}
00133 uint16_t timeout;
00134 time_t expires;
00135 HostInfo loadBalancer;
00136 bool followRedirects;
00137 bool chunkedResponse;
00138 bool stateful;
00139 HostList *hostList;
00140 ChunkList *chunkList;
00141 uint16_t redirectLimit;
00142 };
00143
00144 class MessageUtils
00145 {
00146 public:
00147
00149
00150 static XRootDStatus WaitForStatus( SyncResponseHandler *handler )
00151 {
00152 handler->WaitForResponse();
00153 XRootDStatus *status = handler->GetStatus();
00154 XRootDStatus ret( *status );
00155 delete status;
00156 return ret;
00157 }
00158
00159
00161
00162 template<class Type>
00163 static XrdCl::XRootDStatus WaitForResponse(
00164 SyncResponseHandler *handler,
00165 Type *&response )
00166 {
00167 handler->WaitForResponse();
00168
00169 AnyObject *resp = handler->GetResponse();
00170 XRootDStatus *status = handler->GetStatus();
00171 XRootDStatus ret( *status );
00172 delete status;
00173
00174 if( ret.IsOK() )
00175 {
00176 if( !resp )
00177 return XRootDStatus( stError, errInternal );
00178 resp->Get( response );
00179 resp->Set( (int *)0 );
00180 delete resp;
00181
00182 if( !response )
00183 return XRootDStatus( stError, errInternal );
00184 }
00185
00186 return ret;
00187 }
00188
00189
00191
00192 template<class Request>
00193 static void CreateRequest( Message *&msg,
00194 Request *&req,
00195 uint32_t payloadSize = 0 )
00196 {
00197 msg = new Message( sizeof(Request) + payloadSize );
00198 req = (Request*)msg->GetBuffer();
00199 msg->Zero();
00200 }
00201
00202
00204
00205 static Status SendMessage( const URL &url,
00206 Message *msg,
00207 ResponseHandler *handler,
00208 const MessageSendParams &sendParams,
00209 LocalFileHandler *lFileHandler );
00210
00211
00213
00214 static Status RedirectMessage( const URL &url,
00215 Message *msg,
00216 ResponseHandler *handler,
00217 MessageSendParams &sendParams,
00218 LocalFileHandler *lFileHandler );
00219
00220
00222
00223 static void ProcessSendParams( MessageSendParams &sendParams );
00224
00225
00235
00236 static void RewriteCGIAndPath( Message *msg,
00237 const URL::ParamsMap &newCgi,
00238 bool replace,
00239 const std::string &newPath );
00240
00241
00249
00250 static void MergeCGI( URL::ParamsMap &cgi1,
00251 const URL::ParamsMap &cgi2,
00252 bool replace );
00253 };
00254 }
00255
00256 #endif // __XRD_CL_MESSAGE_UTILS_HH__