diff --git a/extensions/metrics/src/nsMetricsService.cpp b/extensions/metrics/src/nsMetricsService.cpp index 14fcb0f25618..fcfedf548f71 100644 --- a/extensions/metrics/src/nsMetricsService.cpp +++ b/extensions/metrics/src/nsMetricsService.cpp @@ -61,8 +61,10 @@ #include "nsStreamUtils.h" #include "nsVariant.h" #include "prtime.h" +#include "prmem.h" #include "bzlib.h" #include "nsIClassInfoImpl.h" +#include "nsIUUIDGenerator.h" // Make our MIME type inform the server of possible compression. #ifdef NS_METRICS_SEND_UNCOMPRESSED_DATA @@ -515,10 +517,8 @@ nsMetricsService::OpenDataFile(PRUint32 flags, PRFileDesc **fd) nsresult nsMetricsService::UploadData() { - // TODO: 1) Submit a request to the server to figure out how much data to - // upload. For now, we just submit all of the data. - // 2) Prepare a data stream for upload that is prefixed with a PROFILE - // event. + // TODO: Prepare a data stream for upload that is prefixed with a PROFILE + // event. PRBool enable = PR_FALSE; nsXPIDLCString spec; @@ -571,6 +571,22 @@ nsMetricsService::UploadData() rv = httpChannel->SetRequestMethod(NS_LITERAL_CSTRING("POST")); NS_ENSURE_SUCCESS(rv, rv); + static const char kClientIDPref[] = "metrics.client-id"; + + // Get the client id and set it in an HTTP header + nsXPIDLCString clientID; + rv = prefs->GetCharPref(kClientIDPref, getter_Copies(clientID)); + if (NS_FAILED(rv) || clientID.IsEmpty()) { + rv = GenerateClientID(clientID); + NS_ENSURE_SUCCESS(rv, rv); + + rv = prefs->SetCharPref(kClientIDPref, clientID); + NS_ENSURE_SUCCESS(rv, rv); + } + rv = httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("X-Moz-Client-ID"), + clientID, PR_FALSE); + NS_ENSURE_SUCCESS(rv, rv); + rv = channel->AsyncOpen(this, nsnull); NS_ENSURE_SUCCESS(rv, rv); @@ -721,6 +737,30 @@ nsMetricsService::GetConfigFile(nsIFile **result) file.swap(*result); } +nsresult +nsMetricsService::GenerateClientID(nsCString &clientID) +{ + nsCOMPtr idgen = + do_GetService("@mozilla.org/uuid-generator;1"); + NS_ENSURE_STATE(idgen); + + nsID id; + nsresult rv = idgen->GenerateUUIDInPlace(&id); + NS_ENSURE_SUCCESS(rv, rv); + + char *idstr = id.ToString(); + NS_ENSURE_STATE(idstr); + + // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} + static const PRUint32 kGUIDLength = 38; + NS_ASSERTION(idstr.Length() == kGUIDLength); + + // Strip off the enclosing curly brackets + clientID.Assign(idstr + 1, kGUIDLength - 2); + PR_Free(idstr); + return NS_OK; +} + /* static */ nsresult nsMetricsUtils::PutUint16(nsIWritablePropertyBag *bag, const nsAString &propertyName, diff --git a/extensions/metrics/src/nsMetricsService.h b/extensions/metrics/src/nsMetricsService.h index c7e533f79e46..af28c9601dee 100644 --- a/extensions/metrics/src/nsMetricsService.h +++ b/extensions/metrics/src/nsMetricsService.h @@ -140,6 +140,9 @@ private: // A reference to the local file containing our current configuration void GetConfigFile(nsIFile **result); + // Generate a new random client id string + nsresult GenerateClientID(nsCString &clientID); + private: // Pointer to the metrics service singleton static nsMetricsService* sMetricsService;