|
|
@ -33,8 +33,8 @@ import ( |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
const ( |
|
|
|
maxRequestContentLength = 1024 * 1024 * 5 |
|
|
|
defaultBodyLimit = 5 * 1024 * 1024 |
|
|
|
contentType = "application/json" |
|
|
|
contentType = "application/json" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
// https://www.jsonrpc.org/historical/json-rpc-over-http.html#id13
|
|
|
|
// https://www.jsonrpc.org/historical/json-rpc-over-http.html#id13
|
|
|
@ -253,8 +253,8 @@ type httpServerConn struct { |
|
|
|
r *http.Request |
|
|
|
r *http.Request |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func newHTTPServerConn(r *http.Request, w http.ResponseWriter) ServerCodec { |
|
|
|
func (s *Server) newHTTPServerConn(r *http.Request, w http.ResponseWriter) ServerCodec { |
|
|
|
body := io.LimitReader(r.Body, maxRequestContentLength) |
|
|
|
body := io.LimitReader(r.Body, int64(s.httpBodyLimit)) |
|
|
|
conn := &httpServerConn{Reader: body, Writer: w, r: r} |
|
|
|
conn := &httpServerConn{Reader: body, Writer: w, r: r} |
|
|
|
|
|
|
|
|
|
|
|
encoder := func(v any, isErrorResponse bool) error { |
|
|
|
encoder := func(v any, isErrorResponse bool) error { |
|
|
@ -312,7 +312,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
|
|
|
w.WriteHeader(http.StatusOK) |
|
|
|
w.WriteHeader(http.StatusOK) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
if code, err := validateRequest(r); err != nil { |
|
|
|
if code, err := s.validateRequest(r); err != nil { |
|
|
|
http.Error(w, err.Error(), code) |
|
|
|
http.Error(w, err.Error(), code) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
@ -330,19 +330,19 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
|
|
|
// until EOF, writes the response to w, and orders the server to process a
|
|
|
|
// until EOF, writes the response to w, and orders the server to process a
|
|
|
|
// single request.
|
|
|
|
// single request.
|
|
|
|
w.Header().Set("content-type", contentType) |
|
|
|
w.Header().Set("content-type", contentType) |
|
|
|
codec := newHTTPServerConn(r, w) |
|
|
|
codec := s.newHTTPServerConn(r, w) |
|
|
|
defer codec.close() |
|
|
|
defer codec.close() |
|
|
|
s.serveSingleRequest(ctx, codec) |
|
|
|
s.serveSingleRequest(ctx, codec) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// validateRequest returns a non-zero response code and error message if the
|
|
|
|
// validateRequest returns a non-zero response code and error message if the
|
|
|
|
// request is invalid.
|
|
|
|
// request is invalid.
|
|
|
|
func validateRequest(r *http.Request) (int, error) { |
|
|
|
func (s *Server) validateRequest(r *http.Request) (int, error) { |
|
|
|
if r.Method == http.MethodPut || r.Method == http.MethodDelete { |
|
|
|
if r.Method == http.MethodPut || r.Method == http.MethodDelete { |
|
|
|
return http.StatusMethodNotAllowed, errors.New("method not allowed") |
|
|
|
return http.StatusMethodNotAllowed, errors.New("method not allowed") |
|
|
|
} |
|
|
|
} |
|
|
|
if r.ContentLength > maxRequestContentLength { |
|
|
|
if r.ContentLength > int64(s.httpBodyLimit) { |
|
|
|
err := fmt.Errorf("content length too large (%d>%d)", r.ContentLength, maxRequestContentLength) |
|
|
|
err := fmt.Errorf("content length too large (%d>%d)", r.ContentLength, s.httpBodyLimit) |
|
|
|
return http.StatusRequestEntityTooLarge, err |
|
|
|
return http.StatusRequestEntityTooLarge, err |
|
|
|
} |
|
|
|
} |
|
|
|
// Allow OPTIONS (regardless of content-type)
|
|
|
|
// Allow OPTIONS (regardless of content-type)
|
|
|
|