GNU libmicrohttpd  0.9.72
response.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 
27 #include "internal.h"
28 
29 
39 static bool
40 add_response_entry (struct MHD_Response *response,
41  enum MHD_ValueKind kind,
42  const char *header,
43  const char *content)
44 {
45  struct MHD_HTTP_Header *hdr;
46 
47  if ( (NULL == header) ||
48  (NULL == content) ||
49  (0 == header[0]) ||
50  (0 == content[0]) ||
51  (NULL != strchr (header, '\t')) ||
52  (NULL != strchr (header, '\r')) ||
53  (NULL != strchr (header, '\n')) ||
54  (NULL != strchr (content, '\t')) ||
55  (NULL != strchr (content, '\r')) ||
56  (NULL != strchr (content, '\n')) )
57  return false;
58  if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header))))
59  return false;
60  if (NULL == (hdr->header = strdup (header)))
61  {
62  free (hdr);
63  return false;
64  }
65  if (NULL == (hdr->value = strdup (content)))
66  {
67  free (hdr->header);
68  free (hdr);
69  return false;
70  }
71  hdr->kind = kind;
72  hdr->next = response->first_header;
73  response->first_header = hdr;
74  return true;
75 }
76 
77 
87 void
89 {
90  struct MHD_HTTP_Header *pos;
91 
92  MHD_mutex_lock_chk_ (&response->mutex);
93  if (0 != --(response->reference_count))
94  {
95  MHD_mutex_unlock_chk_ (&response->mutex);
96  return;
97  }
98  MHD_mutex_unlock_chk_ (&response->mutex);
99  MHD_mutex_destroy_chk_ (&response->mutex);
100  if (NULL != response->crfc)
101  response->crfc (response->crc_cls);
102  while (NULL != response->first_header)
103  {
104  pos = response->first_header;
105  response->first_header = pos->next;
106  free (pos->header);
107  free (pos->value);
108  free (pos);
109  }
110  free (response);
111 }
112 
113 
124 enum MHD_Bool
125 MHD_response_add_header (struct MHD_Response *response,
126  const char *header,
127  const char *content)
128 {
129  return add_response_entry (response,
131  header,
132  content) ? MHD_YES : MHD_NO;
133 }
134 
135 
146 enum MHD_Bool
147 MHD_response_add_trailer (struct MHD_Response *response,
148  const char *footer,
149  const char *content)
150 {
151  return add_response_entry (response,
153  footer,
154  content) ? MHD_YES : MHD_NO;
155 }
156 
157 
167 enum MHD_Bool
168 MHD_response_del_header (struct MHD_Response *response,
169  const char *header,
170  const char *content)
171 {
172  struct MHD_HTTP_Header *pos;
173  struct MHD_HTTP_Header *prev;
174 
175  prev = NULL;
176  pos = response->first_header;
177  while (NULL != pos)
178  {
179  if ((0 == strcmp (header,
180  pos->header)) &&
181  (0 == strcmp (content,
182  pos->value)))
183  {
184  free (pos->header);
185  free (pos->value);
186  if (NULL == prev)
187  response->first_header = pos->next;
188  else
189  prev->next = pos->next;
190  free (pos);
191  return MHD_YES;
192  }
193  prev = pos;
194  pos = pos->next;
195  }
196  return MHD_NO;
197 }
198 
199 
210 unsigned int
212  MHD_KeyValueIterator iterator,
213  void *iterator_cls)
214 {
215  unsigned int numHeaders = 0;
216  struct MHD_HTTP_Header *pos;
217 
218  for (pos = response->first_header;
219  NULL != pos;
220  pos = pos->next)
221  {
222  numHeaders++;
223  if ( (NULL != iterator) &&
224  (MHD_YES != iterator (iterator_cls,
225  pos->kind,
226  pos->header,
227  pos->value)) )
228  break;
229  }
230  return numHeaders;
231 }
232 
233 
242 const char *
244  const char *key)
245 {
246  struct MHD_HTTP_Header *pos;
247 
248  for (pos = response->first_header;
249  NULL != pos;
250  pos = pos->next)
251  {
253  key))
254  return pos->value;
255  }
256  return NULL;
257 }
258 
259 
260 /* end of response.c */
enum MHD_Result(* MHD_KeyValueIterator)(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
Definition: microhttpd.h:2261
const char * MHD_response_get_header(struct MHD_Response *response, const char *key)
Definition: response.c:243
enum MHD_Bool MHD_response_add_trailer(struct MHD_Response *response, const char *footer, const char *content)
Definition: response.c:147
void MHD_response_queue_for_destroy(struct MHD_Response *response)
Definition: response.c:88
unsigned int MHD_response_get_headers(struct MHD_Response *response, MHD_KeyValueIterator iterator, void *iterator_cls)
Definition: response.c:211
enum MHD_Bool MHD_response_add_header(struct MHD_Response *response, const char *header, const char *content)
Definition: response.c:125
enum MHD_Bool MHD_response_del_header(struct MHD_Response *response, const char *header, const char *content)
Definition: response.c:168
#define MHD_mutex_unlock_chk_(pmutex)
Definition: mhd_locks.h:180
#define MHD_mutex_destroy_chk_(pmutex)
Definition: mhd_locks.h:121
#define MHD_mutex_lock_chk_(pmutex)
Definition: mhd_locks.h:154
int MHD_str_equal_caseless_(const char *str1, const char *str2)
Definition: mhd_str.c:346
#define NULL
Definition: reason_phrase.c:30
static bool add_response_entry(struct MHD_Response *response, enum MHD_ValueKind kind, const char *header, const char *content)
Definition: response.c:40
internal shared structures
@ MHD_YES
Definition: microhttpd.h:151
@ MHD_NO
Definition: microhttpd.h:146
MHD_ValueKind
Definition: microhttpd.h:1781
@ MHD_FOOTER_KIND
Definition: microhttpd.h:1822
@ MHD_HEADER_KIND
Definition: microhttpd.h:1796
char * header
Definition: internal.h:347
enum MHD_ValueKind kind
Definition: internal.h:358
struct MHD_HTTP_Header * next
Definition: internal.h:342
char * value
Definition: internal.h:352
MHD_ContentReaderFreeCallback crfc
Definition: internal.h:1606
struct MHD_HTTP_Header * first_header
Definition: internal.h:1582
void * crc_cls
Definition: internal.h:1594
unsigned int reference_count
Definition: internal.h:1675
MHD_mutex_ mutex
Definition: internal.h:1637