Use plain integers to represent status codes

This commit is contained in:
Adnan Maolood 2021-02-09 09:41:36 -05:00
parent 9bfb007581
commit 5ef5824d6f
3 changed files with 43 additions and 47 deletions

View File

@ -95,7 +95,7 @@ func do(req *gemini.Request, via []*gemini.Request) (*gemini.Response, error) {
return resp, err return resp, err
} }
switch resp.Status.Class() { switch gemini.StatusClass(resp.Status) {
case gemini.StatusClassInput: case gemini.StatusClassInput:
input, ok := getInput(resp.Meta, resp.Status == gemini.StatusSensitiveInput) input, ok := getInput(resp.Meta, resp.Status == gemini.StatusSensitiveInput)
if !ok { if !ok {
@ -148,7 +148,7 @@ func main() {
defer resp.Body.Close() defer resp.Body.Close()
// Handle response // Handle response
if resp.Status.Class() == gemini.StatusClassSuccess { if gemini.StatusClass(resp.Status) == gemini.StatusClassSuccess {
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)

View File

@ -10,7 +10,7 @@ import (
// Response is a Gemini response. // Response is a Gemini response.
type Response struct { type Response struct {
// Status contains the response status code. // Status contains the response status code.
Status Status Status int
// Meta contains more information related to the response status. // Meta contains more information related to the response status.
// For successful responses, Meta should contain the media type of the response. // For successful responses, Meta should contain the media type of the response.
@ -43,11 +43,11 @@ func ReadResponse(rc io.ReadCloser) (*Response, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp.Status = Status(status) resp.Status = status
// Disregard invalid status codes // Disregard invalid status codes
const minStatus, maxStatus = 1, 6 const minStatus, maxStatus = 1, 6
statusClass := resp.Status.Class() statusClass := resp.Status / 10
if statusClass < minStatus || statusClass > maxStatus { if statusClass < minStatus || statusClass > maxStatus {
return nil, ErrInvalidResponse return nil, ErrInvalidResponse
} }
@ -83,7 +83,7 @@ func ReadResponse(rc io.ReadCloser) (*Response, error) {
return nil, ErrInvalidResponse return nil, ErrInvalidResponse
} }
if resp.Status.Class() == StatusClassSuccess { if resp.Status/10 == StatusClassSuccess {
resp.Body = newReadCloserBody(br, rc) resp.Body = newReadCloserBody(br, rc)
} else { } else {
resp.Body = nopReadCloser{} resp.Body = nopReadCloser{}
@ -132,7 +132,7 @@ func (b *readCloserBody) Read(p []byte) (n int, err error) {
// ResponseWriter is used to construct a Gemini response. // ResponseWriter is used to construct a Gemini response.
type ResponseWriter struct { type ResponseWriter struct {
b *bufio.Writer b *bufio.Writer
status Status status int
meta string meta string
wroteHeader bool wroteHeader bool
bodyAllowed bool bodyAllowed bool
@ -146,16 +146,16 @@ func NewResponseWriter(w io.Writer) *ResponseWriter {
} }
// Header sets the response header. // Header sets the response header.
func (w *ResponseWriter) Header(status Status, meta string) { func (w *ResponseWriter) Header(status int, meta string) {
w.status = status w.status = status
w.meta = meta w.meta = meta
} }
// Status sets the response status code. // Status sets the response status code.
// It also sets the response meta to status.Meta(). // It also sets the response meta to Meta(status).
func (w *ResponseWriter) Status(status Status) { func (w *ResponseWriter) Status(status int) {
w.status = status w.status = status
w.meta = status.Meta() w.meta = Meta(status)
} }
// Meta sets the response meta. // Meta sets the response meta.
@ -183,14 +183,14 @@ func (w *ResponseWriter) Write(b []byte) (int, error) {
return w.b.Write(b) return w.b.Write(b)
} }
func (w *ResponseWriter) writeHeader(defaultStatus Status) { func (w *ResponseWriter) writeHeader(defaultStatus int) {
status := w.status status := w.status
if status == 0 { if status == 0 {
status = defaultStatus status = defaultStatus
} }
meta := w.meta meta := w.meta
if status.Class() == StatusClassSuccess { if status/10 == StatusClassSuccess {
w.bodyAllowed = true w.bodyAllowed = true
if meta == "" { if meta == "" {
@ -198,7 +198,7 @@ func (w *ResponseWriter) writeHeader(defaultStatus Status) {
} }
} }
w.b.WriteString(strconv.Itoa(int(status))) w.b.WriteString(strconv.Itoa(status))
w.b.WriteByte(' ') w.b.WriteByte(' ')
w.b.WriteString(meta) w.b.WriteString(meta)
w.b.Write(crlf) w.b.Write(crlf)

View File

@ -1,51 +1,47 @@
package gemini package gemini
// Status codes. // Status codes.
type Status int
const ( const (
StatusInput Status = 10 StatusInput = 10
StatusSensitiveInput Status = 11 StatusSensitiveInput = 11
StatusSuccess Status = 20 StatusSuccess = 20
StatusRedirect Status = 30 StatusRedirect = 30
StatusPermanentRedirect Status = 31 StatusPermanentRedirect = 31
StatusTemporaryFailure Status = 40 StatusTemporaryFailure = 40
StatusServerUnavailable Status = 41 StatusServerUnavailable = 41
StatusCGIError Status = 42 StatusCGIError = 42
StatusProxyError Status = 43 StatusProxyError = 43
StatusSlowDown Status = 44 StatusSlowDown = 44
StatusPermanentFailure Status = 50 StatusPermanentFailure = 50
StatusNotFound Status = 51 StatusNotFound = 51
StatusGone Status = 52 StatusGone = 52
StatusProxyRequestRefused Status = 53 StatusProxyRequestRefused = 53
StatusBadRequest Status = 59 StatusBadRequest = 59
StatusCertificateRequired Status = 60 StatusCertificateRequired = 60
StatusCertificateNotAuthorized Status = 61 StatusCertificateNotAuthorized = 61
StatusCertificateNotValid Status = 62 StatusCertificateNotValid = 62
) )
// Status code categories. // Status code categories.
type StatusClass int
const ( const (
StatusClassInput StatusClass = 1 StatusClassInput = 1
StatusClassSuccess StatusClass = 2 StatusClassSuccess = 2
StatusClassRedirect StatusClass = 3 StatusClassRedirect = 3
StatusClassTemporaryFailure StatusClass = 4 StatusClassTemporaryFailure = 4
StatusClassPermanentFailure StatusClass = 5 StatusClassPermanentFailure = 5
StatusClassCertificateRequired StatusClass = 6 StatusClassCertificateRequired = 6
) )
// Class returns the status class for this status code. // StatusClass returns the status class for this status code.
func (s Status) Class() StatusClass { func StatusClass(status int) int {
return StatusClass(s / 10) return status / 10
} }
// Meta returns a description of the status code appropriate for use in a response. // Meta returns a description of the status code appropriate for use in a response.
// //
// Meta returns an empty string for input, success, and redirect status codes. // Meta returns an empty string for input, success, and redirect status codes.
func (s Status) Meta() string { func Meta(status int) string {
switch s { switch status {
case StatusTemporaryFailure: case StatusTemporaryFailure:
return "Temporary failure" return "Temporary failure"
case StatusServerUnavailable: case StatusServerUnavailable: