Example #1
0
func sendHTMLEmail(email, subject, plainBody, htmlBody string) error {
	if htmlBody == "" {
		return sendPlainEmail(email, subject, plainBody)
	}

	var buf bytes.Buffer
	w := multipart.NewWriter(&buf)

	appendPart(w, func(h textproto.MIMEHeader) {
		h.Set("Content-Type", "text/plain; charset=utf-8")
	}, plainBody)

	appendPart(w, func(h textproto.MIMEHeader) {
		h.Set("Content-Type", "text/html; charset=utf-8")
	}, htmlBody)

	sendemail.SendAsync(&sendemail.Email{
		To: []string{email},
		Headers: map[string][]string{
			"Subject":      []string{subject},
			"MIME-Version": []string{"1.0"},
			"Content-Type": []string{"multipart/alternative; boundary=" + w.Boundary()},
		},
		Body: string(buf.Bytes()),
	})

	return nil
}
Example #2
0
func sendPlainEmail(email, subject, plainBody string) error {
	sendemail.SendAsync(&sendemail.Email{
		To: []string{email},
		Headers: map[string][]string{
			"Subject": []string{subject},
		},
		Body: plainBody,
	})

	return nil
}
Example #3
0
func renderError(rw http.ResponseWriter, req *http.Request, reqerr interface{}, stack []byte) {
	_, filePath, line, _ := runtime.Caller(4)

	cErrorResponsesIssued.Inc()

	rw.Header().Set("Content-Type", "text/html; charset=utf-8")
	rw.Header().Del("Content-Security-Policy")
	rw.Header().Del("Content-Security-Policy-Report-Only")
	rw.WriteHeader(http.StatusInternalServerError)

	type info struct {
		Error         interface{} `yaml:"error"`
		Stack         string      `yaml:"stack"`
		URL           string      `yaml:"url"`
		Method        string      `yaml:"method"`
		Proto         string      `yaml:"proto"`
		Header        http.Header `yaml:"header"`
		ContentLength int64       `yaml:"content-length"`
		RawRemoteAddr string      `yaml:"raw-remote-addr"`
		Host          string      `yaml:"host"`
		FilePath      string      `yaml:"file-path"`
		FileLine      int         `yaml:"file-line"`
		Time          string      `yaml:"time"`
		PostForm      url.Values  `yaml:"post-form"`
	}

	errInfo := info{
		Error:         reqerr,
		Stack:         strings.Replace(string(stack), "\t", "  ", -1),
		URL:           req.URL.String(),
		Method:        req.Method,
		Proto:         req.Proto,
		Header:        req.Header,
		ContentLength: req.ContentLength,
		RawRemoteAddr: req.RemoteAddr,
		Host:          req.Host,
		FilePath:      filePath,
		FileLine:      line,
		Time:          time.Now().String(),
	}
	if req.ContentLength >= 0 && req.ContentLength <= 4*1024 { // 4k size limit
		errInfo.PostForm = req.PostForm
	}

	b, err := yaml.Marshal(&errInfo)
	log.Infoe(err, "marshalling emergency error information") // ...

	shouldEncrypt, shouldEmail := errorMode(req)

	var encryptedError string
	if shouldEncrypt {
		encryptedError = encryptErrorBase64(b)
	}

	data := map[string]interface{}{
		"EncryptedBlob":    encryptedError,
		"Info":             string(b),
		"Encrypted":        shouldEncrypt,
		"WebmasterAddress": webmasterAddressFlag.Value(),
		"Notified":         shouldEmail,
	}

	emergencyErrorTemplate.Execute(rw, data)

	// send e. mail
	if shouldEmail {
		emailBuf := new(bytes.Buffer)
		emergencyErrorEmailTemplate.Execute(emailBuf, data)

		subjectLine := fmt.Sprintf("%s panic", exepath.ProgramName)

		sendemail.SendAsync(&sendemail.Email{
			To: []string{panicsToFlag.Value()},
			Headers: map[string][]string{
				"Subject": []string{subjectLine},
			},
			Body: string(emailBuf.Bytes()),
		})
	}
}