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")); } } // 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. try { Package package = _packageService.FindPackageByIdAndVersion(id, version, allowPrerelease: false); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } try { _packageService.AddDownloadStatistics( package, Request.UserHostAddress, Request.UserAgent, Request.Headers["NuGet-Operation"]); } 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 QuietlyLogException(e); } catch (DataException e) { // Log the error and continue QuietlyLogException(e); } return(await _packageFileService.CreateDownloadPackageActionResultAsync(HttpContext.Request.Url, package)); } catch (SqlException e) { QuietlyLogException(e); } catch (DataException e) { QuietlyLogException(e); } // Fall back to constructing the URL based on the package version and ID. return(await _packageFileService.CreateDownloadPackageActionResultAsync(HttpContext.Request.Url, id, version)); }