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 reportMetric( asset_id, asset_type, NULL, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
00092
00093 delete req;
00094 if (callback)
00095 {
00096 callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT);
00097 }
00098 return;
00099 }
00100 else
00101 {
00102
00103 S32 size = mVFS->getSize(asset_id, asset_type);
00104 const char *message = "Added to upload queue";
00105 reportMetric( asset_id, asset_type, NULL, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message );
00106
00107 if(is_priority)
00108 {
00109 mPendingUploads.push_front(req);
00110 }
00111 else
00112 {
00113 mPendingUploads.push_back(req);
00114 }
00115 }
00116
00117
00118 if (asset_size + 100 < MTUBYTES)
00119 {
00120 BOOL res = vfile.read(buffer, asset_size);
00121 S32 bytes_read = res ? vfile.getLastBytesRead() : 0;
00122
00123 if( bytes_read == asset_size )
00124 {
00125 req->mDataSentInFirstPacket = TRUE;
00126
00127 }
00128 else
00129 {
00130 llwarns << "Probable corruption in VFS file, aborting store asset data" << llendl;
00131
00132
00133 reportMetric( asset_id, asset_type, NULL, LLUUID::null, asset_size, MR_VFS_CORRUPTION, __FILE__, __LINE__, "VFS corruption" );
00134
00135 if (callback)
00136 {
00137 callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT);
00138 }
00139 return;
00140 }
00141 }
00142 else
00143 {
00144
00145 buffer[0] = 0;
00146 asset_size = 0;
00147 }
00148 mMessageSys->newMessageFast(_PREHASH_AssetUploadRequest);
00149 mMessageSys->nextBlockFast(_PREHASH_AssetBlock);
00150 mMessageSys->addUUIDFast(_PREHASH_TransactionID, tid);
00151 mMessageSys->addS8Fast(_PREHASH_Type, (S8)asset_type);
00152 mMessageSys->addBOOLFast(_PREHASH_Tempfile, temp_file);
00153 mMessageSys->addBOOLFast(_PREHASH_StoreLocal, store_local);
00154 mMessageSys->addBinaryDataFast( _PREHASH_AssetData, buffer, asset_size );
00155 mMessageSys->sendReliable(mUpstreamHost);
00156 }
00157 else
00158 {
00159 llwarns << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
00160
00161 reportMetric( asset_id, asset_type, NULL, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
00162 if (callback)
00163 {
00164 callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE);
00165 }
00166 }
00167 }
00168 else
00169 {
00170 llwarns << "Attempt to move asset store request upstream w/o valid upstream provider" << llendl;
00171
00172 reportMetric( asset_id, asset_type, NULL, LLUUID::null, 0, MR_NO_UPSTREAM, __FILE__, __LINE__, "No upstream provider" );
00173 if (callback)
00174 {
00175 callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
00176 }
00177 }
00178 }
00179
00180 void LLViewerAssetStorage::storeAssetData(
00181 const char* filename,
00182 const LLTransactionID& tid,
00183 LLAssetType::EType asset_type,
00184 LLStoreAssetCallback callback,
00185 void* user_data,
00186 bool temp_file,
00187 bool is_priority,
00188 bool user_waiting,
00189 F64 timeout)
00190 {
00191 if(!filename)
00192 {
00193
00194 reportMetric( LLUUID::null, asset_type, "", LLUUID::null, 0, MR_VFS_CORRUPTION, __FILE__, __LINE__, "Filename missing" );
00195 llerrs << "No filename specified" << llendl;
00196 return;
00197 }
00198
00199 LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
00200 llinfos << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
00201
00202 llinfos << "ASSET_ID: " << asset_id << llendl;
00203
00204 S32 size = 0;
00205 LLFILE* fp = LLFile::fopen(filename, "rb");
00206 if (fp)
00207 {
00208 fseek(fp, 0, SEEK_END);
00209 size = ftell(fp);
00210 fseek(fp, 0, SEEK_SET);
00211 }
00212 if( size )
00213 {
00214 LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest;
00215
00216 legacy->mUpCallback = callback;
00217 legacy->mUserData = user_data;
00218
00219 LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE);
00220
00221 file.setMaxSize(size);
00222
00223 const S32 buf_size = 65536;
00224 U8 copy_buf[buf_size];
00225 while ((size = (S32)fread(copy_buf, 1, buf_size, fp)))
00226 {
00227 file.write(copy_buf, size);
00228 }
00229 fclose(fp);
00230
00231
00232 if (temp_file)
00233 {
00234 LLFile::remove(filename);
00235 }
00236
00237
00238
00239 LLViewerAssetStorage::storeAssetData(
00240 tid,
00241 asset_type,
00242 legacyStoreDataCallback,
00243 (void**)legacy,
00244 temp_file,
00245 is_priority);
00246 }
00247 else
00248 {
00249 if( fp )
00250 {
00251
00252 reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file was zero length" );
00253 }
00254 else
00255 {
00256
00257 reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_FILE_NONEXIST, __FILE__, __LINE__, "The file didn't exist" );
00258 }
00259 if (callback)
00260 {
00261 callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE);
00262 }
00263 }
00264 }