Commit a7ee821c authored by renovate's avatar renovate

Update module mssola/user_agent to v0.5.2

parent 18217cd0
Pipeline #10693 passed with stages
in 52 seconds
......@@ -13,7 +13,7 @@ require (
github.com/gorilla/securecookie v1.1.1
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/mattermost/xml-roundtrip-validator v0.0.0-20201219040909-8fd2afad43d1 // indirect
github.com/mssola/user_agent v0.0.0-20170906152553-a2f39d5a9b15
github.com/mssola/user_agent v0.5.2
github.com/oschwald/maxminddb-golang v0.2.0
github.com/prometheus/client_golang v1.9.0
github.com/rs/cors v0.0.0-20190613161432-33ffc0734c60
......
language: go
git:
depth: false
go:
- 1.4.x
- 1.5.x
......@@ -6,8 +10,19 @@ go:
- 1.7.x
- 1.8.x
- 1.9.x
- 1.10.x
- 1.11.x
- 1.12.x
- 1.13.x
- 1.14.x
- 1.x
- tip
matrix:
allow_failures:
- go: tip
before_install:
- chmod +x ./ci/install.sh && ./ci/install.sh
script:
- make ci
# Changelog
## 0.5.2
- Detect Electron. See [commit](https://github.com/mssola/user_agent/commit/1a36963d74c0efca7de80dc7518a0958c66b3c4f).
- Add support for both http and https site urls. See [commit](https://github.com/mssola/user_agent/commit/d78bf2c5886a0ab7e1cf90b68c808fe3e3ab6f8c).
- Add more support for BingBot. See [commit](https://github.com/mssola/user_agent/commit/c6402a7b8aefdc4acfbf1e7f3b43eac0b266e49e).
- Add a test case for Firefox focus on iOS. See [commit](https://github.com/mssola/user_agent/commit/a1e9c19d5a6887a17cef1d249118ccbd45cf4c0b).
- Detect iMessage-Preview. See [commit](https://github.com/mssola/user_agent/commit/e8f5e19ded9711ee1f4b43218b9d57d00ef5c26a).
## 0.5.1
- add Firefox for iOS. See [commit](https://github.com/mssola/user_agent/commit/00a868fa17e7).
- Add go.mod. See [commit](https://github.com/mssola/user_agent/commit/8c16c37f4e07).
- Use CodeLingo to Address Further Issues. See [commit](https://github.com/mssola/user_agent/commit/7e313fc62553).
- Fix function comments based on best practices from Effective Go. See [commit](https://github.com/mssola/user_agent/commit/95b0c164394f).
- test: mobile Yandex Browser. See [commit](https://github.com/mssola/user_agent/commit/1df9e04ee4f5).
- Add Yandex browser. See [commit](https://github.com/mssola/user_agent/commit/6eb76c60b5e8).
- Updating license notice. See [commit](https://github.com/mssola/user_agent/commit/8b3999083770).
- Detect Chrome for iOS correctly. See [commit](https://github.com/mssola/user_agent/commit/82f141dea4a8).
- Facebook App Handling. See [commit](https://github.com/mssola/user_agent/commit/5723c361ed97).
- Add a new google bot user agent format. See [commit](https://github.com/mssola/user_agent/commit/57c32981bd5f).
## 0.5.0
### Newly supported and improvements
- Added support for Microsoft Edge. See [commit](https://github.com/mssola/user_agent/commit/f659b9863849).
- Precompile regular expressions. See [commit](https://github.com/mssola/user_agent/commit/783ec61292ae).
- Added support for Dalvik user agent parsing. See [commit](https://github.com/mssola/user_agent/commit/78413629666f).
- Improved bot support (also e25e612b37a4). See [commit](https://github.com/mssola/user_agent/commit/0319fcf00bfd).
- Add Chromium support and Ubuntu specific tests. See [commit](https://github.com/mssola/user_agent/commit/6e7843e05771).
- Add OSInfo function to user agent (also 7286ca6abc28). See [commit](https://github.com/mssola/user_agent/commit/3335cae017e7).
- Detect updated UA for Googlebot. See [commit](https://github.com/mssola/user_agent/commit/6fe362d7cd64).
- Adds the Adsense bot (mobile). See [commit](https://github.com/mssola/user_agent/commit/1438bfba89d7).
### Fixes
- Fixed bug when extracting windows 10. See [commit](https://github.com/mssola/user_agent/commit/8d86c2cf88bf).
- Fixed bug on mobile Firefox browsers running on Android OS versions that report their version number inline.. See [commit](https://github.com/mssola/user_agent/commit/9d00ff9e4202).
### Other
- Improved testing infrastructure. See [commit](https://github.com/mssola/user_agent/commit/63395b193f8812526305bec75ea7117262a124aa).
## Older releases
See the description on each release
[here](https://github.com/mssola/user_agent/releases).
# Contributing to user_agent
## Check that your changes do not break anything
You can safely run the `ci` target locally:
```
$ make ci
```
This will run all the make targets that will also be run on the CI, which are
described below.
### Running tests
Call the `test` make target:
```bash
$ make test
```
### Checking the style
This project uses some standard tools in order to check the Go style. You can
run them by calling the `validate-go` make target:
```bash
$ make validate-go
```
This target is included inside of the `validate` one.
### Git validation
In order to ensure that the git log is as maintainable as possible, the
[git-validation](https://github.com/vbatts/git-validation) tool is used. You can
install this tool by running:
```bash
$ go get -u github.com/vbatts/git-validation
```
If you already have this tool installed, then simply perform:
```bash
$ make git-validation
```
This target is included inside of the `validate` one.
## Issue reporting
I'm using [Github](https://github.com/mssola/user_agent) in order to host the
code. Thus, in order to report issues you can do it on its [issue
tracker](https://github.com/mssola/user_agent/issues). A couple of notes on
reports:
- Check that the issue has not already been reported or fixed in `master`.
- Try to be concise and precise in your description of the problem.
- Provide a step by step guide on how to reproduce this problem.
- Provide the version you are using (the commit SHA, if possible).
## Pull requests
- Write a [good commit message](https://chris.beams.io/posts/git-commit/).
- Make sure that tests are passing on your local machine (it will also be
checked by the CI system whenever you submit the pull request).
- Update the [changelog](./CHANGELOG.md).
- Try to use the same coding conventions as used in this project.
- Open a pull request with *only* one subject and a clear title and
description. Refrain from submitting pull requests with tons of different
unrelated commits.
Copyright (c) 2012-2017 Miquel Sabaté Solà
Copyright (c) 2012-2020 Miquel Sabaté Solà
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
......
GO ?= go
GO_SRC = $(shell find . -name \*.go)
.DEFAULT: build
build: $(GO_SRC)
@$(GO) build
#
# Unit & integration tests.
#
.PHONY: test
test:
@$(GO) test
.PHONY: bench
bench:
@$(GO) test -bench=.
#
# Validation tools.
#
EPOCH_COMMIT ?= 2046da2a89bd
.PHONY: git-validation
git-validation:
ifeq (, $(shell which git-validation 2> /dev/null))
@echo "You don't have 'git-validation' installed, consider installing it (see the CONTRIBUTING.md file)."
else
@git-validation -q -range $(EPOCH_COMMIT)..HEAD -travis-pr-only=false
endif
.PHONY: validate-go
validate-go:
@which gofmt >/dev/null 2>/dev/null || (echo "ERROR: gofmt not found." && false)
@test -z "$$(gofmt -s -l . | grep -vE '^vendor/' | tee /dev/stderr)"
@chmod +x ci/lint.sh
@./ci/lint.sh
# Go 1.4.x does not have go vet, so there is no point on trying.
ifneq ("$(TRAVIS_GO_VERSION)","1.4.x")
@go doc cmd/vet >/dev/null 2>/dev/null || (echo "ERROR: go vet not found." && false)
@test -z "$$(go vet . | grep -v vendor | tee /dev/stderr)"
endif
.PHONY: validate
validate: git-validation validate-go
#
# Travis-CI
#
.PHONY: ci
ci: build validate test
# UserAgent [![Build Status](https://travis-ci.org/mssola/user_agent.png?branch=master)](https://travis-ci.org/mssola/user_agent) [![GoDoc](https://godoc.org/github.com/mssola/user_agent?status.png)](http://godoc.org/github.com/mssola/user_agent)
<p align="center">
<a href="https://travis-ci.org/mssola/user_agent" title="Travis CI status for the master branch"><img src="https://travis-ci.org/mssola/user_agent.svg?branch=master" alt="Build Status for master branch" /></a>
<a href="http://godoc.org/github.com/mssola/user_agent" title="godoc.org page"><img src="https://godoc.org/github.com/mssola/user_agent?status.png" alt="godoc.org page" /></a>
<a href="https://en.wikipedia.org/wiki/MIT_License" rel="nofollow"><img alt="MIT" src="https://img.shields.io/badge/license-MIT-blue.svg" style="max-width:100%;"></a>
</p>
---
UserAgent is a Go library that parses HTTP User Agents.
UserAgent is a Go library that parses HTTP User Agents. As an example:
## Usage
~~~ go
```go
package main
import (
......@@ -46,6 +49,47 @@ func main() {
fmt.Printf("%v\n", name) // => Googlebot
fmt.Printf("%v\n", version) // => 2.1
}
~~~
```
If you want to read the full API documentation simply check
[godoc](http://godoc.org/github.com/mssola/user_agent).
## Installation
```
go get -u github.com/mssola/user_agent
```
## Contributing
Do you want to contribute with code, or to report an issue you are facing? Read
the [CONTRIBUTING.md](./CONTRIBUTING.md) file.
## [Changelog](https://pbs.twimg.com/media/DJDYCcLXcAA_eIo?format=jpg&name=small)
Read the [CHANGELOG.md](./CHANGELOG.md) file.
## License
```
Copyright (c) 2012-2020 Miquel Sabaté Solà
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
Copyright &copy; 2012-2017 Miquel Sabaté Solà, released under the MIT License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
```
// Copyright (C) 2014-2017 Miquel Sabaté Solà <mikisabate@gmail.com>
// Copyright (C) 2014-2020 Miquel Sabaté Solà <mikisabate@gmail.com>
// This file is licensed under the MIT license.
// See the LICENSE file.
......@@ -9,7 +9,7 @@ import (
"strings"
)
var botFromSiteRegexp = regexp.MustCompile("http://.+\\.\\w+")
var botFromSiteRegexp = regexp.MustCompile("http[s]?://.+\\.\\w+")
// Get the name of the bot from the website that may be in the given comment. If
// there is no website in the comment, then an empty string is returned.
......@@ -22,6 +22,8 @@ func getFromSite(comment []string) string {
idx := 2
if len(comment) < 3 {
idx = 0
} else if len(comment) == 4 {
idx = 3
}
// Pick the site.
......@@ -34,23 +36,47 @@ func getFromSite(comment []string) string {
// This is a large comment, usually the name will be in the previous
// field of the comment.
return strings.TrimSpace(comment[1])
return strings.TrimSpace(comment[idx-1])
}
return ""
}
// Returns true if the info that we currently have corresponds to the Google
// mobile bot. This function also modifies some attributes in the receiver
// or Bing mobile bot. This function also modifies some attributes in the receiver
// accordingly.
func (p *UserAgent) googleBot() bool {
// This is a hackish way to detect Google's mobile bot.
if strings.Index(p.ua, "Googlebot") != -1 {
func (p *UserAgent) googleOrBingBot() bool {
// This is a hackish way to detect
// Google's mobile bot (Googlebot, AdsBot-Google-Mobile, etc.)
// (See https://support.google.com/webmasters/answer/1061943)
// and Bing's mobile bot
// (See https://www.bing.com/webmaster/help/which-crawlers-does-bing-use-8c184ec0)
if strings.Index(p.ua, "Google") != -1 || strings.Index(p.ua, "bingbot") != -1 {
p.platform = ""
p.undecided = true
}
return p.undecided
}
// Returns true if we think that it is iMessage-Preview. This function also
// modifies some attributes in the receiver accordingly.
func (p *UserAgent) iMessagePreview() bool {
// iMessage-Preview doesn't advertise itself. We have a to rely on a hack
// to detect it: it impersonates both facebook and twitter bots.
// See https://medium.com/@siggi/apples-imessage-impersonates-twitter-facebook-bots-when-scraping-cef85b2cbb7d
if strings.Index(p.ua, "facebookexternalhit") == -1 {
return false
}
if strings.Index(p.ua, "Twitterbot") == -1 {
return false
}
p.bot = true
p.browser.Name = "iMessage-Preview"
p.browser.Engine = ""
p.browser.EngineVersion = ""
// We don't set the mobile flag because iMessage can be on iOS (mobile) or macOS (not mobile).
return true
}
// Set the attributes of the receiver as given by the parameters. All the other
// parameters are set to empty.
func (p *UserAgent) setSimple(name, version string, bot bool) {
......
// Copyright (C) 2012-2017 Miquel Sabaté Solà <mikisabate@gmail.com>
// Copyright (C) 2012-2020 Miquel Sabaté Solà <mikisabate@gmail.com>
// This file is licensed under the MIT license.
// See the LICENSE file.
......@@ -11,7 +11,7 @@ import (
var ie11Regexp = regexp.MustCompile("^rv:(.+)$")
// A struct containing all the information that we might be
// Browser is a struct containing all the information that we might be
// interested from the browser.
type Browser struct {
// The name of the browser's engine.
......@@ -69,12 +69,35 @@ func (p *UserAgent) detectBrowser(sections []section) {
p.browser.Name = "Opera"
p.browser.Version = sections[slen-1].version
default:
if sections[sectionIndex].name == "Chrome" {
p.browser.Name = "Chrome"
} else if sections[sectionIndex].name == "Chromium" {
p.browser.Name = "Chromium"
} else {
p.browser.Name = "Safari"
switch sections[slen-3].name {
case "YaBrowser":
p.browser.Name = "YaBrowser"
p.browser.Version = sections[slen-3].version
default:
switch sections[slen-2].name {
case "Electron":
p.browser.Name = "Electron"
p.browser.Version = sections[slen-2].version
default:
switch sections[sectionIndex].name {
case "Chrome", "CriOS":
p.browser.Name = "Chrome"
case "Chromium":
p.browser.Name = "Chromium"
case "FxiOS":
p.browser.Name = "Firefox"
default:
p.browser.Name = "Safari"
}
}
}
// It's possible the google-bot emulates these now
for _, comment := range engine.comment {
if len(comment) > 5 &&
(strings.HasPrefix(comment, "Googlebot") || strings.HasPrefix(comment, "bingbot")) {
p.undecided = true
break
}
}
}
} else if engine.name == "Gecko" {
......@@ -127,13 +150,13 @@ func (p *UserAgent) detectBrowser(sections []section) {
}
}
// Returns two strings. The first string is the name of the engine and the
// Engine returns two strings. The first string is the name of the engine and the
// second one is the version of the engine.
func (p *UserAgent) Engine() (string, string) {
return p.browser.Engine, p.browser.EngineVersion
}
// Returns two strings. The first string is the name of the browser and the
// Browser returns two strings. The first string is the name of the browser and the
// second one is the version of the browser.
func (p *UserAgent) Browser() (string, string) {
return p.browser.Name, p.browser.Version
......
module github.com/mssola/user_agent
go 1.13
// Copyright (C) 2012-2017 Miquel Sabaté Solà <mikisabate@gmail.com>
// Copyright (C) 2012-2020 Miquel Sabaté Solà <mikisabate@gmail.com>
// This file is licensed under the MIT license.
// See the LICENSE file.
package user_agent
import "strings"
import (
"strings"
)
// Represents full information on the operating system extracted from the user agent.
// OSInfo represents full information on the operating system extracted from the
// user agent.
type OSInfo struct {
// Full name of the operating system. This is identical to the output of ua.OS()
FullName string
......@@ -88,6 +91,8 @@ func webkit(p *UserAgent, comment []string) {
}
if len(comment) > 3 {
p.localization = comment[3]
} else if len(comment) == 3 {
_ = p.googleOrBingBot()
}
} else if len(comment) > 0 {
if len(comment) > 3 {
......@@ -98,7 +103,7 @@ func webkit(p *UserAgent, comment []string) {
} else if len(comment) < 2 {
p.localization = comment[0]
} else if len(comment) < 3 {
if !p.googleBot() {
if !p.googleOrBingBot() && !p.iMessagePreview() {
p.os = normalizeOS(comment[1])
}
} else {
......@@ -127,7 +132,7 @@ func gecko(p *UserAgent, comment []string) {
p.os = normalizeOS(comment[1])
}
} else {
if p.platform == "Android" {
if strings.Contains(p.platform, "Android") {
p.mobile = true
p.platform, p.os = normalizeOS(comment[1]), p.platform
} else if comment[0] == "Mobile" || comment[0] == "Tablet" {
......@@ -280,17 +285,17 @@ func (p *UserAgent) detectOS(s section) {
}
}
// Returns a string containing the platform..
// Platform returns a string containing the platform..
func (p *UserAgent) Platform() string {
return p.platform
}
// Returns a string containing the name of the Operating System.
// OS returns a string containing the name of the Operating System.
func (p *UserAgent) OS() string {
return p.os
}
// Returns a string containing the localization.
// Localization returns a string containing the localization.
func (p *UserAgent) Localization() string {
return p.localization
}
......@@ -323,7 +328,7 @@ func osName(osSplit []string) (name, version string) {
return name, version
}
// Returns combined information for the operating system.
// OSInfo returns combined information for the operating system.
func (p *UserAgent) OSInfo() OSInfo {
// Special case for iPhone weirdness
os := strings.Replace(p.os, "like Mac OS X", "", 1)
......
// Copyright (C) 2012-2017 Miquel Sabaté Solà <mikisabate@gmail.com>
// Copyright (C) 2012-2020 Miquel Sabaté Solà <mikisabate@gmail.com>
// This file is licensed under the MIT license.
// See the LICENSE file.
......@@ -85,15 +85,27 @@ func parseProduct(product []byte) (string, string) {
// Returns a section containing the information that we could extract
// from the last parsed section.
func parseSection(ua string, index *int) (s section) {
buffer := readUntil(ua, index, ' ', false)
var buffer []byte
// Check for empty products
if *index < len(ua) && ua[*index] != '(' && ua[*index] != '[' {
buffer = readUntil(ua, index, ' ', false)
s.name, s.version = parseProduct(buffer)
}
s.name, s.version = parseProduct(buffer)
if *index < len(ua) && ua[*index] == '(' {
*index++
buffer = readUntil(ua, index, ')', true)
s.comment = strings.Split(string(buffer), "; ")
*index++
}
// Discards any trailing data within square brackets
if *index < len(ua) && ua[*index] == '[' {
*index++
buffer = readUntil(ua, index, ']', true)
*index++
}
return s
}
......@@ -113,7 +125,8 @@ func (p *UserAgent) initialize() {
p.undecided = false
}
// Parse the given User-Agent string and get the resulting UserAgent object.
// New parses the given User-Agent string and get the resulting UserAgent
// object.
//
// Returns an UserAgent object that has been initialized after parsing
// the given User-Agent string.
......@@ -152,23 +165,23 @@ func (p *UserAgent) Parse(ua string) {
}
}
// Returns the mozilla version (it's how the User Agent string begins:
// Mozilla returns the mozilla version (it's how the User Agent string begins:
// "Mozilla/5.0 ...", unless we're dealing with Opera, of course).
func (p *UserAgent) Mozilla() string {
return p.mozilla
}
// Returns true if it's a bot, false otherwise.
// Bot returns true if it's a bot, false otherwise.
func (p *UserAgent) Bot() bool {
return p.bot
}
// Returns true if it's a mobile device, false otherwise.
// Mobile returns true if it's a mobile device, false otherwise.
func (p *UserAgent) Mobile() bool {
return p.mobile
}
// Returns the original given user agent.
// UA returns the original given user agent.
func (p *UserAgent) UA() string {
return p.ua
}
......@@ -62,7 +62,7 @@ github.com/jonboulle/clockwork
github.com/mattermost/xml-roundtrip-validator
# github.com/matttproud/golang_protobuf_extensions v1.0.1
github.com/matttproud/golang_protobuf_extensions/pbutil
# github.com/mssola/user_agent v0.0.0-20170906152553-a2f39d5a9b15
# github.com/mssola/user_agent v0.5.2
## explicit
github.com/mssola/user_agent
# github.com/openzipkin/zipkin-go v0.2.5
...