mirror of
https://code.rocketnine.space/tslocum/gmitohtml.git
synced 2024-11-27 15:38:14 +01:00
Allow specifying client certificate
This commit is contained in:
parent
fb5e7f4ea4
commit
26115183a9
1 changed files with 34 additions and 2 deletions
|
@ -3,6 +3,7 @@ package gmitohtml
|
|||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
@ -14,8 +15,13 @@ import (
|
|||
|
||||
var lastRequestTime = time.Now().Unix()
|
||||
|
||||
var clientCerts = make(map[string]tls.Certificate)
|
||||
|
||||
// ErrInvalidCertificate is the error returned when an invalid certificate is provided.
|
||||
var ErrInvalidCertificate = errors.New("invalid certificate")
|
||||
|
||||
// Fetch downloads and converts a Gemini page.
|
||||
func fetch(u string, clientCertFile string, clientCertKey string) ([]byte, []byte, error) {
|
||||
func fetch(u string) ([]byte, []byte, error) {
|
||||
if u == "" {
|
||||
return nil, nil, ErrInvalidURL
|
||||
}
|
||||
|
@ -39,6 +45,16 @@ func fetch(u string, clientCertFile string, clientCertKey string) ([]byte, []byt
|
|||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
certHost := requestURL.Hostname()
|
||||
if strings.HasPrefix(certHost, "www.") {
|
||||
certHost = certHost[4:]
|
||||
}
|
||||
|
||||
clientCert, certAvailable := clientCerts[certHost]
|
||||
if certAvailable {
|
||||
tlsConfig.Certificates = []tls.Certificate{clientCert}
|
||||
}
|
||||
|
||||
conn, err := tls.Dial("tcp", host, tlsConfig)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -153,7 +169,7 @@ func handleRequest(writer http.ResponseWriter, request *http.Request) {
|
|||
u.RawQuery = request.URL.RawQuery
|
||||
}
|
||||
|
||||
header, data, err := fetch(u.String(), "", "")
|
||||
header, data, err := fetch(u.String())
|
||||
if err != nil {
|
||||
fmt.Fprintf(writer, "Error: failed to fetch %s: %s", u, err)
|
||||
return
|
||||
|
@ -205,3 +221,19 @@ func StartDaemon(address string) error {
|
|||
func LastRequestTime() int64 {
|
||||
return lastRequestTime
|
||||
}
|
||||
|
||||
// SetClientCertificate sets the client certificate to use for a domain.
|
||||
func SetClientCertificate(domain string, certificate string, privateKey string) error {
|
||||
if len(certificate) == 0 || len(privateKey) == 0 {
|
||||
delete(clientCerts, domain)
|
||||
return nil
|
||||
}
|
||||
|
||||
clientCert, err := tls.LoadX509KeyPair(certificate, privateKey)
|
||||
if err != nil {
|
||||
return ErrInvalidCertificate
|
||||
}
|
||||
|
||||
clientCerts[domain] = clientCert
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue