aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmessage
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:56 -0500
committerJacek Antonelli2008-08-15 23:44:56 -0500
commitc07901e29ed545bbb02e3bddf148fe1104b94e9f (patch)
treef1ada64ce834acd7d92a425efb96c4b86bcf16b1 /linden/indra/llmessage
parentSecond Life viewer sources 1.15.0.2 (diff)
downloadmeta-impy-c07901e29ed545bbb02e3bddf148fe1104b94e9f.zip
meta-impy-c07901e29ed545bbb02e3bddf148fe1104b94e9f.tar.gz
meta-impy-c07901e29ed545bbb02e3bddf148fe1104b94e9f.tar.bz2
meta-impy-c07901e29ed545bbb02e3bddf148fe1104b94e9f.tar.xz
Second Life viewer sources 1.15.1.3
Diffstat (limited to '')
-rw-r--r--linden/indra/llmessage/llassetstorage.cpp41
-rw-r--r--linden/indra/llmessage/llassetstorage.h11
-rw-r--r--linden/indra/llmessage/llcachename.cpp95
-rw-r--r--linden/indra/llmessage/llcachename.h3
-rw-r--r--linden/indra/llmessage/llcircuit.cpp8
-rw-r--r--linden/indra/llmessage/llcircuit.h4
-rw-r--r--linden/indra/llmessage/lldatapacker.cpp80
-rw-r--r--linden/indra/llmessage/llhttpassetstorage.cpp39
-rw-r--r--linden/indra/llmessage/llhttpassetstorage.h4
-rw-r--r--linden/indra/llmessage/llhttpclient.cpp9
-rw-r--r--linden/indra/llmessage/llhttpclient.h1
-rw-r--r--linden/indra/llmessage/lliohttpserver.cpp44
-rw-r--r--linden/indra/llmessage/lliohttpserver.h20
-rw-r--r--linden/indra/llmessage/lliosocket.cpp15
-rw-r--r--linden/indra/llmessage/llmail.cpp2
-rw-r--r--linden/indra/llmessage/llmessage.vcproj3
-rw-r--r--linden/indra/llmessage/llpacketbuffer.cpp10
-rw-r--r--linden/indra/llmessage/llregionflags.h3
-rw-r--r--linden/indra/llmessage/lltransfermanager.cpp1
-rw-r--r--linden/indra/llmessage/llurlrequest.cpp5
-rw-r--r--linden/indra/llmessage/llxfer_file.cpp23
-rw-r--r--linden/indra/llmessage/llxfer_mem.cpp3
-rw-r--r--linden/indra/llmessage/llxfermanager.cpp8
-rw-r--r--linden/indra/llmessage/message.cpp45
24 files changed, 338 insertions, 139 deletions
diff --git a/linden/indra/llmessage/llassetstorage.cpp b/linden/indra/llmessage/llassetstorage.cpp
index 4f4fc0c..c8610a7 100644
--- a/linden/indra/llmessage/llassetstorage.cpp
+++ b/linden/indra/llmessage/llassetstorage.cpp
@@ -57,10 +57,6 @@ LLAssetStorage *gAssetStorage = NULL;
57 57
58const LLUUID CATEGORIZE_LOST_AND_FOUND_ID("00000000-0000-0000-0000-000000000010"); 58const LLUUID CATEGORIZE_LOST_AND_FOUND_ID("00000000-0000-0000-0000-000000000010");
59 59
60const F32 LL_ASSET_STORAGE_TIMEOUT = 300.0f; // anything that takes longer than this will abort
61
62
63
64///---------------------------------------------------------------------------- 60///----------------------------------------------------------------------------
65/// LLAssetInfo 61/// LLAssetInfo
66///---------------------------------------------------------------------------- 62///----------------------------------------------------------------------------
@@ -837,43 +833,6 @@ void LLAssetStorage::downloadInvItemCompleteCallback(
837// Store routines 833// Store routines
838///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 834/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
839 835
840// virtual
841void LLAssetStorage::cancelStoreAsset(
842 const LLUUID& uuid,
843 LLAssetType::EType atype)
844{
845 bool do_callback = true;
846 LLAssetRequest* req = NULL;
847
848 if(mPendingUploads.size() > 0)
849 {
850 req = mPendingUploads.front();
851 if((req->getUUID() == uuid) && (req->getType() == atype))
852 {
853 // This is probably because the request is in progress - do
854 // not attempt to cancel.
855 do_callback = false;
856 }
857 }
858
859 if (mPendingLocalUploads.size() > 0)
860 {
861 req = mPendingLocalUploads.front();
862 if((req->getUUID() == uuid) && (req->getType() == atype))
863 {
864 // This is probably because the request is in progress - do
865 // not attempt to cancel.
866 do_callback = false;
867 }
868 }
869
870 if (do_callback)
871 {
872 // clear it out of the upload queue if it is there.
873 _callUploadCallbacks(uuid, atype, FALSE);
874 }
875}
876
877// static 836// static
878void LLAssetStorage::uploadCompleteCallback(const LLUUID& uuid, void *user_data, S32 result) // StoreAssetData callback (fixed) 837void LLAssetStorage::uploadCompleteCallback(const LLUUID& uuid, void *user_data, S32 result) // StoreAssetData callback (fixed)
879{ 838{
diff --git a/linden/indra/llmessage/llassetstorage.h b/linden/indra/llmessage/llassetstorage.h
index 3c7a709..f80a77d 100644
--- a/linden/indra/llmessage/llassetstorage.h
+++ b/linden/indra/llmessage/llassetstorage.h
@@ -48,6 +48,10 @@ class LLAssetStorage;
48class LLVFS; 48class LLVFS;
49class LLSD; 49class LLSD;
50 50
51// anything that takes longer than this to download will abort.
52// HTTP Uploads also timeout if they take longer than this.
53const F32 LL_ASSET_STORAGE_TIMEOUT = 5 * 60.0f;
54
51class LLAssetInfo 55class LLAssetInfo
52{ 56{
53protected: 57protected:
@@ -264,13 +268,6 @@ public:
264 bool store_local = false, 268 bool store_local = false,
265 const LLUUID& requesting_agent_id = LLUUID::null); 269 const LLUUID& requesting_agent_id = LLUUID::null);
266 270
267 // This call will attempt to clear a store asset. This will only
268 // attempt to cancel an upload that has not yet begun. The
269 // callback will be called with an error code.
270 virtual void cancelStoreAsset(
271 const LLUUID& uuid,
272 LLAssetType::EType oatype);
273
274 virtual void checkForTimeouts(); 271 virtual void checkForTimeouts();
275 272
276 void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id, 273 void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id,
diff --git a/linden/indra/llmessage/llcachename.cpp b/linden/indra/llmessage/llcachename.cpp
index 5df62b3..1cc7e09 100644
--- a/linden/indra/llmessage/llcachename.cpp
+++ b/linden/indra/llmessage/llcachename.cpp
@@ -52,6 +52,10 @@ const char* CN_NONE = "(none)";
52const char* CN_HIPPOS = "(hippos)"; 52const char* CN_HIPPOS = "(hippos)";
53const F32 HIPPO_PROBABILITY = 0.01f; 53const F32 HIPPO_PROBABILITY = 0.01f;
54 54
55// We track name requests in flight for up to this long.
56// We won't re-request a name during this time
57const U32 PENDING_TIMEOUT_SECS = 5 * 60;
58
55// File version number 59// File version number
56const S32 CN_FILE_VERSION = 2; 60const S32 CN_FILE_VERSION = 2;
57 61
@@ -182,8 +186,9 @@ namespace {
182 } 186 }
183 187
184 188
185 typedef std::vector<LLUUID> AskQueue; 189 typedef std::set<LLUUID> AskQueue;
186 typedef std::vector<PendingReply> ReplyQueue; 190 typedef std::vector<PendingReply> ReplyQueue;
191 typedef std::map<LLUUID,U32> PendingQueue;
187 typedef std::map<LLUUID, LLCacheNameEntry*> Cache; 192 typedef std::map<LLUUID, LLCacheNameEntry*> Cache;
188 typedef std::vector<LLCacheNameCallback> Observers; 193 typedef std::vector<LLCacheNameCallback> Observers;
189}; 194};
@@ -200,6 +205,9 @@ public:
200 AskQueue mAskNameQueue; 205 AskQueue mAskNameQueue;
201 AskQueue mAskGroupQueue; 206 AskQueue mAskGroupQueue;
202 // UUIDs to ask our upstream host about 207 // UUIDs to ask our upstream host about
208
209 PendingQueue mPendingQueue;
210 // UUIDs that have been requested but are not in cache yet.
203 211
204 ReplyQueue mReplyQueue; 212 ReplyQueue mReplyQueue;
205 // requests awaiting replies from us 213 // requests awaiting replies from us
@@ -214,6 +222,7 @@ public:
214 void processPendingAsks(); 222 void processPendingAsks();
215 void processPendingReplies(); 223 void processPendingReplies();
216 void sendRequest(const char* msg_name, const AskQueue& queue); 224 void sendRequest(const char* msg_name, const AskQueue& queue);
225 bool isRequestPending(const LLUUID& id);
217 226
218 // Message system callbacks. 227 // Message system callbacks.
219 void processUUIDRequest(LLMessageSystem* msg, bool isGroup); 228 void processUUIDRequest(LLMessageSystem* msg, bool isGroup);
@@ -456,7 +465,10 @@ BOOL LLCacheName::getName(const LLUUID& id, char* first, char* last)
456 : CN_WAITING); 465 : CN_WAITING);
457 strcpy(last, ""); /*Flawfinder: ignore*/ 466 strcpy(last, ""); /*Flawfinder: ignore*/
458 467
459 impl.mAskNameQueue.push_back(id); 468 if (!impl.isRequestPending(id))
469 {
470 impl.mAskNameQueue.insert(id);
471 }
460 return FALSE; 472 return FALSE;
461 } 473 }
462 474
@@ -496,8 +508,10 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, char* group)
496 // The function signature needs to change to pass in the length 508 // The function signature needs to change to pass in the length
497 // of first and last. 509 // of first and last.
498 strcpy(group, CN_WAITING); /*Flawfinder: ignore*/ 510 strcpy(group, CN_WAITING); /*Flawfinder: ignore*/
499 511 if (!impl.isRequestPending(id))
500 impl.mAskGroupQueue.push_back(id); 512 {
513 impl.mAskGroupQueue.insert(id);
514 }
501 return FALSE; 515 return FALSE;
502 } 516 }
503} 517}
@@ -525,13 +539,16 @@ void LLCacheName::get(const LLUUID& id, BOOL is_group, LLCacheNameCallback callb
525 } 539 }
526 else 540 else
527 { 541 {
528 if (!is_group) 542 if (!impl.isRequestPending(id))
529 {
530 impl.mAskNameQueue.push_back(id);
531 }
532 else
533 { 543 {
534 impl.mAskGroupQueue.push_back(id); 544 if (!is_group)
545 {
546 impl.mAskNameQueue.insert(id);
547 }
548 else
549 {
550 impl.mAskGroupQueue.insert(id);
551 }
535 } 552 }
536 impl.mReplyQueue.push_back(PendingReply(id, callback, user_data)); 553 impl.mReplyQueue.push_back(PendingReply(id, callback, user_data));
537 } 554 }
@@ -570,6 +587,19 @@ void LLCacheName::deleteEntriesOlderThan(S32 secs)
570 impl.mCache.erase(curiter); 587 impl.mCache.erase(curiter);
571 } 588 }
572 } 589 }
590
591 // These are pending requests that we never heard back from.
592 U32 pending_expire_time = now - PENDING_TIMEOUT_SECS;
593 for(PendingQueue::iterator p_iter = impl.mPendingQueue.begin();
594 p_iter != impl.mPendingQueue.end(); )
595 {
596 PendingQueue::iterator p_curitor = p_iter++;
597
598 if (p_curitor->second < pending_expire_time)
599 {
600 impl.mPendingQueue.erase(p_curitor);
601 }
602 }
573} 603}
574 604
575 605
@@ -599,6 +629,18 @@ void LLCacheName::dump()
599 } 629 }
600} 630}
601 631
632void LLCacheName::dumpStats()
633{
634 llinfos << "Queue sizes: "
635 << " Cache=" << impl.mCache.size()
636 << " AskName=" << impl.mAskNameQueue.size()
637 << " AskGroup=" << impl.mAskGroupQueue.size()
638 << " Pending=" << impl.mPendingQueue.size()
639 << " Reply=" << impl.mReplyQueue.size()
640 << " Observers=" << impl.mObservers.size()
641 << llendl;
642}
643
602void LLCacheName::Impl::processPendingAsks() 644void LLCacheName::Impl::processPendingAsks()
603{ 645{
604 sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue); 646 sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue);
@@ -702,7 +744,23 @@ void LLCacheName::Impl::notifyObservers(const LLUUID& id,
702 } 744 }
703} 745}
704 746
747bool LLCacheName::Impl::isRequestPending(const LLUUID& id)
748{
749 U32 now = (U32)time(NULL);
750 U32 expire_time = now - PENDING_TIMEOUT_SECS;
705 751
752 PendingQueue::iterator iter = mPendingQueue.find(id);
753
754 if (iter == mPendingQueue.end()
755 || (iter->second < expire_time) )
756 {
757 mPendingQueue[id] = now;
758 return false;
759 }
760
761 return true;
762}
763
706void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup) 764void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup)
707{ 765{
708 // You should only get this message if the cache is at the simulator 766 // You should only get this message if the cache is at the simulator
@@ -740,13 +798,16 @@ void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup)
740 } 798 }
741 else 799 else
742 { 800 {
743 if (isGroup) 801 if (!isRequestPending(id))
744 { 802 {
745 mAskGroupQueue.push_back(id); 803 if (isGroup)
746 } 804 {
747 else 805 mAskGroupQueue.insert(id);
748 { 806 }
749 mAskNameQueue.push_back(id); 807 else
808 {
809 mAskNameQueue.insert(id);
810 }
750 } 811 }
751 812
752 mReplyQueue.push_back(PendingReply(id, fromHost)); 813 mReplyQueue.push_back(PendingReply(id, fromHost));
@@ -770,6 +831,8 @@ void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup)
770 mCache[id] = entry; 831 mCache[id] = entry;
771 } 832 }
772 833
834 mPendingQueue.erase(id);
835
773 entry->mIsGroup = isGroup; 836 entry->mIsGroup = isGroup;
774 entry->mCreateTime = (U32)time(NULL); 837 entry->mCreateTime = (U32)time(NULL);
775 if (!isGroup) 838 if (!isGroup)
diff --git a/linden/indra/llmessage/llcachename.h b/linden/indra/llmessage/llcachename.h
index 9009b1f..7d606e6 100644
--- a/linden/indra/llmessage/llcachename.h
+++ b/linden/indra/llmessage/llcachename.h
@@ -98,7 +98,8 @@ public:
98 void deleteEntriesOlderThan(S32 secs); 98 void deleteEntriesOlderThan(S32 secs);
99 99
100 // Debugging 100 // Debugging
101 void dump(); 101 void dump(); // Dumps the contents of the cache
102 void dumpStats(); // Dumps the sizes of the cache and associated queues.
102 103
103private: 104private:
104 class Impl; 105 class Impl;
diff --git a/linden/indra/llmessage/llcircuit.cpp b/linden/indra/llmessage/llcircuit.cpp
index 5e93e0a..239c1df 100644
--- a/linden/indra/llmessage/llcircuit.cpp
+++ b/linden/indra/llmessage/llcircuit.cpp
@@ -1167,13 +1167,13 @@ std::ostream& operator<<(std::ostream& s, LLCircuitData& circuit)
1167 return s; 1167 return s;
1168} 1168}
1169 1169
1170const char* LLCircuitData::getInfoString() const 1170const LLString LLCircuitData::getInfoString() const
1171{ 1171{
1172 std::ostringstream info; 1172 std::ostringstream info;
1173 info << "Circuit: " << mHost << std::endl 1173 info << "Circuit: " << mHost << std::endl
1174 << (mbAlive ? "Alive" : "Not Alive") << std::endl 1174 << (mbAlive ? "Alive" : "Not Alive") << std::endl
1175 << "Age: " << mExistenceTimer.getElapsedTimeF32() << std::endl; 1175 << "Age: " << mExistenceTimer.getElapsedTimeF32() << std::endl;
1176 return info.str().c_str(); 1176 return LLString(info.str());
1177} 1177}
1178 1178
1179void LLCircuitData::dumpResendCountAndReset() 1179void LLCircuitData::dumpResendCountAndReset()
@@ -1197,7 +1197,7 @@ std::ostream& operator<<(std::ostream& s, LLCircuit &circuit)
1197 return s; 1197 return s;
1198} 1198}
1199 1199
1200const char* LLCircuit::getInfoString() const 1200const LLString LLCircuit::getInfoString() const
1201{ 1201{
1202 std::ostringstream info; 1202 std::ostringstream info;
1203 info << "Circuit Info:" << std::endl; 1203 info << "Circuit Info:" << std::endl;
@@ -1207,7 +1207,7 @@ const char* LLCircuit::getInfoString() const
1207 { 1207 {
1208 info << (*it).second->getInfoString() << std::endl; 1208 info << (*it).second->getInfoString() << std::endl;
1209 } 1209 }
1210 return info.str().c_str(); 1210 return LLString(info.str());
1211} 1211}
1212 1212
1213void LLCircuit::getCircuitRange( 1213void LLCircuit::getCircuitRange(
diff --git a/linden/indra/llmessage/llcircuit.h b/linden/indra/llmessage/llcircuit.h
index e3a5779..1eea203 100644
--- a/linden/indra/llmessage/llcircuit.h
+++ b/linden/indra/llmessage/llcircuit.h
@@ -151,7 +151,7 @@ public:
151 // 151 //
152 void checkPeriodTime(); // Reset per-period counters if necessary. 152 void checkPeriodTime(); // Reset per-period counters if necessary.
153 friend std::ostream& operator<<(std::ostream& s, LLCircuitData &circuit); 153 friend std::ostream& operator<<(std::ostream& s, LLCircuitData &circuit);
154 const char* getInfoString() const; 154 const LLString getInfoString() const;
155 155
156 friend class LLCircuit; 156 friend class LLCircuit;
157 friend class LLMessageSystem; 157 friend class LLMessageSystem;
@@ -297,7 +297,7 @@ public:
297 void sendAcks(); 297 void sendAcks();
298 298
299 friend std::ostream& operator<<(std::ostream& s, LLCircuit &circuit); 299 friend std::ostream& operator<<(std::ostream& s, LLCircuit &circuit);
300 const char* getInfoString() const; 300 const LLString getInfoString() const;
301 301
302 void dumpResends(); 302 void dumpResends();
303 303
diff --git a/linden/indra/llmessage/lldatapacker.cpp b/linden/indra/llmessage/lldatapacker.cpp
index 2448c40..3cdaa25 100644
--- a/linden/indra/llmessage/lldatapacker.cpp
+++ b/linden/indra/llmessage/lldatapacker.cpp
@@ -972,11 +972,11 @@ BOOL LLDataPackerAsciiBuffer::packF32(const F32 value, const char *name)
972 int numCopied = 0; 972 int numCopied = 0;
973 if (mWriteEnabled) 973 if (mWriteEnabled)
974 { 974 {
975 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g\n", value); /* Flawfinder: ignore */ 975 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f\n", value); /* Flawfinder: ignore */
976 } 976 }
977 else 977 else
978 { 978 {
979 numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%g\n", value); /* Flawfinder: ignore */ 979 numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%f\n", value); /* Flawfinder: ignore */
980 } 980 }
981 // snprintf returns number of bytes that would have been written 981 // snprintf returns number of bytes that would have been written
982 // had the output not being truncated. In that case, it will 982 // had the output not being truncated. In that case, it will
@@ -1004,7 +1004,7 @@ BOOL LLDataPackerAsciiBuffer::unpackF32(F32 &value, const char *name)
1004 return FALSE; 1004 return FALSE;
1005 } 1005 }
1006 1006
1007 sscanf(valuestr,"%g", &value); 1007 sscanf(valuestr,"%f", &value);
1008 return success; 1008 return success;
1009} 1009}
1010 1010
@@ -1016,11 +1016,11 @@ BOOL LLDataPackerAsciiBuffer::packColor4(const LLColor4 &value, const char *name
1016 int numCopied = 0; 1016 int numCopied = 0;
1017 if (mWriteEnabled) 1017 if (mWriteEnabled)
1018 { 1018 {
1019 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ 1019 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
1020 } 1020 }
1021 else 1021 else
1022 { 1022 {
1023 numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ 1023 numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
1024 } 1024 }
1025 // snprintf returns number of bytes that would have been written 1025 // snprintf returns number of bytes that would have been written
1026 // had the output not being truncated. In that case, it will 1026 // had the output not being truncated. In that case, it will
@@ -1048,7 +1048,7 @@ BOOL LLDataPackerAsciiBuffer::unpackColor4(LLColor4 &value, const char *name)
1048 return FALSE; 1048 return FALSE;
1049 } 1049 }
1050 1050
1051 sscanf(valuestr,"%g %g %g %g", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); 1051 sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]);
1052 return success; 1052 return success;
1053} 1053}
1054 1054
@@ -1109,11 +1109,11 @@ BOOL LLDataPackerAsciiBuffer::packVector2(const LLVector2 &value, const char *na
1109 int numCopied = 0; 1109 int numCopied = 0;
1110 if (mWriteEnabled) 1110 if (mWriteEnabled)
1111 { 1111 {
1112 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g %g\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ 1112 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */
1113 } 1113 }
1114 else 1114 else
1115 { 1115 {
1116 numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%g %g\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ 1116 numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */
1117 } 1117 }
1118 // snprintf returns number of bytes that would have been written 1118 // snprintf returns number of bytes that would have been written
1119 // had the output not being truncated. In that case, it will 1119 // had the output not being truncated. In that case, it will
@@ -1141,7 +1141,7 @@ BOOL LLDataPackerAsciiBuffer::unpackVector2(LLVector2 &value, const char *name)
1141 return FALSE; 1141 return FALSE;
1142 } 1142 }
1143 1143
1144 sscanf(valuestr,"%g %g", &value.mV[0], &value.mV[1]); 1144 sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]);
1145 return success; 1145 return success;
1146} 1146}
1147 1147
@@ -1153,11 +1153,11 @@ BOOL LLDataPackerAsciiBuffer::packVector3(const LLVector3 &value, const char *na
1153 int numCopied = 0; 1153 int numCopied = 0;
1154 if (mWriteEnabled) 1154 if (mWriteEnabled)
1155 { 1155 {
1156 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g %g %g\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ 1156 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */
1157 } 1157 }
1158 else 1158 else
1159 { 1159 {
1160 numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%g %g %g\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ 1160 numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */
1161 } 1161 }
1162 // snprintf returns number of bytes that would have been written 1162 // snprintf returns number of bytes that would have been written
1163 // had the output not being truncated. In that case, it will 1163 // had the output not being truncated. In that case, it will
@@ -1185,7 +1185,7 @@ BOOL LLDataPackerAsciiBuffer::unpackVector3(LLVector3 &value, const char *name)
1185 return FALSE; 1185 return FALSE;
1186 } 1186 }
1187 1187
1188 sscanf(valuestr,"%g %g %g", &value.mV[0], &value.mV[1], &value.mV[2]); 1188 sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]);
1189 return success; 1189 return success;
1190} 1190}
1191 1191
@@ -1196,11 +1196,11 @@ BOOL LLDataPackerAsciiBuffer::packVector4(const LLVector4 &value, const char *na
1196 int numCopied = 0; 1196 int numCopied = 0;
1197 if (mWriteEnabled) 1197 if (mWriteEnabled)
1198 { 1198 {
1199 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ 1199 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
1200 } 1200 }
1201 else 1201 else
1202 { 1202 {
1203 numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ 1203 numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
1204 } 1204 }
1205 // snprintf returns number of bytes that would have been written 1205 // snprintf returns number of bytes that would have been written
1206 // had the output not being truncated. In that case, it will 1206 // had the output not being truncated. In that case, it will
@@ -1228,7 +1228,7 @@ BOOL LLDataPackerAsciiBuffer::unpackVector4(LLVector4 &value, const char *name)
1228 return FALSE; 1228 return FALSE;
1229 } 1229 }
1230 1230
1231 sscanf(valuestr,"%g %g %g %g", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); 1231 sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]);
1232 return success; 1232 return success;
1233} 1233}
1234 1234
@@ -1359,6 +1359,19 @@ BOOL LLDataPackerAsciiBuffer::getValueStr(const char *name, char *out_value, S32
1359 return success; 1359 return success;
1360} 1360}
1361 1361
1362// helper function used by LLDataPackerAsciiFile
1363// to convert F32 into a string. This is to avoid
1364// << operator writing F32 value into a stream
1365// since it does not seem to preserve the float value
1366std::string convertF32ToString(F32 val)
1367{
1368 std::string str;
1369 char buf[20];
1370 snprintf(buf, 20, "%f", val);
1371 str = buf;
1372 return str;
1373}
1374
1362//--------------------------------------------------------------------------- 1375//---------------------------------------------------------------------------
1363// LLDataPackerAsciiFile implementation 1376// LLDataPackerAsciiFile implementation
1364//--------------------------------------------------------------------------- 1377//---------------------------------------------------------------------------
@@ -1633,11 +1646,11 @@ BOOL LLDataPackerAsciiFile::packF32(const F32 value, const char *name)
1633 writeIndentedName(name); 1646 writeIndentedName(name);
1634 if (mFP) 1647 if (mFP)
1635 { 1648 {
1636 fprintf(mFP,"%g\n", value); 1649 fprintf(mFP,"%f\n", value);
1637 } 1650 }
1638 else if (mOutputStream) 1651 else if (mOutputStream)
1639 { 1652 {
1640 *mOutputStream <<"" << value << "\n"; 1653 *mOutputStream <<"" << convertF32ToString(value) << "\n";
1641 } 1654 }
1642 return success; 1655 return success;
1643} 1656}
@@ -1652,7 +1665,7 @@ BOOL LLDataPackerAsciiFile::unpackF32(F32 &value, const char *name)
1652 return FALSE; 1665 return FALSE;
1653 } 1666 }
1654 1667
1655 sscanf(valuestr,"%g", &value); 1668 sscanf(valuestr,"%f", &value);
1656 return success; 1669 return success;
1657} 1670}
1658 1671
@@ -1663,11 +1676,11 @@ BOOL LLDataPackerAsciiFile::packColor4(const LLColor4 &value, const char *name)
1663 writeIndentedName(name); 1676 writeIndentedName(name);
1664 if (mFP) 1677 if (mFP)
1665 { 1678 {
1666 fprintf(mFP,"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); 1679 fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]);
1667 } 1680 }
1668 else if (mOutputStream) 1681 else if (mOutputStream)
1669 { 1682 {
1670 *mOutputStream << value.mV[0] << " " << value.mV[1] << " " << value.mV[2] << " " << value.mV[3] << "\n"; 1683 *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(value.mV[3]) << "\n";
1671 } 1684 }
1672 return success; 1685 return success;
1673} 1686}
@@ -1682,7 +1695,7 @@ BOOL LLDataPackerAsciiFile::unpackColor4(LLColor4 &value, const char *name)
1682 return FALSE; 1695 return FALSE;
1683 } 1696 }
1684 1697
1685 sscanf(valuestr,"%g %g %g %g", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); 1698 sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]);
1686 return success; 1699 return success;
1687} 1700}
1688 1701
@@ -1728,11 +1741,11 @@ BOOL LLDataPackerAsciiFile::packVector2(const LLVector2 &value, const char *name
1728 writeIndentedName(name); 1741 writeIndentedName(name);
1729 if (mFP) 1742 if (mFP)
1730 { 1743 {
1731 fprintf(mFP,"%g %g\n", value.mV[0], value.mV[1]); 1744 fprintf(mFP,"%f %f\n", value.mV[0], value.mV[1]);
1732 } 1745 }
1733 else if (mOutputStream) 1746 else if (mOutputStream)
1734 { 1747 {
1735 *mOutputStream << value.mV[0] << " " << value.mV[1] << "\n"; 1748 *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << "\n";
1736 } 1749 }
1737 return success; 1750 return success;
1738} 1751}
@@ -1747,7 +1760,7 @@ BOOL LLDataPackerAsciiFile::unpackVector2(LLVector2 &value, const char *name)
1747 return FALSE; 1760 return FALSE;
1748 } 1761 }
1749 1762
1750 sscanf(valuestr,"%g %g", &value.mV[0], &value.mV[1]); 1763 sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]);
1751 return success; 1764 return success;
1752} 1765}
1753 1766
@@ -1758,11 +1771,11 @@ BOOL LLDataPackerAsciiFile::packVector3(const LLVector3 &value, const char *name
1758 writeIndentedName(name); 1771 writeIndentedName(name);
1759 if (mFP) 1772 if (mFP)
1760 { 1773 {
1761 fprintf(mFP,"%g %g %g\n", value.mV[0], value.mV[1], value.mV[2]); 1774 fprintf(mFP,"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]);
1762 } 1775 }
1763 else if (mOutputStream) 1776 else if (mOutputStream)
1764 { 1777 {
1765 *mOutputStream << value.mV[0] << " " << value.mV[1] << " " << value.mV[2] << "\n"; 1778 *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << "\n";
1766 } 1779 }
1767 return success; 1780 return success;
1768} 1781}
@@ -1777,7 +1790,7 @@ BOOL LLDataPackerAsciiFile::unpackVector3(LLVector3 &value, const char *name)
1777 return FALSE; 1790 return FALSE;
1778 } 1791 }
1779 1792
1780 sscanf(valuestr,"%g %g %g", &value.mV[0], &value.mV[1], &value.mV[2]); 1793 sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]);
1781 return success; 1794 return success;
1782} 1795}
1783 1796
@@ -1787,11 +1800,11 @@ BOOL LLDataPackerAsciiFile::packVector4(const LLVector4 &value, const char *name
1787 writeIndentedName(name); 1800 writeIndentedName(name);
1788 if (mFP) 1801 if (mFP)
1789 { 1802 {
1790 fprintf(mFP,"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); 1803 fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]);
1791 } 1804 }
1792 else if (mOutputStream) 1805 else if (mOutputStream)
1793 { 1806 {
1794 *mOutputStream << value.mV[0] << " " << value.mV[1] << " " << value.mV[2] << " " << value.mV[3] << "\n"; 1807 *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(value.mV[3]) << "\n";
1795 } 1808 }
1796 return success; 1809 return success;
1797} 1810}
@@ -1806,7 +1819,7 @@ BOOL LLDataPackerAsciiFile::unpackVector4(LLVector4 &value, const char *name)
1806 return FALSE; 1819 return FALSE;
1807 } 1820 }
1808 1821
1809 sscanf(valuestr,"%g %g %g %g", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); 1822 sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]);
1810 return success; 1823 return success;
1811} 1824}
1812 1825
@@ -1848,7 +1861,8 @@ BOOL LLDataPackerAsciiFile::unpackUUID(LLUUID &value, const char *name)
1848 1861
1849void LLDataPackerAsciiFile::writeIndentedName(const char *name) 1862void LLDataPackerAsciiFile::writeIndentedName(const char *name)
1850{ 1863{
1851 char indent_buf[64]; /*Flawfinder: ignore*/ 1864 std::string indent_buf;
1865 indent_buf.reserve(mIndent+1);
1852 1866
1853 S32 i; 1867 S32 i;
1854 for(i = 0; i < mIndent; i++) 1868 for(i = 0; i < mIndent; i++)
@@ -1858,11 +1872,11 @@ void LLDataPackerAsciiFile::writeIndentedName(const char *name)
1858 indent_buf[i] = 0; 1872 indent_buf[i] = 0;
1859 if (mFP) 1873 if (mFP)
1860 { 1874 {
1861 fprintf(mFP,"%s%s\t",indent_buf, name); 1875 fprintf(mFP,"%s%s\t",indent_buf.c_str(), name);
1862 } 1876 }
1863 else if (mOutputStream) 1877 else if (mOutputStream)
1864 { 1878 {
1865 *mOutputStream << indent_buf << name << "\t"; 1879 *mOutputStream << indent_buf.c_str() << name << "\t";
1866 } 1880 }
1867} 1881}
1868 1882
diff --git a/linden/indra/llmessage/llhttpassetstorage.cpp b/linden/indra/llmessage/llhttpassetstorage.cpp
index 8e328ce..5a0cdad 100644
--- a/linden/indra/llmessage/llhttpassetstorage.cpp
+++ b/linden/indra/llmessage/llhttpassetstorage.cpp
@@ -34,6 +34,7 @@
34#include <sys/stat.h> 34#include <sys/stat.h>
35 35
36#include "indra_constants.h" 36#include "indra_constants.h"
37#include "message.h"
37#include "llvfile.h" 38#include "llvfile.h"
38#include "llvfs.h" 39#include "llvfs.h"
39 40
@@ -517,6 +518,8 @@ void LLHTTPAssetStorage::storeAssetData(
517 callback(LLUUID::null, user_data, LL_ERR_CANNOT_OPEN_FILE); 518 callback(LLUUID::null, user_data, LL_ERR_CANNOT_OPEN_FILE);
518 } 519 }
519 } 520 }
521 // Coverity CID-269 says there's a leak of 'legacy' here, but
522 // legacyStoreDataCallback() will delete it somewhere down the line.
520} 523}
521 524
522// virtual 525// virtual
@@ -937,9 +940,45 @@ void LLHTTPAssetStorage::checkForTimeouts()
937 } while (curl_msg && queue_length > 0); 940 } while (curl_msg && queue_length > 0);
938 941
939 942
943 // Cleanup
944 // We want to bump to the back of the line any running uploads that have timed out.
945 bumpTimedOutUploads();
946
940 LLAssetStorage::checkForTimeouts(); 947 LLAssetStorage::checkForTimeouts();
941} 948}
942 949
950void LLHTTPAssetStorage::bumpTimedOutUploads()
951{
952 // No point bumping currently running uploads if there are no others in line.
953 if (!(mPendingUploads.size() > mRunningUploads.size()))
954 {
955 return;
956 }
957
958 F64 mt_secs = LLMessageSystem::getMessageTimeSeconds();
959
960 // deletePendingRequest will modify the mRunningUploads list so we don't want to iterate over it.
961 request_list_t temp_running = mRunningUploads;
962
963 request_list_t::iterator it = temp_running.begin();
964 request_list_t::iterator end = temp_running.end();
965 for ( ; it != end; ++it)
966 {
967 //request_list_t::iterator curiter = iter++;
968 LLAssetRequest* req = *it;
969
970 if ( LL_ASSET_STORAGE_TIMEOUT < (mt_secs - req->mTime) )
971 {
972 llwarns << "Asset upload request timed out for "
973 << req->getUUID() << "."
974 << LLAssetType::lookup(req->getType())
975 << ", bumping to the back of the line!" << llendl;
976
977 deletePendingRequest(RT_UPLOAD, req->getType(), req->getUUID());
978 }
979 }
980}
981
943// static 982// static
944size_t LLHTTPAssetStorage::curlDownCallback(void *data, size_t size, size_t nmemb, void *user_data) 983size_t LLHTTPAssetStorage::curlDownCallback(void *data, size_t size, size_t nmemb, void *user_data)
945{ 984{
diff --git a/linden/indra/llmessage/llhttpassetstorage.h b/linden/indra/llmessage/llhttpassetstorage.h
index b5ab56b..2977301 100644
--- a/linden/indra/llmessage/llhttpassetstorage.h
+++ b/linden/indra/llmessage/llhttpassetstorage.h
@@ -133,6 +133,10 @@ private:
133 // This will return the correct base URI for any http asset request 133 // This will return the correct base URI for any http asset request
134 std::string getBaseURL(const LLUUID& asset_id, LLAssetType::EType asset_type); 134 std::string getBaseURL(const LLUUID& asset_id, LLAssetType::EType asset_type);
135 135
136 // Check for running uploads that have timed out
137 // Bump these to the back of the line to let other uploads complete.
138 void bumpTimedOutUploads();
139
136protected: 140protected:
137 std::string mBaseURL; 141 std::string mBaseURL;
138 std::string mLocalBaseURL; 142 std::string mLocalBaseURL;
diff --git a/linden/indra/llmessage/llhttpclient.cpp b/linden/indra/llmessage/llhttpclient.cpp
index 1d38a13..8cb8344 100644
--- a/linden/indra/llmessage/llhttpclient.cpp
+++ b/linden/indra/llmessage/llhttpclient.cpp
@@ -37,6 +37,7 @@
37#include "llsdserialize.h" 37#include "llsdserialize.h"
38#include "llvfile.h" 38#include "llvfile.h"
39#include "llvfs.h" 39#include "llvfs.h"
40#include "lluri.h"
40 41
41#include "message.h" 42#include "message.h"
42#include <curl/curl.h> 43#include <curl/curl.h>
@@ -283,6 +284,14 @@ void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const F32
283 request(url, LLURLRequest::HTTP_GET, NULL, responder, timeout); 284 request(url, LLURLRequest::HTTP_GET, NULL, responder, timeout);
284} 285}
285 286
287void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const F32 timeout)
288{
289 LLURI uri;
290
291 uri = LLURI::buildHTTP(url, LLSD::emptyArray(), query);
292 get(uri.asString(), responder, timeout);
293}
294
286// A simple class for managing data returned from a curl http request. 295// A simple class for managing data returned from a curl http request.
287class LLHTTPBuffer 296class LLHTTPBuffer
288{ 297{
diff --git a/linden/indra/llmessage/llhttpclient.h b/linden/indra/llmessage/llhttpclient.h
index 136577c..c2dfb5d 100644
--- a/linden/indra/llmessage/llhttpclient.h
+++ b/linden/indra/llmessage/llhttpclient.h
@@ -73,6 +73,7 @@ public:
73 typedef boost::intrusive_ptr<Responder> ResponderPtr; 73 typedef boost::intrusive_ptr<Responder> ResponderPtr;
74 74
75 static void get(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); 75 static void get(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
76 static void get(const std::string& url, const LLSD& query, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
76 static void put(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); 77 static void put(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
77 ///< non-blocking 78 ///< non-blocking
78 static void post(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); 79 static void post(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
diff --git a/linden/indra/llmessage/lliohttpserver.cpp b/linden/indra/llmessage/lliohttpserver.cpp
index 9ea7272..d7fc54e 100644
--- a/linden/indra/llmessage/lliohttpserver.cpp
+++ b/linden/indra/llmessage/lliohttpserver.cpp
@@ -29,9 +29,8 @@
29 */ 29 */
30 30
31#include "linden_common.h" 31#include "linden_common.h"
32#include "lliohttpserver.h"
33 32
34#include "boost/tokenizer.hpp" 33#include "lliohttpserver.h"
35 34
36#include "llapr.h" 35#include "llapr.h"
37#include "llbuffer.h" 36#include "llbuffer.h"
@@ -46,9 +45,12 @@
46#include "llsd.h" 45#include "llsd.h"
47#include "llsdserialize_xml.h" 46#include "llsdserialize_xml.h"
48#include "llstl.h" 47#include "llstl.h"
48#include "lltimer.h"
49 49
50#include <sstream> 50#include <sstream>
51 51
52#include "boost/tokenizer.hpp"
53
52static const char HTTP_VERSION_STR[] = "HTTP/1.0"; 54static const char HTTP_VERSION_STR[] = "HTTP/1.0";
53static const std::string CONTEXT_REQUEST("request"); 55static const std::string CONTEXT_REQUEST("request");
54static const std::string HTTP_VERB_GET("GET"); 56static const std::string HTTP_VERB_GET("GET");
@@ -56,6 +58,8 @@ static const std::string HTTP_VERB_PUT("PUT");
56static const std::string HTTP_VERB_POST("POST"); 58static const std::string HTTP_VERB_POST("POST");
57static const std::string HTTP_VERB_DELETE("DELETE"); 59static const std::string HTTP_VERB_DELETE("DELETE");
58 60
61static LLIOHTTPServer::timing_callback_t sTimingCallback = NULL;
62static void* sTimingCallbackData = NULL;
59 63
60class LLHTTPPipe : public LLIOPipe 64class LLHTTPPipe : public LLIOPipe
61{ 65{
@@ -151,6 +155,12 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
151 // TODO: Babbage: Parameterize parser? 155 // TODO: Babbage: Parameterize parser?
152 LLBufferStream istr(channels, buffer.get()); 156 LLBufferStream istr(channels, buffer.get());
153 157
158 static LLTimer timer;
159 if (sTimingCallback)
160 {
161 timer.reset();
162 }
163
154 std::string verb = context[CONTEXT_REQUEST]["verb"]; 164 std::string verb = context[CONTEXT_REQUEST]["verb"];
155 if(verb == HTTP_VERB_GET) 165 if(verb == HTTP_VERB_GET)
156 { 166 {
@@ -179,6 +189,18 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
179 mResponse->methodNotAllowed(); 189 mResponse->methodNotAllowed();
180 } 190 }
181 191
192 if (sTimingCallback)
193 {
194 LLHTTPNode::Description desc;
195 mNode.describe(desc);
196 LLSD info = desc.getInfo();
197 std::string timing_name = info["description"];
198 timing_name += " ";
199 timing_name += verb;
200 F32 delta = timer.getElapsedTimeF32();
201 sTimingCallback(timing_name.c_str(), delta, sTimingCallbackData);
202 }
203
182 // Log Internal Server Errors 204 // Log Internal Server Errors
183 if(mStatusCode == 500) 205 if(mStatusCode == 500)
184 { 206 {
@@ -819,9 +841,9 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
819} 841}
820 842
821 843
822 844// static
823void LLCreateHTTPPipe(LLPumpIO::chain_t& chain, 845void LLIOHTTPServer::createPipe(LLPumpIO::chain_t& chain,
824 const LLHTTPNode& root, const LLSD& ctx) 846 const LLHTTPNode& root, const LLSD& ctx)
825{ 847{
826 chain.push_back(LLIOPipe::ptr_t(new LLHTTPResponder(root, ctx))); 848 chain.push_back(LLIOPipe::ptr_t(new LLHTTPResponder(root, ctx)));
827} 849}
@@ -832,7 +854,7 @@ class LLHTTPResponseFactory : public LLChainIOFactory
832public: 854public:
833 bool build(LLPumpIO::chain_t& chain, LLSD ctx) const 855 bool build(LLPumpIO::chain_t& chain, LLSD ctx) const
834 { 856 {
835 LLCreateHTTPPipe(chain, mTree, ctx); 857 LLIOHTTPServer::createPipe(chain, mTree, ctx);
836 return true; 858 return true;
837 } 859 }
838 860
@@ -843,7 +865,8 @@ private:
843}; 865};
844 866
845 867
846LLHTTPNode& LLCreateHTTPServer( 868// static
869LLHTTPNode& LLIOHTTPServer::create(
847 apr_pool_t* pool, LLPumpIO& pump, U16 port) 870 apr_pool_t* pool, LLPumpIO& pump, U16 port)
848{ 871{
849 LLSocket::ptr_t socket = LLSocket::create( 872 LLSocket::ptr_t socket = LLSocket::create(
@@ -867,3 +890,10 @@ LLHTTPNode& LLCreateHTTPServer(
867 return factory->getRootNode(); 890 return factory->getRootNode();
868} 891}
869 892
893// static
894void LLIOHTTPServer::setTimingCallback(timing_callback_t callback,
895 void* data)
896{
897 sTimingCallback = callback;
898 sTimingCallbackData = data;
899}
diff --git a/linden/indra/llmessage/lliohttpserver.h b/linden/indra/llmessage/lliohttpserver.h
index 64dce63..8a6c8d4 100644
--- a/linden/indra/llmessage/lliohttpserver.h
+++ b/linden/indra/llmessage/lliohttpserver.h
@@ -36,7 +36,12 @@
36 36
37class LLPumpIO; 37class LLPumpIO;
38 38
39LLHTTPNode& LLCreateHTTPServer(apr_pool_t* pool, LLPumpIO& pump, U16 port); 39class LLIOHTTPServer
40{
41public:
42 typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data);
43
44 static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port);
40 /**< Creates an HTTP wire server on the pump for the given TCP port. 45 /**< Creates an HTTP wire server on the pump for the given TCP port.
41 * 46 *
42 * Returns the root node of the new server. Add LLHTTPNode instances 47 * Returns the root node of the new server. Add LLHTTPNode instances
@@ -51,14 +56,23 @@ LLHTTPNode& LLCreateHTTPServer(apr_pool_t* pool, LLPumpIO& pump, U16 port);
51 * for example), use the helper templates below. 56 * for example), use the helper templates below.
52 */ 57 */
53 58
54void LLCreateHTTPPipe(LLPumpIO::chain_t& chain, 59 static void createPipe(LLPumpIO::chain_t& chain,
55 const LLHTTPNode& root, const LLSD& ctx); 60 const LLHTTPNode& root, const LLSD& ctx);
56 /**< Create a pipe on the chain that handles HTTP requests. 61 /**< Create a pipe on the chain that handles HTTP requests.
57 * The requests are served by the node tree given at root. 62 * The requests are served by the node tree given at root.
58 * 63 *
59 * This is primarily useful for unit testing. 64 * This is primarily useful for unit testing.
60 */ 65 */
61 66
67 static void setTimingCallback(timing_callback_t callback, void* data);
68 /**< Register a callback function that will be called every time
69 * a GET, PUT, POST, or DELETE is handled.
70 *
71 * This is used to time the LLHTTPNode handler code, which often hits
72 * the database or does other, slow operations. JC
73 */
74};
75
62/* @name Helper Templates 76/* @name Helper Templates
63 * 77 *
64 * These templates make it easy to create nodes that use thier own protocol 78 * These templates make it easy to create nodes that use thier own protocol
diff --git a/linden/indra/llmessage/lliosocket.cpp b/linden/indra/llmessage/lliosocket.cpp
index af22180..0ceb436 100644
--- a/linden/indra/llmessage/lliosocket.cpp
+++ b/linden/indra/llmessage/lliosocket.cpp
@@ -423,23 +423,35 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
423 bool done = false; 423 bool done = false;
424 while(it != end) 424 while(it != end)
425 { 425 {
426
426 PUMP_DEBUG; 427 PUMP_DEBUG;
427 if((*it).isOnChannel(channels.in())) 428 if((*it).isOnChannel(channels.in()))
428 { 429 {
429 PUMP_DEBUG; 430 PUMP_DEBUG;
430 // *FIX: check return code - sockets will fail (broken, etc.) 431 // *FIX: check return code - sockets will fail (broken, etc.)
431 len = (apr_size_t)segment.size(); 432 len = (apr_size_t)segment.size();
432 apr_socket_send( 433 apr_status_t status = apr_socket_send(
433 mDestination->getSocket(), 434 mDestination->getSocket(),
434 (const char*)segment.data(), 435 (const char*)segment.data(),
435 &len); 436 &len);
437 // We sometimes get a 'non-blocking socket operation could not be
438 // completed immediately' error from apr_socket_send. In this
439 // case we break and the data will be sent the next time the chain
440 // is pumped.
441#if LL_WINDOWS
442 if (status == 730035)
443 break;
444#endif
436 mLastWritten = segment.data() + len - 1; 445 mLastWritten = segment.data() + len - 1;
446
437 PUMP_DEBUG; 447 PUMP_DEBUG;
438 if((S32)len < segment.size()) 448 if((S32)len < segment.size())
439 { 449 {
440 break; 450 break;
441 } 451 }
452
442 } 453 }
454
443 ++it; 455 ++it;
444 if(it != end) 456 if(it != end)
445 { 457 {
@@ -449,6 +461,7 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
449 { 461 {
450 done = true; 462 done = true;
451 } 463 }
464
452 } 465 }
453 PUMP_DEBUG; 466 PUMP_DEBUG;
454 if(done && eos) 467 if(done && eos)
diff --git a/linden/indra/llmessage/llmail.cpp b/linden/indra/llmessage/llmail.cpp
index 793cb19..633a2a3 100644
--- a/linden/indra/llmessage/llmail.cpp
+++ b/linden/indra/llmessage/llmail.cpp
@@ -64,7 +64,7 @@ static apr_sockaddr_t* gSockAddr;
64static apr_socket_t* gMailSocket; 64static apr_socket_t* gMailSocket;
65 65
66// According to RFC2822 66// According to RFC2822
67static const boost::regex valid_subject_chars("[\\x1-\\x9\\xb\\xc\\xe-\\x7f]+"); 67static const boost::regex valid_subject_chars("[\\x1-\\x9\\xb\\xc\\xe-\\x7f]*");
68bool connect_smtp(); 68bool connect_smtp();
69void disconnect_smtp(); 69void disconnect_smtp();
70 70
diff --git a/linden/indra/llmessage/llmessage.vcproj b/linden/indra/llmessage/llmessage.vcproj
index ac16f52..d3e0d89 100644
--- a/linden/indra/llmessage/llmessage.vcproj
+++ b/linden/indra/llmessage/llmessage.vcproj
@@ -440,6 +440,9 @@
440 RelativePath=".\llhttpsender.h"> 440 RelativePath=".\llhttpsender.h">
441 </File> 441 </File>
442 <File 442 <File
443 RelativePath=".\llhttpnode.h">
444 </File>
445 <File
443 RelativePath=".\llinstantmessage.h"> 446 RelativePath=".\llinstantmessage.h">
444 </File> 447 </File>
445 <File 448 <File
diff --git a/linden/indra/llmessage/llpacketbuffer.cpp b/linden/indra/llmessage/llpacketbuffer.cpp
index 69144f5..525569d 100644
--- a/linden/indra/llmessage/llpacketbuffer.cpp
+++ b/linden/indra/llmessage/llpacketbuffer.cpp
@@ -42,11 +42,13 @@ LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32
42 { 42 {
43 llerrs << "Sending packet > " << NET_BUFFER_SIZE << " of size " << size << llendl; 43 llerrs << "Sending packet > " << NET_BUFFER_SIZE << " of size " << size << llendl;
44 } 44 }
45 45 else // we previously relied on llerrs being fatal to not get here...
46 if (datap != NULL)
47 { 46 {
48 memcpy(mData, datap, size); /*Flawfinder: ignore*/ 47 if (datap != NULL)
49 mSize = size; 48 {
49 memcpy(mData, datap, size);
50 mSize = size;
51 }
50 } 52 }
51 53
52} 54}
diff --git a/linden/indra/llmessage/llregionflags.h b/linden/indra/llmessage/llregionflags.h
index 6a23544..fb9bf5b 100644
--- a/linden/indra/llmessage/llregionflags.h
+++ b/linden/indra/llmessage/llregionflags.h
@@ -63,7 +63,7 @@ const U32 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid
63const U32 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13); 63const U32 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13);
64const U32 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics 64const U32 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics
65const U32 REGION_FLAGS_EXTERNALLY_VISIBLE = (1 << 15); 65const U32 REGION_FLAGS_EXTERNALLY_VISIBLE = (1 << 15);
66const U32 REGION_FLAGS_MAINLAND_VISIBLE = (1 << 16); 66//const U32 REGION_FLAGS_MAINLAND_VISIBLE = (1 << 16);
67const U32 REGION_FLAGS_PUBLIC_ALLOWED = (1 << 17); 67const U32 REGION_FLAGS_PUBLIC_ALLOWED = (1 << 17);
68const U32 REGION_FLAGS_BLOCK_DWELL = (1 << 18); 68const U32 REGION_FLAGS_BLOCK_DWELL = (1 << 18);
69 69
@@ -99,7 +99,6 @@ const U32 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK
99 | REGION_FLAGS_ALLOW_SET_HOME; 99 | REGION_FLAGS_ALLOW_SET_HOME;
100 100
101const U32 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE 101const U32 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE
102 | REGION_FLAGS_MAINLAND_VISIBLE
103 | REGION_FLAGS_PUBLIC_ALLOWED 102 | REGION_FLAGS_PUBLIC_ALLOWED
104 | REGION_FLAGS_SUN_FIXED 103 | REGION_FLAGS_SUN_FIXED
105 | REGION_FLAGS_DENY_ANONYMOUS 104 | REGION_FLAGS_DENY_ANONYMOUS
diff --git a/linden/indra/llmessage/lltransfermanager.cpp b/linden/indra/llmessage/lltransfermanager.cpp
index 12e1728..f42ce45 100644
--- a/linden/indra/llmessage/lltransfermanager.cpp
+++ b/linden/indra/llmessage/lltransfermanager.cpp
@@ -958,6 +958,7 @@ void LLTransferTargetChannel::requestTransfer(
958 if (!ttp) 958 if (!ttp)
959 { 959 {
960 llwarns << "LLTransferManager::requestTransfer aborting due to target creation failure!" << llendl; 960 llwarns << "LLTransferManager::requestTransfer aborting due to target creation failure!" << llendl;
961 return;
961 } 962 }
962 963
963 ttp->applyParams(target_params); 964 ttp->applyParams(target_params);
diff --git a/linden/indra/llmessage/llurlrequest.cpp b/linden/indra/llmessage/llurlrequest.cpp
index b3dfb52..1c7648b 100644
--- a/linden/indra/llmessage/llurlrequest.cpp
+++ b/linden/indra/llmessage/llurlrequest.cpp
@@ -544,7 +544,10 @@ size_t headerCallback(void* data, size_t size, size_t nmemb, void* user)
544 int statusCode = atoi(status.c_str()); 544 int statusCode = atoi(status.c_str());
545 if (statusCode > 0) 545 if (statusCode > 0)
546 { 546 {
547 complete->httpStatus((U32)statusCode, reason); 547 if (complete)
548 {
549 complete->httpStatus((U32)statusCode, reason);
550 }
548 } 551 }
549 } 552 }
550 553
diff --git a/linden/indra/llmessage/llxfer_file.cpp b/linden/indra/llmessage/llxfer_file.cpp
index 297d163..33db248 100644
--- a/linden/indra/llmessage/llxfer_file.cpp
+++ b/linden/indra/llmessage/llxfer_file.cpp
@@ -82,7 +82,8 @@ void LLXfer_File::init (const LLString& local_filename, BOOL delete_local_on_com
82 82
83 if (!local_filename.empty()) 83 if (!local_filename.empty())
84 { 84 {
85 strncpy(mLocalFilename, local_filename.c_str(), LL_MAX_PATH); /* Flawfinder : ignore */ 85 strncpy(mLocalFilename, local_filename.c_str(), LL_MAX_PATH-1);
86 mLocalFilename[LL_MAX_PATH-1] = '\0'; // stupid strncpy.
86 87
87 // You can only automatically delete .tmp file as a safeguard against nasty messages. 88 // You can only automatically delete .tmp file as a safeguard against nasty messages.
88 mDeleteLocalOnCompletion = (delete_local_on_completion && (strstr(mLocalFilename,".tmp") == &mLocalFilename[strlen(mLocalFilename)-4])); /* Flawfinder : ignore */ 89 mDeleteLocalOnCompletion = (delete_local_on_completion && (strstr(mLocalFilename,".tmp") == &mLocalFilename[strlen(mLocalFilename)-4])); /* Flawfinder : ignore */
@@ -117,19 +118,21 @@ void LLXfer_File::free ()
117/////////////////////////////////////////////////////////// 118///////////////////////////////////////////////////////////
118 119
119S32 LLXfer_File::initializeRequest(U64 xfer_id, 120S32 LLXfer_File::initializeRequest(U64 xfer_id,
120 const LLString& local_filename, 121 const LLString& local_filename,
121 const LLString& remote_filename, 122 const LLString& remote_filename,
122 ELLPath remote_path, 123 ELLPath remote_path,
123 const LLHost& remote_host, 124 const LLHost& remote_host,
124 BOOL delete_remote_on_completion, 125 BOOL delete_remote_on_completion,
125 void (*callback)(void**,S32), 126 void (*callback)(void**,S32),
126 void** user_data) 127 void** user_data)
127{ 128{
128 S32 retval = 0; // presume success 129 S32 retval = 0; // presume success
129 130
130 mID = xfer_id; 131 mID = xfer_id;
131 strncpy(mLocalFilename, local_filename.c_str(), LL_MAX_PATH); /* Flawfinder : ignore */ 132 strncpy(mLocalFilename, local_filename.c_str(), LL_MAX_PATH-1);
132 strncpy(mRemoteFilename,remote_filename.c_str(), LL_MAX_PATH); /* Flawfinder : ignore */ 133 mLocalFilename[LL_MAX_PATH-1] = '\0'; // stupid strncpy.
134 strncpy(mRemoteFilename,remote_filename.c_str(), LL_MAX_PATH-1);
135 mRemoteFilename[LL_MAX_PATH-1] = '\0'; // stupid strncpy.
133 mRemotePath = remote_path; 136 mRemotePath = remote_path;
134 mRemoteHost = remote_host; 137 mRemoteHost = remote_host;
135 mDeleteRemoteOnCompletion = delete_remote_on_completion; 138 mDeleteRemoteOnCompletion = delete_remote_on_completion;
diff --git a/linden/indra/llmessage/llxfer_mem.cpp b/linden/indra/llmessage/llxfer_mem.cpp
index e9b4224..0f055c8 100644
--- a/linden/indra/llmessage/llxfer_mem.cpp
+++ b/linden/indra/llmessage/llxfer_mem.cpp
@@ -162,7 +162,8 @@ S32 LLXfer_Mem::initializeRequest(U64 xfer_id,
162 mCallbackDataHandle = user_data; 162 mCallbackDataHandle = user_data;
163 mCallbackResult = LL_ERR_NOERR; 163 mCallbackResult = LL_ERR_NOERR;
164 164
165 strncpy(mRemoteFilename, remote_filename.c_str(), LL_MAX_PATH); /* Flawfinder : ignore */ 165 strncpy(mRemoteFilename, remote_filename.c_str(), LL_MAX_PATH-1);
166 mRemoteFilename[LL_MAX_PATH-1] = '\0'; // stupid strncpy.
166 mRemotePath = remote_path; 167 mRemotePath = remote_path;
167 mDeleteRemoteOnCompletion = delete_remote_on_completion; 168 mDeleteRemoteOnCompletion = delete_remote_on_completion;
168 169
diff --git a/linden/indra/llmessage/llxfermanager.cpp b/linden/indra/llmessage/llxfermanager.cpp
index 914488e..7758a32 100644
--- a/linden/indra/llmessage/llxfermanager.cpp
+++ b/linden/indra/llmessage/llxfermanager.cpp
@@ -223,8 +223,8 @@ LLXfer *LLXferManager::findXfer (U64 id, LLXfer *list_head)
223 223
224void LLXferManager::removeXfer (LLXfer *delp, LLXfer **list_head) 224void LLXferManager::removeXfer (LLXfer *delp, LLXfer **list_head)
225{ 225{
226 LLXfer *xferp; 226 // This function assumes that delp will only occur in the list
227 227 // zero or one times.
228 if (delp) 228 if (delp)
229 { 229 {
230 if (*list_head == delp) 230 if (*list_head == delp)
@@ -234,14 +234,14 @@ void LLXferManager::removeXfer (LLXfer *delp, LLXfer **list_head)
234 } 234 }
235 else 235 else
236 { 236 {
237 xferp = *list_head; 237 LLXfer *xferp = *list_head;
238 while (xferp->mNext) 238 while (xferp->mNext)
239 { 239 {
240 if (xferp->mNext == delp) 240 if (xferp->mNext == delp)
241 { 241 {
242 xferp->mNext = delp->mNext; 242 xferp->mNext = delp->mNext;
243 delete (delp); 243 delete (delp);
244 continue; 244 break;
245 } 245 }
246 xferp = xferp->mNext; 246 xferp = xferp->mNext;
247 } 247 }
diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp
index ef22b63..29f232c 100644
--- a/linden/indra/llmessage/message.cpp
+++ b/linden/indra/llmessage/message.cpp
@@ -535,6 +535,8 @@ void LLMessageSystem::loadTemplateFile(const char* filename)
535 if(!filename) 535 if(!filename)
536 { 536 {
537 llerrs << "No template filename specified" << llendl; 537 llerrs << "No template filename specified" << llendl;
538 mbError = TRUE;
539 return;
538 } 540 }
539 541
540 char token[MAX_MESSAGE_INTERNAL_NAME_SIZE]; /* Flawfinder: ignore */ 542 char token[MAX_MESSAGE_INTERNAL_NAME_SIZE]; /* Flawfinder: ignore */
@@ -655,6 +657,13 @@ void LLMessageSystem::loadTemplateFile(const char* filename)
655 // add data! 657 // add data!
656 // we've gotten a complete variable! hooray! 658 // we've gotten a complete variable! hooray!
657 // add it! 659 // add it!
660 if (NULL == templatep)
661 {
662 llerrs << "Trying to addTemplate a NULL templatep during load." << llendl;
663 mbError = TRUE;
664 fclose(messagefilep);
665 return;
666 }
658 addTemplate(templatep); 667 addTemplate(templatep);
659 668
660 //llinfos << "Read template: "templatep->mNametemp_str 669 //llinfos << "Read template: "templatep->mNametemp_str
@@ -672,7 +681,13 @@ void LLMessageSystem::loadTemplateFile(const char* filename)
672 // add data! 681 // add data!
673 // we've gotten a complete variable! hooray! 682 // we've gotten a complete variable! hooray!
674 // add it to template 683 // add it to template
675 684 if (NULL == templatep)
685 {
686 llerrs << "Trying to addBlock to NULL templatep during load." << llendl;
687 mbError = TRUE;
688 fclose(messagefilep);
689 return;
690 }
676 templatep->addBlock(blockp); 691 templatep->addBlock(blockp);
677 692
678 // start working on it! 693 // start working on it!
@@ -876,10 +891,24 @@ void LLMessageSystem::loadTemplateFile(const char* filename)
876 891
877 if (strcmp(token, "Trusted") == 0) 892 if (strcmp(token, "Trusted") == 0)
878 { 893 {
894 if (NULL == templatep)
895 {
896 llerrs << "Trying to setTrust for NULL templatep during load." << llendl;
897 mbError = TRUE;
898 fclose(messagefilep);
899 return;
900 }
879 templatep->setTrust(MT_TRUST); 901 templatep->setTrust(MT_TRUST);
880 } 902 }
881 else if (strcmp(token, "NotTrusted") == 0) 903 else if (strcmp(token, "NotTrusted") == 0)
882 { 904 {
905 if (NULL == templatep)
906 {
907 llerrs << "Trying to setTrust for NULL templatep during load." << llendl;
908 mbError = TRUE;
909 fclose(messagefilep);
910 return;
911 }
883 templatep->setTrust(MT_NOTRUST); 912 templatep->setTrust(MT_NOTRUST);
884 } 913 }
885 else 914 else
@@ -912,10 +941,24 @@ void LLMessageSystem::loadTemplateFile(const char* filename)
912 941
913 if(0 == strcmp(token, "Unencoded")) 942 if(0 == strcmp(token, "Unencoded"))
914 { 943 {
944 if (NULL == templatep)
945 {
946 llerrs << "Trying to setEncoding for NULL templatep during load." << llendl;
947 mbError = TRUE;
948 fclose(messagefilep);
949 return;
950 }
915 templatep->setEncoding(ME_UNENCODED); 951 templatep->setEncoding(ME_UNENCODED);
916 } 952 }
917 else if(0 == strcmp(token, "Zerocoded")) 953 else if(0 == strcmp(token, "Zerocoded"))
918 { 954 {
955 if (NULL == templatep)
956 {
957 llerrs << "Trying to setEncoding for NULL templatep during load." << llendl;
958 mbError = TRUE;
959 fclose(messagefilep);
960 return;
961 }
919 templatep->setEncoding(ME_ZEROCODED); 962 templatep->setEncoding(ME_ZEROCODED);
920 } 963 }
921 else 964 else