response.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00027 #include "internal.h"
00028 #include "response.h"
00029
00035 int
00036 MHD_add_response_header (struct MHD_Response *response,
00037 const char *header, const char *content)
00038 {
00039 struct MHD_HTTP_Header *hdr;
00040
00041 if ((response == NULL) ||
00042 (header == NULL) ||
00043 (content == NULL) ||
00044 (strlen (header) == 0) ||
00045 (strlen (content) == 0) ||
00046 (NULL != strstr (header, "\t")) ||
00047 (NULL != strstr (header, "\r")) ||
00048 (NULL != strstr (header, "\n")) ||
00049 (NULL != strstr (content, "\t")) ||
00050 (NULL != strstr (content, "\r")) || (NULL != strstr (content, "\n")))
00051 return MHD_NO;
00052 hdr = malloc (sizeof (struct MHD_HTTP_Header));
00053 if (hdr == NULL)
00054 return MHD_NO;
00055 hdr->header = strdup (header);
00056 if (hdr->header == NULL)
00057 {
00058 free (hdr);
00059 return MHD_NO;
00060 }
00061 hdr->value = strdup (content);
00062 if (hdr->value == NULL)
00063 {
00064 free (hdr->header);
00065 free (hdr);
00066 return MHD_NO;
00067 }
00068 hdr->kind = MHD_HEADER_KIND;
00069 hdr->next = response->first_header;
00070 response->first_header = hdr;
00071 return MHD_YES;
00072 }
00073
00079 int
00080 MHD_del_response_header (struct MHD_Response *response,
00081 const char *header, const char *content)
00082 {
00083 struct MHD_HTTP_Header *pos;
00084 struct MHD_HTTP_Header *prev;
00085
00086 if ((header == NULL) || (content == NULL))
00087 return MHD_NO;
00088 prev = NULL;
00089 pos = response->first_header;
00090 while (pos != NULL)
00091 {
00092 if ((0 == strcmp (header, pos->header)) &&
00093 (0 == strcmp (content, pos->value)))
00094 {
00095 free (pos->header);
00096 free (pos->value);
00097 if (prev == NULL)
00098 response->first_header = pos->next;
00099 else
00100 prev->next = pos->next;
00101 free (pos);
00102 return MHD_YES;
00103 }
00104 prev = pos;
00105 pos = pos->next;
00106 }
00107 return MHD_NO;
00108 }
00109
00118 int
00119 MHD_get_response_headers (struct MHD_Response *response,
00120 MHD_KeyValueIterator iterator, void *iterator_cls)
00121 {
00122 struct MHD_HTTP_Header *pos;
00123 int numHeaders = 0;
00124 pos = response->first_header;
00125 while (pos != NULL)
00126 {
00127 numHeaders++;
00128 if ((iterator != NULL) &&
00129 (MHD_YES != iterator (iterator_cls,
00130 pos->kind, pos->header, pos->value)))
00131 break;
00132 pos = pos->next;
00133 }
00134 return numHeaders;
00135 }
00136
00137
00144 const char *
00145 MHD_get_response_header (struct MHD_Response *response, const char *key)
00146 {
00147 struct MHD_HTTP_Header *pos;
00148
00149 if (key == NULL)
00150 return NULL;
00151 pos = response->first_header;
00152 while (pos != NULL)
00153 {
00154 if (0 == strcmp (key, pos->header))
00155 return pos->value;
00156 pos = pos->next;
00157 }
00158 return NULL;
00159 }
00160
00161
00177 struct MHD_Response *
00178 MHD_create_response_from_callback (uint64_t size,
00179 size_t block_size,
00180 MHD_ContentReaderCallback crc,
00181 void *crc_cls,
00182 MHD_ContentReaderFreeCallback crfc)
00183 {
00184 struct MHD_Response *retVal;
00185
00186 if ((crc == NULL) || (block_size == 0))
00187 return NULL;
00188 retVal = malloc (sizeof (struct MHD_Response) + block_size);
00189 if (retVal == NULL)
00190 return NULL;
00191 memset (retVal, 0, sizeof (struct MHD_Response));
00192 retVal->data = (void *) &retVal[1];
00193 retVal->data_buffer_size = block_size;
00194 if (pthread_mutex_init (&retVal->mutex, NULL) != 0)
00195 {
00196 free (retVal);
00197 return NULL;
00198 }
00199 retVal->crc = crc;
00200 retVal->crfc = crfc;
00201 retVal->crc_cls = crc_cls;
00202 retVal->reference_count = 1;
00203 retVal->total_size = size;
00204 return retVal;
00205 }
00206
00219 struct MHD_Response *
00220 MHD_create_response_from_data (size_t size,
00221 void *data, int must_free, int must_copy)
00222 {
00223 struct MHD_Response *retVal;
00224 void *tmp;
00225
00226 if ((data == NULL) && (size > 0))
00227 return NULL;
00228 retVal = malloc (sizeof (struct MHD_Response));
00229 if (retVal == NULL)
00230 return NULL;
00231 memset (retVal, 0, sizeof (struct MHD_Response));
00232 if (pthread_mutex_init (&retVal->mutex, NULL) != 0)
00233 {
00234 free (retVal);
00235 return NULL;
00236 }
00237 if ((must_copy) && (size > 0))
00238 {
00239 tmp = malloc (size);
00240 if (tmp == NULL)
00241 {
00242 free (retVal);
00243 return NULL;
00244 }
00245 memcpy (tmp, data, size);
00246 must_free = 1;
00247 data = tmp;
00248 }
00249 retVal->crc = NULL;
00250 retVal->crfc = must_free ? &free : NULL;
00251 retVal->crc_cls = must_free ? data : NULL;
00252 retVal->reference_count = 1;
00253 retVal->total_size = size;
00254 retVal->data = data;
00255 retVal->data_size = size;
00256 return retVal;
00257 }
00258
00265 void
00266 MHD_destroy_response (struct MHD_Response *response)
00267 {
00268 struct MHD_HTTP_Header *pos;
00269
00270 if (response == NULL)
00271 return;
00272 pthread_mutex_lock (&response->mutex);
00273 if (0 != --response->reference_count)
00274 {
00275 pthread_mutex_unlock (&response->mutex);
00276 return;
00277 }
00278 pthread_mutex_unlock (&response->mutex);
00279 pthread_mutex_destroy (&response->mutex);
00280 if (response->crfc != NULL)
00281 response->crfc (response->crc_cls);
00282 while (response->first_header != NULL)
00283 {
00284 pos = response->first_header;
00285 response->first_header = pos->next;
00286 free (pos->header);
00287 free (pos->value);
00288 free (pos);
00289 }
00290 free (response);
00291 }
00292
00293
00294 void
00295 MHD_increment_response_rc (struct MHD_Response *response)
00296 {
00297 pthread_mutex_lock (&response->mutex);
00298 response->reference_count++;
00299 pthread_mutex_unlock (&response->mutex);
00300 }
00301
00302
00303