File: html_discovery.go

package info (click to toggle)
golang-github-yohcop-openid-go 0.0~git20170901.0.cfc72ed-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 184 kB
  • sloc: makefile: 3
file content (75 lines) | stat: -rw-r--r-- 1,985 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package openid

import (
	"errors"
	"io"

	"golang.org/x/net/html"
)

func htmlDiscovery(id string, getter httpGetter) (opEndpoint, opLocalID, claimedID string, err error) {
	resp, err := getter.Get(id, nil)
	if err != nil {
		return "", "", "", err
	}
	opEndpoint, opLocalID, err = findProviderFromHeadLink(resp.Body)
	return opEndpoint, opLocalID, resp.Request.URL.String(), err
}

func findProviderFromHeadLink(input io.Reader) (opEndpoint, opLocalID string, err error) {
	tokenizer := html.NewTokenizer(input)
	inHead := false
	for {
		tt := tokenizer.Next()
		switch tt {
		case html.ErrorToken:
			// Even if the document is malformed after we found a
			// valid <link> tag, ignore and let's be happy with our
			// openid2.provider and potentially openid2.local_id as well.
			if len(opEndpoint) > 0 {
				return
			}
			return "", "", tokenizer.Err()
		case html.StartTagToken, html.EndTagToken, html.SelfClosingTagToken:
			tk := tokenizer.Token()
			if tk.Data == "head" {
				if tt == html.StartTagToken {
					inHead = true
				} else {
					if len(opEndpoint) > 0 {
						return
					}
					return "", "", errors.New(
						"LINK with rel=openid2.provider not found")
				}
			} else if inHead && tk.Data == "link" {
				provider := false
				localID := false
				href := ""
				for _, attr := range tk.Attr {
					if attr.Key == "rel" {
						if attr.Val == "openid2.provider" {
							provider = true
						} else if attr.Val == "openid2.local_id" {
							localID = true
						}
					} else if attr.Key == "href" {
						href = attr.Val
					}
				}
				if provider && !localID && len(href) > 0 {
					opEndpoint = href
				} else if !provider && localID && len(href) > 0 {
					opLocalID = href
				}
			}
		}
	}
	// At this point we should probably have returned either from
	// a closing </head> or a tokenizer error (no </head> found).
	// But just in case.
	if len(opEndpoint) > 0 {
		return
	}
	return "", "", errors.New("LINK rel=openid2.provider not found")
}