Commit 6bcca58a authored by Andrei Mihu's avatar Andrei Mihu
Browse files

Update Docker compose files, improve handling of request bodies in RPC operations.

parent 095c7a66
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -4,6 +4,9 @@ All notable changes to this project are documented below.
The format is based on [keep a changelog](http://keepachangelog.com) and this project uses [semantic versioning](http://semver.org).

## [Unreleased]
### Changed
- RPC now allows a request payload on GET requests.
- RPC now allows omitting the `unwrap` parameter for requests with empty payloads.

## [3.18.0] - 2023-10-24
### Added
+1 −1
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ services:
      retries: 5
  nakama:
    container_name: nakama
    image: registry.heroiclabs.com/heroiclabs/nakama:3.17.1
    image: registry.heroiclabs.com/heroiclabs/nakama:3.18.0
    entrypoint:
      - "/bin/sh"
      - "-ecx"
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ services:
      timeout: 3s
      retries: 5
  nakama:
    image: registry.heroiclabs.com/heroiclabs/nakama:3.17.1
    image: registry.heroiclabs.com/heroiclabs/nakama:3.18.0
    entrypoint:
      - "/bin/sh"
      - "-ecx"
+25 −25
Original line number Diff line number Diff line
@@ -142,49 +142,49 @@ func (s *ApiServer) RpcFuncHttp(w http.ResponseWriter, r *http.Request) {
	// indicate that raw behaviour is expected.
	_, unwrap := queryParams["unwrap"]

	// Prepare input to function.
	// Prepare input to function. Attempt to read request body no matter what the HTTP method is.
	var payload string
	if r.Method == "POST" {
		b, err := io.ReadAll(r.Body)
	if b, err := io.ReadAll(r.Body); err == nil && len(b) > 0 {
		recvBytes = len(b)
		// Maybe attempt to decode to a JSON string to mimic existing GRPC Gateway behaviour.
		if !unwrap {
			err = json.Unmarshal(b, &payload)
			if err != nil {
			// Request body too large.
			if err.Error() == "http: request body too large" {
				w.Header().Set("content-type", "application/json")
				w.WriteHeader(http.StatusBadRequest)
				sentBytes, err = w.Write(requestBodyTooLargeBytes)
				sentBytes, err = w.Write(badJSONBytes)
				if err != nil {
					s.logger.Debug("Error writing response to client", zap.Error(err))
				}
				return
			}

			// Other error reading request body.
		} else {
			payload = string(b)
		}
	} else if err == io.EOF && r.Method == http.MethodGet {
		// GET requests with no request body always return an EOF immediately. A body is not usually
		// expected, so treat this as a simple GET with no request body rather than an error.
	} else if err != nil {
		// Request body too large.
		if err.Error() == "http: request body too large" {
			w.Header().Set("content-type", "application/json")
			w.WriteHeader(http.StatusInternalServerError)
			sentBytes, err = w.Write(internalServerErrorBytes)
			w.WriteHeader(http.StatusBadRequest)
			sentBytes, err = w.Write(requestBodyTooLargeBytes)
			if err != nil {
				s.logger.Debug("Error writing response to client", zap.Error(err))
			}
			return
		}
		recvBytes = len(b)

		// Maybe attempt to decode to a JSON string to mimic existing GRPC Gateway behaviour.
		if !unwrap {
			err = json.Unmarshal(b, &payload)
			if err != nil {
		// Other error reading request body.
		w.Header().Set("content-type", "application/json")
				w.WriteHeader(http.StatusBadRequest)
				sentBytes, err = w.Write(badJSONBytes)
		w.WriteHeader(http.StatusInternalServerError)
		sentBytes, err = w.Write(internalServerErrorBytes)
		if err != nil {
			s.logger.Debug("Error writing response to client", zap.Error(err))
		}
		return
	}
		} else {
			payload = string(b)
		}
	}

	queryParams.Del("http_key")