-
Notifications
You must be signed in to change notification settings - Fork 101
refactor: extract readRequestBody and parseBoolQueryParam helpers #745
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,23 @@ import ( | |
|
|
||
| type contextKey bool | ||
|
|
||
| // readRequestBody reads up to maxSize bytes from the request body and writes | ||
| // an appropriate HTTP error if reading fails. Returns (body, true) on success | ||
| // or (nil, false) after writing the error response. | ||
| func readRequestBody(w http.ResponseWriter, r *http.Request, maxSize int64) ([]byte, bool) { | ||
| body, err := io.ReadAll(http.MaxBytesReader(w, r.Body, maxSize)) | ||
| if err != nil { | ||
| var maxBytesError *http.MaxBytesError | ||
| if errors.As(err, &maxBytesError) { | ||
| http.Error(w, "request too large", http.StatusBadRequest) | ||
| } else { | ||
| http.Error(w, "failed to read request body", http.StatusInternalServerError) | ||
| } | ||
| return nil, false | ||
| } | ||
| return body, true | ||
| } | ||
|
|
||
| const preloadOnlyKey contextKey = false | ||
|
|
||
| // HTTPHandler handles HTTP requests for the scheduler. | ||
|
|
@@ -132,14 +149,8 @@ func (h *HTTPHandler) handleOpenAIInference(w http.ResponseWriter, r *http.Reque | |
|
|
||
| // Read the entire request body. We put some basic size constraints in place | ||
| // to avoid DoS attacks. We do this early to avoid client write timeouts. | ||
| body, err := io.ReadAll(http.MaxBytesReader(w, r.Body, maximumOpenAIInferenceRequestSize)) | ||
| if err != nil { | ||
| var maxBytesError *http.MaxBytesError | ||
| if errors.As(err, &maxBytesError) { | ||
| http.Error(w, "request too large", http.StatusBadRequest) | ||
| } else { | ||
| http.Error(w, "failed to read request body", http.StatusInternalServerError) | ||
| } | ||
| body, ok := readRequestBody(w, r, maximumOpenAIInferenceRequestSize) | ||
| if !ok { | ||
| return | ||
| } | ||
|
|
||
|
|
@@ -338,14 +349,8 @@ func (h *HTTPHandler) GetDiskUsage(w http.ResponseWriter, _ *http.Request) { | |
| // Unload unloads the specified runners (backend, model) from the backend. | ||
| // Currently, this doesn't work for runners that are handling an OpenAI request. | ||
| func (h *HTTPHandler) Unload(w http.ResponseWriter, r *http.Request) { | ||
| body, err := io.ReadAll(http.MaxBytesReader(w, r.Body, maximumOpenAIInferenceRequestSize)) | ||
| if err != nil { | ||
| var maxBytesError *http.MaxBytesError | ||
| if errors.As(err, &maxBytesError) { | ||
| http.Error(w, "request too large", http.StatusBadRequest) | ||
| } else { | ||
| http.Error(w, "failed to read request body", http.StatusInternalServerError) | ||
| } | ||
| body, ok := readRequestBody(w, r, maximumOpenAIInferenceRequestSize) | ||
| if !ok { | ||
| return | ||
| } | ||
|
|
||
|
|
@@ -371,14 +376,8 @@ type installBackendRequest struct { | |
| // InstallBackend handles POST <inference-prefix>/install-backend requests. | ||
| // It triggers on-demand installation of a deferred backend. | ||
| func (h *HTTPHandler) InstallBackend(w http.ResponseWriter, r *http.Request) { | ||
| body, err := io.ReadAll(http.MaxBytesReader(w, r.Body, maximumOpenAIInferenceRequestSize)) | ||
| if err != nil { | ||
| var maxBytesError *http.MaxBytesError | ||
| if errors.As(err, &maxBytesError) { | ||
| http.Error(w, "request too large", http.StatusBadRequest) | ||
| } else { | ||
| http.Error(w, "failed to read request body", http.StatusInternalServerError) | ||
| } | ||
| body, ok := readRequestBody(w, r, maximumOpenAIInferenceRequestSize) | ||
| if !ok { | ||
| return | ||
| } | ||
|
|
||
|
|
@@ -414,14 +413,8 @@ func (h *HTTPHandler) Configure(w http.ResponseWriter, r *http.Request) { | |
| return | ||
| } | ||
|
|
||
| body, err := io.ReadAll(http.MaxBytesReader(w, r.Body, maximumOpenAIInferenceRequestSize)) | ||
| if err != nil { | ||
| var maxBytesError *http.MaxBytesError | ||
| if errors.As(err, &maxBytesError) { | ||
| http.Error(w, "request too large", http.StatusBadRequest) | ||
| } else { | ||
| http.Error(w, "failed to read request body", http.StatusInternalServerError) | ||
| } | ||
| body, ok := readRequestBody(w, r, maximumOpenAIInferenceRequestSize) | ||
| if !ok { | ||
| return | ||
| } | ||
|
|
||
|
|
@@ -433,7 +426,7 @@ func (h *HTTPHandler) Configure(w http.ResponseWriter, r *http.Request) { | |
| return | ||
| } | ||
|
|
||
| backend, err = h.scheduler.ConfigureRunner(r.Context(), backend, configureRequest, r.UserAgent()) | ||
| backend, err := h.scheduler.ConfigureRunner(r.Context(), backend, configureRequest, r.UserAgent()) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): Avoid shadowing the outer This line used to reassign the existing |
||
| if err != nil { | ||
| if errors.Is(err, errRunnerAlreadyActive) { | ||
| http.Error(w, err.Error(), http.StatusConflict) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current implementation of
parseBoolQueryParamtreats a query parameter present without a value (e.g.,?force) asfalsebecauser.URL.Query().Get("force")returns an empty string, andstrconv.ParseBool("")results in an error. This is likely not the expected behavior for users of the API, who would probably expect the presence of the flag to meantrue.I suggest modifying the logic to treat the presence of the key with an empty value as
true. This would make the API more intuitive and align with common web API conventions. The updated implementation also avoids callingr.URL.Query()multiple times and improves the warning log message to include the unparseable value.