/* * http_hdrs.c -- This file contains declarations for http headers * Created: Christopher Blizzard , 3-Aug-1998 * * Copyright (C) 1998 Free Software Foundation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "http_hdrs.h" /* entity headers */ const char http_hdr_Allow[] = "Allow"; const char http_hdr_Content_Encoding[] = "Content-Encoding"; const char http_hdr_Content_Language[] = "Content-Language"; const char http_hdr_Content_Length[] = "Content-Length"; const char http_hdr_Content_Location[] = "Content-Location"; const char http_hdr_Content_MD5[] = "Content-MD5"; const char http_hdr_Content_Range[] = "Content-Range"; const char http_hdr_Content_Type[] = "Content-Type"; const char http_hdr_Expires[] = "Expires"; const char http_hdr_Last_Modified[] = "Last-Modified"; /* general headers */ const char http_hdr_Cache_Control[] = "Cache-Control"; const char http_hdr_Connection[] = "Connection"; const char http_hdr_Date[] = "Date"; const char http_hdr_Pragma[] = "Pragma"; const char http_hdr_Transfer_Encoding[] = "Transfer-Encoding"; const char http_hdr_Update[] = "Update"; const char http_hdr_Trailer[] = "Trailer"; const char http_hdr_Via[] = "Via"; /* request headers */ const char http_hdr_Accept[] = "Accept"; const char http_hdr_Accept_Charset[] = "Accept-Charset"; const char http_hdr_Accept_Encoding[] = "Accept-Encoding"; const char http_hdr_Accept_Language[] = "Accept-Language"; const char http_hdr_Authorization[] = "Authorization"; const char http_hdr_Expect[] = "Expect"; const char http_hdr_From[] = "From"; const char http_hdr_Host[] = "Host"; const char http_hdr_If_Modified_Since[] = "If-Modified-Since"; const char http_hdr_If_Match[] = "If-Match"; const char http_hdr_If_None_Match[] = "If-None-Match"; const char http_hdr_If_Range[] = "If-Range"; const char http_hdr_If_Unmodified_Since[] = "If-Unmodified-Since"; const char http_hdr_Max_Forwards[] = "Max-Forwards"; const char http_hdr_Proxy_Authorization[] = "Proxy-Authorization"; const char http_hdr_Range[] = "Range"; const char http_hdr_Referrer[] = "Referrer"; const char http_hdr_TE[] = "TE"; const char http_hdr_User_Agent[] = "User-Agent"; /* response headers */ const char http_hdr_Accept_Ranges[] = "Accept-Ranges"; const char http_hdr_Age[] = "Age"; const char http_hdr_ETag[] = "ETag"; const char http_hdr_Location[] = "Location"; const char http_hdr_Retry_After[] = "Retry-After"; const char http_hdr_Server[] = "Server"; const char http_hdr_Vary[] = "Vary"; const char http_hdr_Warning[] = "Warning"; const char http_hdr_WWW_Authenticate[] = "WWW-Authenticate"; /* Other headers */ const char http_hdr_Set_Cookie[] = "Set-Cookie"; /* WebDAV headers */ const char http_hdr_DAV[] = "DAV"; const char http_hdr_Depth[] = "Depth"; const char http_hdr_Destination[] = "Destination"; const char http_hdr_If[] = "If"; const char http_hdr_Lock_Token[] = "Lock-Token"; const char http_hdr_Overwrite[] = "Overwrite"; const char http_hdr_Status_URI[] = "Status-URI"; const char http_hdr_Timeout[] = "Timeout"; const char *http_hdr_known_list[] = { /* entity headers */ http_hdr_Allow, http_hdr_Content_Encoding, http_hdr_Content_Language, http_hdr_Content_Length, http_hdr_Content_Location, http_hdr_Content_MD5, http_hdr_Content_Range, http_hdr_Content_Type, http_hdr_Expires, http_hdr_Last_Modified, /* general headers */ http_hdr_Cache_Control, http_hdr_Connection, http_hdr_Date, http_hdr_Pragma, http_hdr_Transfer_Encoding, http_hdr_Update, http_hdr_Trailer, http_hdr_Via, /* request headers */ http_hdr_Accept, http_hdr_Accept_Charset, http_hdr_Accept_Encoding, http_hdr_Accept_Language, http_hdr_Authorization, http_hdr_Expect, http_hdr_From, http_hdr_Host, http_hdr_If_Modified_Since, http_hdr_If_Match, http_hdr_If_None_Match, http_hdr_If_Range, http_hdr_If_Unmodified_Since, http_hdr_Max_Forwards, http_hdr_Proxy_Authorization, http_hdr_Range, http_hdr_Referrer, http_hdr_TE, http_hdr_User_Agent, /* response headers */ http_hdr_Accept_Ranges, http_hdr_Age, http_hdr_ETag, http_hdr_Location, http_hdr_Retry_After, http_hdr_Server, http_hdr_Vary, http_hdr_Warning, http_hdr_WWW_Authenticate, NULL }; /* functions dealing with headers */ const char * http_hdr_is_known(const char *a_hdr) { int l_pos = 0; const char *l_return = NULL; if (!a_hdr) goto ec; while(http_hdr_known_list[l_pos] != NULL) { if (strcasecmp(a_hdr, http_hdr_known_list[l_pos]) == 0) { l_return = http_hdr_known_list[l_pos]; break; } l_pos++; } ec: return l_return; } http_hdr_list * http_hdr_list_new(void) { http_hdr_list *l_return = NULL; l_return = (http_hdr_list *)malloc(sizeof(http_hdr_list)); memset(l_return, 0, sizeof(http_hdr_list)); return l_return; } void http_hdr_list_destroy(http_hdr_list *a_list) { int i = 0; if (a_list == NULL) return; for(i=0; i < HTTP_HDRS_MAX; i++) { if (a_list->header[i] && (http_hdr_is_known(a_list->header[i]) == NULL)) free(a_list->header[i]); if (a_list->value[i]) free(a_list->value[i]); } free (a_list); } int http_hdr_set_value_no_nts(http_hdr_list *a_list, const char *a_name_start, int a_name_len, const char *a_val_start, int a_val_len) { int l_return = 0; char *l_temp_name = NULL; char *l_temp_val = NULL; /* note that a zero len value is valid... */ if ((a_list == NULL) || (a_name_start == NULL) || (a_val_start == NULL) || (a_name_len == 0)) goto ec; l_temp_name = (char *)malloc(a_name_len + 1); memset(l_temp_name, 0, a_name_len + 1); memcpy(l_temp_name, a_name_start, a_name_len); l_temp_val = (char *)malloc(a_val_len + 1); memset(l_temp_val, 0, a_val_len + 1); memcpy(l_temp_val, a_val_start, a_val_len); /* set the value */ l_return = http_hdr_set_value(a_list, l_temp_name, l_temp_val); free(l_temp_name); free(l_temp_val); ec: return l_return; } int http_hdr_set_value(http_hdr_list *a_list, const char *a_name, const char *a_val) { int i = 0; char *l_temp_value = NULL; int l_return = 0; if ((a_list == NULL) || (a_name == NULL) || (a_val == NULL)) goto ec; l_temp_value = http_hdr_get_value(a_list, a_name); if (l_temp_value == NULL) { for (i=0; i < HTTP_HDRS_MAX; i++) { if (a_list->header[i] == NULL) { /* I promise not to mess with this value. */ l_temp_value = (char *)http_hdr_is_known(a_name); if (l_temp_value) { a_list->header[i] = l_temp_value; /* dont free this later... */ } else a_list->header[i] = strdup(a_name); a_list->value[i] = strdup(a_val); l_return = 1; break; } } } else { for(i = 0; i < HTTP_HDRS_MAX; i++) { if (a_list->value[i] == l_temp_value) { free(a_list->value[i]); a_list->value[i] = strdup(a_val); l_return = 1; break; } } } ec: return l_return; } char * http_hdr_get_value(http_hdr_list *a_list, const char *a_name) { int i = 0; char *l_return = NULL; if (a_name == NULL) goto ec; for (i=0; i < HTTP_HDRS_MAX; i++) { if (a_list->header[i] && (strcasecmp(a_list->header[i], a_name) == 0)) { if (a_list->value[i] == NULL) goto ec; l_return = a_list->value[i]; break; } } ec: return l_return; } int http_hdr_get_headers(http_hdr_list *a_list, char ***a_names, int *a_num_names) { int i = 0; int l_num_names = 0; char **l_names; if (a_num_names == NULL) return -1; if (a_names == NULL) return -1; /* set our return values */ *a_names = NULL; *a_num_names = 0; /* make a pass to find out how many headers we have. */ for (i=0; i < HTTP_HDRS_MAX; i++) { if (a_list->header[i]) l_num_names++; } /* return if there are no headers */ if (l_num_names == 0) return 0; /* now that we know how many headers we have allocate the number of slots in the return */ l_names = malloc(sizeof(char *) * l_num_names); if (l_names == NULL) return -1; /* zero the list so that we can clean up later if we have to */ memset(l_names, 0, l_num_names); /* copy the headers */ for (i=0; i < HTTP_HDRS_MAX; i++) { if (a_list->header[i]) { l_names[i] = strdup(a_list->header[i]); if (l_names[i] == NULL) goto ec; } } *a_names = l_names; *a_num_names = l_num_names; return 0; /* something bad happened. Try to free up as much as possible. */ ec: if (l_names) { for (i=0; i < l_num_names; i++) { if (l_names[i]) { free(l_names[i]); l_names[i] = NULL; } } free(l_names); *a_names = 0; } *a_num_names = 0; return -1; } int http_hdr_clear_value(http_hdr_list *a_list, const char *a_name) { int i = 0; int l_return = 0; if ((a_list == NULL) || (a_name == NULL)) goto ec; for (i=0; i < HTTP_HDRS_MAX; i++) { if (a_name && a_list->header[i] && (strcasecmp(a_list->header[i], a_name) == 0)) { if (http_hdr_is_known(a_name) == NULL) free(a_list->header[i]); a_list->header[i] = NULL; free(a_list->value[i]); a_list->value[i] = NULL; } } ec: return l_return; }