| 906 | #endif |
| 907 | |
| 908 | static Result HandleResponse(HClient client, const char* path, const char* method, Response* response) |
| 909 | { |
| 910 | Result r = RESULT_OK; |
| 911 | |
| 912 | client->m_HttpContent(response, client->m_Userdata, response->m_Status, 0, 0, 0, 0, 0, 0, 0); |
| 913 | |
| 914 | if ((strcmp(method, "HEAD") == 0) || (strcmp(method, "CONNECT") == 0)) { |
| 915 | // A response from a HEAD or CONNECT request should not attempt to read |
| 916 | // any body despite content length being non-zero, but we still call |
| 917 | // DoTransfer (with a content length of 0) to ensure that the response |
| 918 | // is setup properly |
| 919 | r = DoTransfer(client, response, 0, client->m_HttpContent, false, method); |
| 920 | } |
| 921 | else if (response->m_Chunked) |
| 922 | { |
| 923 | // Chunked encoding |
| 924 | // Move actual data to the beginning of the buffer |
| 925 | memmove(client->m_Buffer, client->m_Buffer + response->m_ContentOffset, response->m_TotalReceived - response->m_ContentOffset); |
| 926 | |
| 927 | response->m_TotalReceived = response->m_TotalReceived - response->m_ContentOffset; |
| 928 | response->m_ContentOffset = 0; |
| 929 | |
| 930 | int chunk_size; |
| 931 | while(true) |
| 932 | { |
| 933 | chunk_size = 0; |
| 934 | // NOTE: We have an extra byte for null-termination so no buffer overrun here. |
| 935 | client->m_Buffer[response->m_TotalReceived] = '\0'; |
| 936 | |
| 937 | char* chunk_size_end = strstr(client->m_Buffer, "\r\n"); |
| 938 | if (chunk_size_end) |
| 939 | { |
| 940 | // We found a chunk |
| 941 | sscanf(client->m_Buffer, "%x", &chunk_size); |
| 942 | chunk_size_end += 2; // "\r\n" |
| 943 | |
| 944 | // Move content-offset after chunk termination, ie after "\r\n" |
| 945 | response->m_ContentOffset = chunk_size_end - client->m_Buffer; |
| 946 | r = DoTransfer(client, response, chunk_size, client->m_HttpContent, true, method); |
| 947 | if (r != RESULT_OK) |
| 948 | break; |
| 949 | |
| 950 | // Consume \r\n" |
| 951 | // NOTE: *not* added to cache |
| 952 | r = DoTransfer(client, response, 2, &HttpContentConsume, false, method); |
| 953 | if (r != RESULT_OK) |
| 954 | break; |
| 955 | |
| 956 | if (chunk_size == 0) |
| 957 | { |
| 958 | r = RESULT_OK; |
| 959 | break; |
| 960 | } |
| 961 | } |
| 962 | else |
| 963 | { |
| 964 | // We need more data |
| 965 | int max_to_recv = BUFFER_SIZE - response->m_TotalReceived; |
no test coverage detected