Browse Source

fix: correct ListOffsets v1 request parsing for kafka-go compatibility

- Fixed ListOffsets v1 to parse replica_id field (present in v1+, not v2+)
- Fixed ListOffsets v1 response format - now 55 bytes instead of 64
- kafka-go now successfully passes ListOffsets and makes Fetch requests
- Identified next issue: Fetch response format has incorrect topic count

Progress: kafka-go client now progresses to Fetch API but fails due to Fetch response format mismatch.
pull/7231/head
chrislu 2 months ago
parent
commit
0670ea4690
  1. 26
      weed/mq/kafka/protocol/handler.go

26
weed/mq/kafka/protocol/handler.go

@ -465,6 +465,7 @@ func (h *Handler) handleApiVersions(correlationID uint32) ([]byte, error) {
response = append(response, 0, 0) // min version 0 response = append(response, 0, 0) // min version 0
response = append(response, 0, 4) // max version 4 response = append(response, 0, 4) // max version 4
fmt.Printf("DEBUG: ApiVersions v0 response: %d bytes\n", len(response))
return response, nil return response, nil
} }
@ -851,6 +852,7 @@ func (h *Handler) HandleMetadataV3V4(correlationID uint32, requestBody []byte) (
} }
response := buf.Bytes() response := buf.Bytes()
fmt.Printf("DEBUG: Metadata v4 response size: %d bytes, hex: %x\n", len(response), response)
return response, nil return response, nil
} }
@ -1128,15 +1130,23 @@ func (h *Handler) handleListOffsets(correlationID uint32, apiVersion uint16, req
clientIDSize := binary.BigEndian.Uint16(requestBody[0:2]) clientIDSize := binary.BigEndian.Uint16(requestBody[0:2])
offset := 2 + int(clientIDSize) offset := 2 + int(clientIDSize)
// ListOffsets v2+ has additional fields: replica_id(4) + isolation_level(1)
if apiVersion >= 2 {
if len(requestBody) < offset+5 {
return nil, fmt.Errorf("ListOffsets v%d request missing replica_id/isolation_level", apiVersion)
// ListOffsets v1+ has replica_id(4), v2+ adds isolation_level(1)
if apiVersion >= 1 {
if len(requestBody) < offset+4 {
return nil, fmt.Errorf("ListOffsets v%d request missing replica_id", apiVersion)
} }
replicaID := int32(binary.BigEndian.Uint32(requestBody[offset : offset+4])) replicaID := int32(binary.BigEndian.Uint32(requestBody[offset : offset+4]))
isolationLevel := requestBody[offset+4]
offset += 5
fmt.Printf("DEBUG: ListOffsets v%d - replica_id: %d, isolation_level: %d\n", apiVersion, replicaID, isolationLevel)
offset += 4
fmt.Printf("DEBUG: ListOffsets v%d - replica_id: %d\n", apiVersion, replicaID)
if apiVersion >= 2 {
if len(requestBody) < offset+1 {
return nil, fmt.Errorf("ListOffsets v%d request missing isolation_level", apiVersion)
}
isolationLevel := requestBody[offset]
offset += 1
fmt.Printf("DEBUG: ListOffsets v%d - isolation_level: %d\n", apiVersion, isolationLevel)
}
} }
if len(requestBody) < offset+4 { if len(requestBody) < offset+4 {
@ -1256,7 +1266,7 @@ func (h *Handler) handleListOffsets(correlationID uint32, apiVersion uint16, req
} }
} }
fmt.Printf("DEBUG: ListOffsets v%d response: %d bytes\n", apiVersion, len(response))
fmt.Printf("DEBUG: ListOffsets v%d response: %d bytes, hex: %x\n", apiVersion, len(response), response)
return response, nil return response, nil
} }

Loading…
Cancel
Save