00001
00033 #include "linden_common.h"
00034 #include "llviewerprecompiledheaders.h"
00035
00036 #include "llagent.h"
00037 #include "llviewerassetstorage.h"
00038 #include "llviewerbuild.h"
00039 #include "llvfile.h"
00040 #include "llvfs.h"
00041
00042 LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
00043 LLVFS *vfs, const LLHost &upstream_host)
00044 : LLAssetStorage(msg, xfer, vfs, upstream_host)
00045 {
00046 }
00047
00048
00049 LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
00050 LLVFS *vfs)
00051 : LLAssetStorage(msg, xfer, vfs)
00052 {
00053 }
00054
00055
00056 void LLViewerAssetStorage::storeAssetData(
00057 const LLTransactionID& tid,
00058 LLAssetType::EType asset_type,
00059 LLStoreAssetCallback callback,
00060 void* user_data,
00061 bool temp_file,
00062 bool is_priority,
00063 bool store_local,
00064 bool user_waiting,
00065 F64 timeout)
00066 {
00067 LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
00068 llinfos << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type)
00069 << " ASSET_ID: " << asset_id << llendl;
00070
00071 if (mUpstreamHost.isOk())
00072 {
00073 if (mVFS->getExists(asset_id, asset_type))
00074 {
00075
00076 U8 buffer[MTUBYTES];
00077 buffer[0] = 0;
00078
00079 LLVFile vfile(mVFS, asset_id, asset_type, LLVFile::READ);
00080 S32 asset_size = vfile.getSize();
00081
00082 LLAssetRequest *req = new LLAssetRequest(asset_id, asset_type);
00083 req->mUpCallback = callback;
00084 req->mUserData = user_data;
00085
00086 if (asset_size < 1)
00087 {
00088
00089 llwarns << "LLViewerAssetStorage::storeAssetData() Data _should_ already be in the VFS, but it's not! " << asset_id << llendl;
00090
00091 delete req;
00092 if (callback)
00093 {
00094 callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT);
00095 }
00096 return;
00097 }
00098 else if(is_priority)
00099 {
00100 mPendingUploads.push_front(req);
00101 }
00102 else
00103 {
00104 mPendingUploads.push_back(req);
00105 }
00106
00107
00108 if (asset_size + 100 < MTUBYTES)
00109 {
00110 BOOL res = vfile.read(buffer, asset_size);
00111 S32 bytes_read = res ? vfile.getLastBytesRead() : 0;
00112
00113 if( bytes_read == asset_size )
00114 {
00115 req->mDataSentInFirstPacket = TRUE;
00116
00117 }
00118 else
00119 {
00120 llwarns << "Probable corruption in VFS file, aborting store asset data" << llendl;
00121 if (callback)
00122 {
00123 callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT);
00124 }
00125 return;
00126 }
00127 }
00128 else
00129 {
00130
00131 buffer[0] = 0;
00132 asset_size = 0;
00133 }
00134 mMessageSys->newMessageFast(_PREHASH_AssetUploadRequest);
00135 mMessageSys->nextBlockFast(_PREHASH_AssetBlock);
00136 mMessageSys->addUUIDFast(_PREHASH_TransactionID, tid);
00137 mMessageSys->addS8Fast(_PREHASH_Type, (S8)asset_type);
00138 mMessageSys->addBOOLFast(_PREHASH_Tempfile, temp_file);
00139 mMessageSys->addBOOLFast(_PREHASH_StoreLocal, store_local);
00140 mMessageSys->addBinaryDataFast( _PREHASH_AssetData, buffer, asset_size );
00141 mMessageSys->sendReliable(mUpstreamHost);
00142 }
00143 else
00144 {
00145 llwarns << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
00146 if (callback)
00147 {
00148 callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE);
00149 }
00150 }
00151 }
00152 else
00153 {
00154 llwarns << "Attempt to move asset store request upstream w/o valid upstream provider" << llendl;
00155 if (callback)
00156 {
00157 callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
00158 }
00159 }
00160 }
00161
00162 void LLViewerAssetStorage::storeAssetData(
00163 const char* filename,
00164 const LLTransactionID& tid,
00165 LLAssetType::EType asset_type,
00166 LLStoreAssetCallback callback,
00167 void* user_data,
00168 bool temp_file,
00169 bool is_priority,
00170 bool user_waiting,
00171 F64 timeout)
00172 {
00173 if(!filename)
00174 {
00175 llerrs << "No filename specified" << llendl;
00176 return;
00177 }
00178
00179 LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
00180 llinfos << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
00181
00182 llinfos << "ASSET_ID: " << asset_id << llendl;
00183
00184 FILE* fp = LLFile::fopen(filename, "rb");
00185 if (fp)
00186 {
00187 LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest;
00188
00189 legacy->mUpCallback = callback;
00190 legacy->mUserData = user_data;
00191
00192 LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE);
00193
00194 fseek(fp, 0, SEEK_END);
00195 S32 size = ftell(fp);
00196 fseek(fp, 0, SEEK_SET);
00197
00198 file.setMaxSize(size);
00199
00200 const S32 buf_size = 65536;
00201 U8 copy_buf[buf_size];
00202 while ((size = (S32)fread(copy_buf, 1, buf_size, fp)))
00203 {
00204 file.write(copy_buf, size);
00205 }
00206 fclose(fp);
00207
00208
00209 if (temp_file)
00210 {
00211 LLFile::remove(filename);
00212 }
00213
00214 LLViewerAssetStorage::storeAssetData(
00215 tid,
00216 asset_type,
00217 legacyStoreDataCallback,
00218 (void**)legacy,
00219 temp_file,
00220 is_priority);
00221 }
00222 else
00223 {
00224 if (callback)
00225 {
00226 callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE);
00227 }
00228 }
00229 }