response.c

Go to the documentation of this file.
00001 /*
00002      This file is part of libmicrohttpd
00003      (C) 2007, 2009, 2010 Daniel Pittman and Christian Grothoff
00004 
00005      This library is free software; you can redistribute it and/or
00006      modify it under the terms of the GNU Lesser General Public
00007      License as published by the Free Software Foundation; either
00008      version 2.1 of the License, or (at your option) any later version.
00009 
00010      This library is distributed in the hope that it will be useful,
00011      but WITHOUT ANY WARRANTY; without even the implied warranty of
00012      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013      Lesser General Public License for more details.
00014 
00015      You should have received a copy of the GNU Lesser General Public
00016      License along with this library; if not, write to the Free Software
00017      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
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->fd = -1;
00193   retVal->data = (void *) &retVal[1];
00194   retVal->data_buffer_size = block_size;
00195   if (pthread_mutex_init (&retVal->mutex, NULL) != 0)
00196     {
00197       free (retVal);
00198       return NULL;
00199     }
00200   retVal->crc = crc;
00201   retVal->crfc = crfc;
00202   retVal->crc_cls = crc_cls;
00203   retVal->reference_count = 1;
00204   retVal->total_size = size;
00205   return retVal;
00206 }
00207 
00208 
00219 static ssize_t
00220 file_reader (void *cls, uint64_t pos, char *buf, size_t max)
00221 {
00222   struct MHD_Response *response = cls;
00223   int ret;
00224 
00225   pthread_mutex_lock (&response->mutex);
00226   (void) lseek (response->fd, pos, SEEK_SET);
00227   ret = read (response->fd, buf, max);
00228   pthread_mutex_unlock (&response->mutex);
00229   return ret;
00230 }
00231 
00232 
00239 static void
00240 free_callback (void *cls)
00241 {
00242   struct MHD_Response *response = cls;
00243   (void) close (response->fd);
00244   response->fd = -1;
00245 }
00246 
00247 
00256 struct MHD_Response *MHD_create_response_from_fd (size_t size,
00257                                                   int fd)
00258 {
00259   struct MHD_Response *ret;
00260 
00261   ret = MHD_create_response_from_callback (size,
00262                                            4 * 1024,
00263                                            &file_reader,
00264                                            NULL,
00265                                            &free_callback);
00266   if (ret == NULL)
00267     return NULL;
00268   ret->fd = fd;
00269   ret->crc_cls = ret;
00270   return ret;
00271 }
00272 
00273 
00286 struct MHD_Response *
00287 MHD_create_response_from_data (size_t size,
00288                                void *data, int must_free, int must_copy)
00289 {
00290   struct MHD_Response *retVal;
00291   void *tmp;
00292 
00293   if ((data == NULL) && (size > 0))
00294     return NULL;
00295   retVal = malloc (sizeof (struct MHD_Response));
00296   if (retVal == NULL)
00297     return NULL;
00298   memset (retVal, 0, sizeof (struct MHD_Response));
00299   retVal->fd = -1;
00300   if (pthread_mutex_init (&retVal->mutex, NULL) != 0)
00301     {
00302       free (retVal);
00303       return NULL;
00304     }
00305   if ((must_copy) && (size > 0))
00306     {
00307       tmp = malloc (size);
00308       if (tmp == NULL)
00309         {
00310           pthread_mutex_destroy (&retVal->mutex);
00311           free (retVal);
00312           return NULL;
00313         }
00314       memcpy (tmp, data, size);
00315       must_free = 1;
00316       data = tmp;
00317     }
00318   retVal->crc = NULL;
00319   retVal->crfc = must_free ? &free : NULL;
00320   retVal->crc_cls = must_free ? data : NULL;
00321   retVal->reference_count = 1;
00322   retVal->total_size = size;
00323   retVal->data = data;
00324   retVal->data_size = size;
00325   return retVal;
00326 }
00327 
00334 void
00335 MHD_destroy_response (struct MHD_Response *response)
00336 {
00337   struct MHD_HTTP_Header *pos;
00338 
00339   if (response == NULL)
00340     return;
00341   pthread_mutex_lock (&response->mutex);
00342   if (0 != --(response->reference_count))
00343     {
00344       pthread_mutex_unlock (&response->mutex);
00345       return;
00346     }
00347   pthread_mutex_unlock (&response->mutex);
00348   pthread_mutex_destroy (&response->mutex);
00349   if (response->crfc != NULL)
00350     response->crfc (response->crc_cls);
00351   while (response->first_header != NULL)
00352     {
00353       pos = response->first_header;
00354       response->first_header = pos->next;
00355       free (pos->header);
00356       free (pos->value);
00357       free (pos);
00358     }
00359   free (response);
00360 }
00361 
00362 
00363 void
00364 MHD_increment_response_rc (struct MHD_Response *response)
00365 {
00366   pthread_mutex_lock (&response->mutex);
00367   (response->reference_count)++;
00368   pthread_mutex_unlock (&response->mutex);
00369 }
00370 
00371 
00372 /* end of response.c */

Generated on 16 Nov 2010 for GNU libmicrohttpd by  doxygen 1.6.1