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 class XAttr;
00038
00039
00041
00042 class SyncResponseHandler: public ResponseHandler
00043 {
00044 public:
00045
00047
00048 SyncResponseHandler():
00049 pStatus(0),
00050 pResponse(0),
00051 pCondVar(0) {}
00052
00053
00055
00056 virtual ~SyncResponseHandler()
00057 {
00058 }
00059
00060
00061
00063
00064 virtual void HandleResponse( XRootDStatus *status,
00065 AnyObject *response )
00066 {
00067 XrdSysCondVarHelper scopedLock(pCondVar);
00068 pStatus = status;
00069 pResponse = response;
00070 pCondVar.Broadcast();
00071 }
00072
00073
00075
00076 XRootDStatus *GetStatus()
00077 {
00078 return pStatus;
00079 }
00080
00081
00083
00084 AnyObject *GetResponse()
00085 {
00086 return pResponse;
00087 }
00088
00089
00091
00092 void WaitForResponse()
00093 {
00094 XrdSysCondVarHelper scopedLock(pCondVar);
00095 while (pStatus == 0) {
00096 pCondVar.Wait();
00097 }
00098 }
00099
00100 private:
00101 SyncResponseHandler(const SyncResponseHandler &other);
00102 SyncResponseHandler &operator = (const SyncResponseHandler &other);
00103
00104 XRootDStatus *pStatus;
00105 AnyObject *pResponse;
00106 XrdSysCondVar pCondVar;
00107 };
00108
00109
00110
00111
00112
00113 class NullResponseHandler: public XrdCl::ResponseHandler
00114 {
00115 public:
00116
00117
00118
00119 virtual void HandleResponseWithHosts( XrdCl::XRootDStatus *status,
00120 XrdCl::AnyObject *response,
00121 XrdCl::HostList *hostList )
00122 {
00123 delete this;
00124 }
00125 };
00126
00127
00128
00129
00130 struct MessageSendParams
00131 {
00132 MessageSendParams():
00133 timeout(0), expires(0), followRedirects(true), chunkedResponse(false),
00134 stateful(true), hostList(0), chunkList(0), redirectLimit(0) {}
00135 uint16_t timeout;
00136 time_t expires;
00137 HostInfo loadBalancer;
00138 bool followRedirects;
00139 bool chunkedResponse;
00140 bool stateful;
00141 HostList *hostList;
00142 ChunkList *chunkList;
00143 uint16_t redirectLimit;
00144 };
00145
00146 class MessageUtils
00147 {
00148 public:
00149
00151
00152 static XRootDStatus WaitForStatus( SyncResponseHandler *handler )
00153 {
00154 handler->WaitForResponse();
00155 XRootDStatus *status = handler->GetStatus();
00156 XRootDStatus ret( *status );
00157 delete status;
00158 return ret;
00159 }
00160
00161
00163
00164 template<class Type>
00165 static XrdCl::XRootDStatus WaitForResponse(
00166 SyncResponseHandler *handler,
00167 Type *&response )
00168 {
00169 handler->WaitForResponse();
00170
00171 AnyObject *resp = handler->GetResponse();
00172 XRootDStatus *status = handler->GetStatus();
00173 XRootDStatus ret( *status );
00174 delete status;
00175
00176 if( ret.IsOK() )
00177 {
00178 if( !resp )
00179 return XRootDStatus( stError, errInternal );
00180 resp->Get( response );
00181 resp->Set( (int *)0 );
00182 delete resp;
00183
00184 if( !response )
00185 return XRootDStatus( stError, errInternal );
00186 }
00187
00188 return ret;
00189 }
00190
00191
00193
00194 template<class Request>
00195 static void CreateRequest( Message *&msg,
00196 Request *&req,
00197 uint32_t payloadSize = 0 )
00198 {
00199 msg = new Message( sizeof(Request) + payloadSize );
00200 req = (Request*)msg->GetBuffer();
00201 msg->Zero();
00202 }
00203
00204
00206
00207 static XRootDStatus SendMessage( const URL &url,
00208 Message *msg,
00209 ResponseHandler *handler,
00210 const MessageSendParams &sendParams,
00211 LocalFileHandler *lFileHandler );
00212
00213
00215
00216 static Status RedirectMessage( const URL &url,
00217 Message *msg,
00218 ResponseHandler *handler,
00219 MessageSendParams &sendParams,
00220 LocalFileHandler *lFileHandler );
00221
00222
00224
00225 static void ProcessSendParams( MessageSendParams &sendParams );
00226
00227
00237
00238 static void RewriteCGIAndPath( Message *msg,
00239 const URL::ParamsMap &newCgi,
00240 bool replace,
00241 const std::string &newPath );
00242
00243
00251
00252 static void MergeCGI( URL::ParamsMap &cgi1,
00253 const URL::ParamsMap &cgi2,
00254 bool replace );
00255
00256
00262
00263 static Status CreateXAttrVec( const std::vector<xattr_t> &attrs,
00264 std::vector<char> &avec );
00265
00266
00271
00272 static Status CreateXAttrVec( const std::vector<std::string> &attrs,
00273 std::vector<char> &nvec );
00274
00275
00281
00282 template<typename T>
00283 static Status CreateXAttrBody( Message *msg,
00284 const std::vector<T> &vec,
00285 const std::string &path = "" )
00286 {
00287 ClientRequestHdr *hdr = reinterpret_cast<ClientRequestHdr*>( msg->GetBuffer() );
00288
00289 std::vector<char> xattrvec;
00290 Status st = MessageUtils::CreateXAttrVec( vec, xattrvec );
00291 if( !st.IsOK() )
00292 return st;
00293
00294
00295 hdr->dlen = path.size() + 1;
00296 hdr->dlen += xattrvec.size();
00297
00298
00299 size_t offset = sizeof( ClientRequestHdr );
00300 msg->Append( path.c_str(), path.size() + 1, offset );
00301 offset += path.size() + 1;
00302 msg->Append( xattrvec.data(), xattrvec.size(), offset );
00303
00304 return Status();
00305 }
00306 };
00307 }
00308
00309 #endif // __XRD_CL_MESSAGE_UTILS_HH__