public void AddDownloadStatistics(PackageStatistics stats) { // IMPORTANT: Until we understand privacy implications of storing IP Addresses thoroughly, // It's better to just not store them. Hence "unknown". - Phil Haack 10/6/2011 stats.IPAddress = "unknown"; _packageStatsRepository.InsertOnCommit(stats); _packageStatsRepository.CommitChanges(); }
public void RecordPackageDownloadStatistics(int packageKey, string userHostAddress, string userAgent) { var stats = new PackageStatistics { // IMPORTANT: We may be able to get timestamp from message IPAddress = userHostAddress, UserAgent = userAgent, PackageKey = packageKey }; var message = stats.ToXml(); var request = new SendMessageRequest(); request.WithQueueUrl(clientContext.QueueUrl); request.WithDelaySeconds(0); request.WithMessageBody(message); using (AmazonSQS client = clientContext.CreateInstance()) { SendMessageResponse response = WrapRequestInErrorHandler(() => client.SendMessage(request)); } }
public virtual async Task<ActionResult> GetPackage(string id, string version) { // some security paranoia about URL hacking somehow creating e.g. open redirects // validate user input: explicit calls to the same validators used during Package Registrations // Ideally shouldn't be necessary? if (!PackageIdValidator.IsValidPackageId(id ?? "")) { return new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The format of the package id is invalid"); } if (!String.IsNullOrEmpty(version)) { SemanticVersion dummy; if (!SemanticVersion.TryParse(version, out dummy)) { return new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The package version is not a valid semantic version"); } } // Normalize the version version = SemanticVersionExtensions.Normalize(version); // if the version is null, the user is asking for the latest version. Presumably they don't want includePrerelease release versions. // The allow prerelease flag is ignored if both partialId and version are specified. // In general we want to try to add download statistics for any package regardless of whether a version was specified. // Only allow database requests to take up to 5 seconds. Any longer and we just lose the data; oh well. EntitiesContext.SetCommandTimeout(5); Package package = null; try { package = PackageService.FindPackageByIdAndVersion(id, version, allowPrerelease: false); if (package == null) { return new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version)); } try { var stats = new PackageStatistics { IPAddress = Request.UserHostAddress, UserAgent = Request.UserAgent, Package = package, Operation = Request.Headers["NuGet-Operation"], DependentPackage = Request.Headers["NuGet-DependentPackage"], ProjectGuids = Request.Headers["NuGet-ProjectGuids"], }; PackageService.AddDownloadStatistics(stats); } catch (ReadOnlyModeException) { // *gulp* Swallowed. It's OK not to add statistics and ok to not log errors in read only mode. } catch (SqlException e) { // Log the error and continue QuietLog.LogHandledException(e); } catch (DataException e) { // Log the error and continue QuietLog.LogHandledException(e); } } catch (SqlException e) { QuietLog.LogHandledException(e); } catch (DataException e) { QuietLog.LogHandledException(e); } // Fall back to constructing the URL based on the package version and ID. if (String.IsNullOrEmpty(version) && package == null) { // Database was unavailable and we don't have a version, return a 503 return new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion); } return await PackageFileService.CreateDownloadPackageActionResultAsync( HttpContext.Request.Url, id, String.IsNullOrEmpty(version) ? package.NormalizedVersion : version); }
public virtual async Task <ActionResult> GetPackage(string id, string version) { // some security paranoia about URL hacking somehow creating e.g. open redirects // validate user input: explicit calls to the same validators used during Package Registrations // Ideally shouldn't be necessary? if (!PackageIdValidator.IsValidPackageId(id ?? "")) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The format of the package id is invalid")); } if (!String.IsNullOrEmpty(version)) { SemanticVersion dummy; if (!SemanticVersion.TryParse(version, out dummy)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The package version is not a valid semantic version")); } } // Normalize the version version = SemanticVersionExtensions.Normalize(version); // if the version is null, the user is asking for the latest version. Presumably they don't want includePrerelease release versions. // The allow prerelease flag is ignored if both partialId and version are specified. // In general we want to try to add download statistics for any package regardless of whether a version was specified. Package package = null; try { package = PackageService.FindPackageByIdAndVersion(id, version, allowPrerelease: false); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } try { var stats = new PackageStatistics { // IMPORTANT: Timestamp is managed by the database. IPAddress = Request.UserHostAddress, UserAgent = Request.UserAgent, Package = package, Operation = Request.Headers["NuGet-Operation"], DependentPackage = Request.Headers["NuGet-DependentPackage"], ProjectGuids = Request.Headers["NuGet-ProjectGuids"], }; PackageService.AddDownloadStatistics(stats); } catch (ReadOnlyModeException) { // *gulp* Swallowed. It's OK not to add statistics and ok to not log errors in read only mode. } catch (SqlException e) { // Log the error and continue QuietLog.LogHandledException(e); } catch (DataException e) { // Log the error and continue QuietLog.LogHandledException(e); } } catch (SqlException e) { QuietLog.LogHandledException(e); } catch (DataException e) { QuietLog.LogHandledException(e); } // Fall back to constructing the URL based on the package version and ID. if (String.IsNullOrEmpty(version) && package == null) { // Database was unavailable and we don't have a version, return a 503 return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion)); } return(await PackageFileService.CreateDownloadPackageActionResultAsync( HttpContext.Request.Url, id, String.IsNullOrEmpty(version)?package.NormalizedVersion : version)); }