Holding server response header data after parsing it I'm creating a program to retrieve web content in order to learn how these things work. I would like it to be as correct as possible, ideally fully compliant.

But I'm not sure this is the right approach to the problem. Is the following structure an appropriate way to hold server response header data after parsing it?

typedef enum {
    OPTIONS = 1, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT, PATCH
} HTTP_Methods;

typedef enum {
    KEEP_ALIVE = 1, CLOSE
} HTTP_Connection_Field;

typedef enum {
    CHUNKED = 1, COMPRESS, DEFLATE, GZIP, IDENTITY
} HTTP_Transfer_Encoding;

typedef struct {
    uint8_t http_version; //e.g. HTTP/1.1 = 11, HTTP/1.0 = 10, HTTP/0.9 = 9
    uint16_t response_code; //e.g. 200, 404, 500, ...
    char *accept_ranges;
    uint32_t age; //Non-negative, time in seconds, at least 31 bits of range
    HTTP_Methods allow;
    char *cache_control;
    HTTP_Connection_Field connection;
    char *content_encoding;
    char *content_language;
    uint32_t content_length;
    char *content_location;
    char *content_MD5;
    char *content_disposition;
    char *content_range;
    char *content_type;
    time_t date;
    char *etag;
    time_t expires;
    time_t last_modified;
    char *link;
    char *location;
    char *p3p;
    char *pragma;
    char *proxy_authenticate;
    char *refresh;
    time_t retry_after;
    char *server;
    char *set_cookie;
    char *strict_transport_security;
    char *trailer;
    HTTP_Transfer_Encoding transfer_encoding;
    char *vary;
    char *via;
    char *warning;
    char *www_authenticate;
} HTTP_Response_Header;


Maybe grouping the members that are not very commonly used into a different struct that is only allocated when they are in use would be a better idea?
The way I would do it is by simply representing the headers as map of char* to char*. That'll be the most flexible and extensible situation, since HTTP headers are added over time, and custom headers are completely acceptable and allowed for by the standard. Any solution involving struct fields will require updating as the standard expands, and can't handle custom headers easily. (You could handle custom headers the same way as standard ones, but then you'd have the problem that their meaning is not standard, and different clients could use them to represent different things.)

The downside of making the map values be char* is that you'll have to translate into the proper data type wherever you retrieve them from the map, rather than only performing this translation when you read the request headers. This is an acceptable trade-off for the flexibility you gain, and you can find a way to encapsulate it if desired.