in src/main/java/com/microsoft/azure/proton/transport/proxy/impl/ProxyResponseImpl.java [48:122]
public static ProxyResponse create(ByteBuffer buffer) {
// Because we've flipped the buffer, position = 0, and the limit = size of the content.
int size = buffer.remaining();
if (size <= 0) {
throw new IllegalArgumentException(String.format("Cannot create response with buffer have no content. "
+ "Limit: %s. Position: %s. Cap: %s", buffer.limit(), buffer.position(), buffer.capacity()));
}
final byte[] responseBytes = new byte[size];
buffer.get(responseBytes);
final String response = new String(responseBytes, StandardCharsets.UTF_8);
final String[] lines = response.split(StringUtils.NEW_LINE);
final Map<String, List<String>> headers = new HashMap<>();
WebSocketFrameReadState frameReadState = WebSocketFrameReadState.INIT_READ;
HttpStatusLine statusLine = null;
ByteBuffer contents = ByteBuffer.allocate(0);
//Assume the full header message is in the first frame
for (String line : lines) {
switch (frameReadState) {
case INIT_READ:
statusLine = HttpStatusLine.create(line);
frameReadState = WebSocketFrameReadState.CHUNK_READ;
break;
case CHUNK_READ:
if (StringUtils.isNullOrEmpty(line)) {
// Now that we're done reading all the headers, figure out the size of the HTTP body and
// allocate an array of that size.
int length = 0;
if (headers.containsKey(CONTENT_LENGTH)) {
final List<String> contentLength = headers.get(CONTENT_LENGTH);
length = Integer.parseInt(contentLength.get(0));
}
boolean hasBody = length > 0;
if (!hasBody) {
LOGGER.info("There is no content in the response. Response: {}", response);
return new ProxyResponseImpl(statusLine, headers, contents);
}
contents = ByteBuffer.allocate(length);
frameReadState = WebSocketFrameReadState.HEADER_READ;
} else {
final Map.Entry<String, String> header = parseHeader(line);
final List<String> value = headers.getOrDefault(header.getKey(), new ArrayList<>());
value.add(header.getValue());
headers.put(header.getKey(), value);
}
break;
case HEADER_READ:
if (contents.position() == 0) {
frameReadState = WebSocketFrameReadState.CONTINUED_FRAME_READ;
}
contents.put(line.getBytes(StandardCharsets.UTF_8));
contents.mark();
break;
case CONTINUED_FRAME_READ:
contents.put(line.getBytes(StandardCharsets.UTF_8));
contents.mark();
break;
default:
LOGGER.error("Unknown state: {}. Response: {}", frameReadState, response);
frameReadState = WebSocketFrameReadState.READ_ERROR;
break;
}
}
return new ProxyResponseImpl(statusLine, headers, contents);
}