gitee.com/mysnapcore/mysnapd@v0.1.0/snapdenv/useragent.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2016-2020 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package snapdenv
    21  
    22  import (
    23  	"fmt"
    24  	"strings"
    25  
    26  	"gitee.com/mysnapcore/mysnapd/arch"
    27  	"gitee.com/mysnapcore/mysnapd/osutil"
    28  	"gitee.com/mysnapcore/mysnapd/release"
    29  )
    30  
    31  // UserAgent to send
    32  var userAgent = "unset"
    33  
    34  // SetUserAgentFromVersion sets up a user-agent string.
    35  func SetUserAgentFromVersion(version string, probeForceDevMode func() bool, extraProds ...string) (restore func()) {
    36  	extras := make([]string, 1, 3)
    37  	extras[0] = "series " + release.Series
    38  	if release.OnClassic {
    39  		extras = append(extras, "classic")
    40  	}
    41  	if probeForceDevMode != nil && probeForceDevMode() {
    42  		extras = append(extras, "devmode")
    43  	}
    44  	if release.OnWSL {
    45  		extras = append(extras, "wsl")
    46  	}
    47  	if Testing() {
    48  		extras = append(extras, "testing")
    49  	}
    50  	extraProdStr := ""
    51  	if len(extraProds) != 0 {
    52  		extraProdStr = " " + strings.Join(extraProds, " ")
    53  	}
    54  	origUserAgent := userAgent
    55  
    56  	// xxx this assumes ReleaseInfo's ID and VersionID don't have weird characters
    57  	// (see rfc 7231 for values of weird)
    58  	// assumption checks out in practice, q.v. https://github.com/zyga/os-release-zoo
    59  	userAgent = fmt.Sprintf("snapd/%v (%s)%s %s/%s (%s) linux/%s", version,
    60  		strings.Join(extras, "; "), extraProdStr, release.ReleaseInfo.ID,
    61  		release.ReleaseInfo.VersionID, string(arch.DpkgArchitecture()),
    62  		sanitizeKernelVersion(osutil.KernelVersion()))
    63  	return func() {
    64  		userAgent = origUserAgent
    65  	}
    66  }
    67  
    68  func sanitizeKernelVersion(in string) string {
    69  	out := stripUnsafeRunes(in)
    70  	// Arbitrary choice, limit kernel version to 25 characters
    71  	if len(out) > 25 {
    72  		out = out[:25]
    73  	}
    74  	return out
    75  }
    76  
    77  func safeRuneMapper(r rune) rune {
    78  	if r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r >= '0' && r <= '9' || r == '-' || r == '_' || r == '.' {
    79  		return r
    80  	}
    81  	return -1
    82  }
    83  
    84  func stripUnsafeRunes(in string) string {
    85  	return strings.Map(safeRuneMapper, in)
    86  }
    87  
    88  // UserAgent returns the user-agent string setup through SetUserAgentFromVersion.
    89  func UserAgent() string {
    90  	return userAgent
    91  }