Make ResponseWriter an interface
This commit is contained in:
		
							parent
							
								
									5ef5824d6f
								
							
						
					
					
						commit
						f6824bd813
					
				@ -54,7 +54,7 @@ func fingerprint(cert *x509.Certificate) string {
 | 
			
		||||
	return string(b[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func profile(w *gemini.ResponseWriter, r *gemini.Request) {
 | 
			
		||||
func profile(w gemini.ResponseWriter, r *gemini.Request) {
 | 
			
		||||
	if r.Certificate == nil {
 | 
			
		||||
		w.Status(gemini.StatusCertificateRequired)
 | 
			
		||||
		return
 | 
			
		||||
@ -69,7 +69,7 @@ func profile(w *gemini.ResponseWriter, r *gemini.Request) {
 | 
			
		||||
	fmt.Fprintln(w, "=> /username Change username")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func changeUsername(w *gemini.ResponseWriter, r *gemini.Request) {
 | 
			
		||||
func changeUsername(w gemini.ResponseWriter, r *gemini.Request) {
 | 
			
		||||
	if r.Certificate == nil {
 | 
			
		||||
		w.Status(gemini.StatusCertificateRequired)
 | 
			
		||||
		return
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,7 @@ func main() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stream writes an infinite stream to w.
 | 
			
		||||
func stream(w *gemini.ResponseWriter, r *gemini.Request) {
 | 
			
		||||
func stream(w gemini.ResponseWriter, r *gemini.Request) {
 | 
			
		||||
	ch := make(chan string)
 | 
			
		||||
	ctx, cancel := context.WithCancel(context.Background())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								fs.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								fs.go
									
									
									
									
									
								
							@ -26,7 +26,7 @@ type fsHandler struct {
 | 
			
		||||
	FS
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fsh fsHandler) ServeGemini(w *ResponseWriter, r *Request) {
 | 
			
		||||
func (fsh fsHandler) ServeGemini(w ResponseWriter, r *Request) {
 | 
			
		||||
	p := path.Clean(r.URL.Path)
 | 
			
		||||
	f, err := fsh.Open(p)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@ -73,7 +73,7 @@ func (d Dir) Open(name string) (File, error) {
 | 
			
		||||
// or directory.
 | 
			
		||||
//
 | 
			
		||||
// TODO: Use io/fs.FS when available.
 | 
			
		||||
func ServeFile(w *ResponseWriter, fs FS, name string) {
 | 
			
		||||
func ServeFile(w ResponseWriter, fs FS, name string) {
 | 
			
		||||
	f, err := fs.Open(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		w.Status(StatusNotFound)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								mux.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								mux.go
									
									
									
									
									
								
							@ -132,7 +132,7 @@ func (mux *ServeMux) shouldRedirectRLocked(path string) bool {
 | 
			
		||||
 | 
			
		||||
// ServeGemini dispatches the request to the handler whose
 | 
			
		||||
// pattern most closely matches the request URL.
 | 
			
		||||
func (mux *ServeMux) ServeGemini(w *ResponseWriter, r *Request) {
 | 
			
		||||
func (mux *ServeMux) ServeGemini(w ResponseWriter, r *Request) {
 | 
			
		||||
	path := cleanPath(r.URL.Path)
 | 
			
		||||
 | 
			
		||||
	// If the given path is /tree and its handler is not registered,
 | 
			
		||||
@ -202,7 +202,7 @@ func appendSorted(es []muxEntry, e muxEntry) []muxEntry {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HandleFunc registers the handler function for the given pattern.
 | 
			
		||||
func (mux *ServeMux) HandleFunc(pattern string, handler func(*ResponseWriter, *Request)) {
 | 
			
		||||
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
 | 
			
		||||
	if handler == nil {
 | 
			
		||||
		panic("gemini: nil responder")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										69
									
								
								response.go
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								response.go
									
									
									
									
									
								
							@ -129,8 +129,39 @@ func (b *readCloserBody) Read(p []byte) (n int, err error) {
 | 
			
		||||
	return b.ReadCloser.Read(p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResponseWriter is used to construct a Gemini response.
 | 
			
		||||
type ResponseWriter struct {
 | 
			
		||||
// A ResponseWriter interface is used by a Gemini handler
 | 
			
		||||
// to construct a Gemini response.
 | 
			
		||||
type ResponseWriter interface {
 | 
			
		||||
	// Header sets the response header.
 | 
			
		||||
	Header(status int, meta string)
 | 
			
		||||
 | 
			
		||||
	// Status sets the response status code.
 | 
			
		||||
	// It also sets the response meta to Meta(status).
 | 
			
		||||
	Status(status int)
 | 
			
		||||
 | 
			
		||||
	// Meta sets the response meta.
 | 
			
		||||
	//
 | 
			
		||||
	// For successful responses, meta should contain the media type of the response.
 | 
			
		||||
	// For failure responses, meta should contain a short description of the failure.
 | 
			
		||||
	// The response meta should not be greater than 1024 bytes.
 | 
			
		||||
	Meta(meta string)
 | 
			
		||||
 | 
			
		||||
	// Write writes data to the connection as part of the response body.
 | 
			
		||||
	// If the response status does not allow for a response body, Write returns
 | 
			
		||||
	// ErrBodyNotAllowed.
 | 
			
		||||
	//
 | 
			
		||||
	// Write writes the response header if it has not already been written.
 | 
			
		||||
	// It writes a successful status code if one is not set.
 | 
			
		||||
	Write([]byte) (int, error)
 | 
			
		||||
 | 
			
		||||
	// Flush writes any buffered data to the underlying io.Writer.
 | 
			
		||||
	//
 | 
			
		||||
	// Flush writes the response header if it has not already been written.
 | 
			
		||||
	// It writes a failure status code if one is not set.
 | 
			
		||||
	Flush() error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type responseWriter struct {
 | 
			
		||||
	b           *bufio.Writer
 | 
			
		||||
	status      int
 | 
			
		||||
	meta        string
 | 
			
		||||
@ -139,41 +170,27 @@ type ResponseWriter struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewResponseWriter returns a ResponseWriter that uses the provided io.Writer.
 | 
			
		||||
func NewResponseWriter(w io.Writer) *ResponseWriter {
 | 
			
		||||
	return &ResponseWriter{
 | 
			
		||||
func NewResponseWriter(w io.Writer) ResponseWriter {
 | 
			
		||||
	return &responseWriter{
 | 
			
		||||
		b: bufio.NewWriter(w),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Header sets the response header.
 | 
			
		||||
func (w *ResponseWriter) Header(status int, meta string) {
 | 
			
		||||
func (w *responseWriter) Header(status int, meta string) {
 | 
			
		||||
	w.status = status
 | 
			
		||||
	w.meta = meta
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Status sets the response status code.
 | 
			
		||||
// It also sets the response meta to Meta(status).
 | 
			
		||||
func (w *ResponseWriter) Status(status int) {
 | 
			
		||||
func (w *responseWriter) Status(status int) {
 | 
			
		||||
	w.status = status
 | 
			
		||||
	w.meta = Meta(status)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Meta sets the response meta.
 | 
			
		||||
//
 | 
			
		||||
// For successful responses, meta should contain the media type of the response.
 | 
			
		||||
// For failure responses, meta should contain a short description of the failure.
 | 
			
		||||
// The response meta should not be greater than 1024 bytes.
 | 
			
		||||
func (w *ResponseWriter) Meta(meta string) {
 | 
			
		||||
func (w *responseWriter) Meta(meta string) {
 | 
			
		||||
	w.meta = meta
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write writes data to the connection as part of the response body.
 | 
			
		||||
// If the response status does not allow for a response body, Write returns
 | 
			
		||||
// ErrBodyNotAllowed.
 | 
			
		||||
//
 | 
			
		||||
// Write writes the response header if it has not already been written.
 | 
			
		||||
// It writes a successful status code if one is not set.
 | 
			
		||||
func (w *ResponseWriter) Write(b []byte) (int, error) {
 | 
			
		||||
func (w *responseWriter) Write(b []byte) (int, error) {
 | 
			
		||||
	if !w.wroteHeader {
 | 
			
		||||
		w.writeHeader(StatusSuccess)
 | 
			
		||||
	}
 | 
			
		||||
@ -183,7 +200,7 @@ func (w *ResponseWriter) Write(b []byte) (int, error) {
 | 
			
		||||
	return w.b.Write(b)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (w *ResponseWriter) writeHeader(defaultStatus int) {
 | 
			
		||||
func (w *responseWriter) writeHeader(defaultStatus int) {
 | 
			
		||||
	status := w.status
 | 
			
		||||
	if status == 0 {
 | 
			
		||||
		status = defaultStatus
 | 
			
		||||
@ -205,11 +222,7 @@ func (w *ResponseWriter) writeHeader(defaultStatus int) {
 | 
			
		||||
	w.wroteHeader = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Flush writes any buffered data to the underlying io.Writer.
 | 
			
		||||
//
 | 
			
		||||
// Flush writes the response header if it has not already been written.
 | 
			
		||||
// It writes a failure status code if one is not set.
 | 
			
		||||
func (w *ResponseWriter) Flush() error {
 | 
			
		||||
func (w *responseWriter) Flush() error {
 | 
			
		||||
	if !w.wroteHeader {
 | 
			
		||||
		w.writeHeader(StatusTemporaryFailure)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -83,7 +83,7 @@ func (s *Server) Handle(pattern string, handler Handler) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HandleFunc registers the handler function for the given pattern.
 | 
			
		||||
func (s *Server) HandleFunc(pattern string, handler func(*ResponseWriter, *Request)) {
 | 
			
		||||
func (s *Server) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
 | 
			
		||||
	s.Handle(pattern, HandlerFunc(handler))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -258,15 +258,15 @@ func (s *Server) logf(format string, args ...interface{}) {
 | 
			
		||||
// ServeGemini should write the response header and data to the ResponseWriter
 | 
			
		||||
// and then return.
 | 
			
		||||
type Handler interface {
 | 
			
		||||
	ServeGemini(*ResponseWriter, *Request)
 | 
			
		||||
	ServeGemini(ResponseWriter, *Request)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The HandlerFunc type is an adapter to allow the use of ordinary functions
 | 
			
		||||
// as Gemini handlers. If f is a function with the appropriate signature,
 | 
			
		||||
// HandlerFunc(f) is a Handler that calls f.
 | 
			
		||||
type HandlerFunc func(*ResponseWriter, *Request)
 | 
			
		||||
type HandlerFunc func(ResponseWriter, *Request)
 | 
			
		||||
 | 
			
		||||
// ServeGemini calls f(w, r).
 | 
			
		||||
func (f HandlerFunc) ServeGemini(w *ResponseWriter, r *Request) {
 | 
			
		||||
func (f HandlerFunc) ServeGemini(w ResponseWriter, r *Request) {
 | 
			
		||||
	f(w, r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user