Remember how libcurl transfers are associated with an "easy handle"! Each transfer has such a handle and when a transfer is completed, before the handle is cleaned or reused for another transfer, it can be used to extract information from the previous operation.
Your friend for doing this is called curl_easy_getinfo() and you tell it which specific information you are interested in and it will return that to you if it can.
When you use this function, you pass in the easy handle, which information you want and a pointer to a variable to hold the answer. You must pass in a pointer to a variable of the correct type or you risk that things will go side-ways. These information values are designed to be provided after the transfer is completed.
The data you receive can be a long, a 'char *', a 'struct curl_slist *', a double or a socket.
This is how you extract the Content-Type: value from the previous HTTP transfer:
CURLcode res;
char *content_type;
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &content_type);
If you want to extract the local port number that was used in that connection:
CURLcode res;
long port_number;
res = curl_easy_getinfo(curl, CURLINFO_LOCAL_PORT, &port_number);
Available information
Getinfo option
Type
Description
CURLINFO_ACTIVESOCKET
curl_socket_t
The session's active socket
CURLINFO_APPCONNECT_TIME
double
Time from start until SSL/SSH handshake completed
CURLINFO_APPCONNECT_TIME_T
curl_off_t
Time from start until SSL/SSH handshake completed (in microseconds)
CURLINFO_CERTINFO
struct curl_slist *
Certificate chain
CURLINFO_CONDITION_UNMET
long
Whether or not a time conditional was met
CURLINFO_CONNECT_TIME
double
Time from start until remote host or proxy completed
CURLINFO_CONNECT_TIME_T
curl_off_t
Time from start until remote host or proxy completed (in microseconds)