1748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/* 2748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat This file is part of libmicrohttpd 3748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat Copyright (C) 2007, 2009, 2010 Daniel Pittman and Christian Grothoff 4748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 5748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat This library is free software; you can redistribute it and/or 6748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat modify it under the terms of the GNU Lesser General Public 7748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat License as published by the Free Software Foundation; either 8748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat version 2.1 of the License, or (at your option) any later version. 9748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 10748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat This library is distributed in the hope that it will be useful, 11748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat but WITHOUT ANY WARRANTY; without even the implied warranty of 12748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat Lesser General Public License for more details. 14748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 15748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat You should have received a copy of the GNU Lesser General Public 16748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat License along with this library; if not, write to the Free Software 17748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat*/ 19748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 20748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 21748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @file response.c 22748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @brief Methods for managing response objects 23748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @author Daniel Pittman 24748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @author Christian Grothoff 25748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 26748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 27748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include "internal.h" 28748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include "response.h" 29748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 30748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if defined(_WIN32) && defined(MHD_W32_MUTEX_) 31748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifndef WIN32_LEAN_AND_MEAN 32748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define WIN32_LEAN_AND_MEAN 1 33748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif /* !WIN32_LEAN_AND_MEAN */ 34748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <windows.h> 35748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif /* _WIN32 && MHD_W32_MUTEX_ */ 36748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if defined(_WIN32) 37748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <io.h> /* for lseek(), read() */ 38748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif /* _WIN32 */ 39748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 40748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 41748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 42748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Add a header or footer line to the response. 43748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 44748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param response response to add a header to 45748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param kind header or footer 46748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param header the header to add 47748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param content value to add 48748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return #MHD_NO on error (i.e. invalid header or content format). 49748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 50748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstatic int 51748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratadd_response_entry (struct MHD_Response *response, 52748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat enum MHD_ValueKind kind, 53748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat const char *header, 54748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat const char *content) 55748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 56748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat struct MHD_HTTP_Header *hdr; 57748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 58748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if ( (NULL == response) || 59748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (NULL == header) || 60748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (NULL == content) || 61748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (0 == strlen (header)) || 62748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (0 == strlen (content)) || 63748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (NULL != strchr (header, '\t')) || 64748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (NULL != strchr (header, '\r')) || 65748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (NULL != strchr (header, '\n')) || 66748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (NULL != strchr (content, '\t')) || 67748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (NULL != strchr (content, '\r')) || 68748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (NULL != strchr (content, '\n')) ) 69748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return MHD_NO; 70748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header)))) 71748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return MHD_NO; 72748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (NULL == (hdr->header = strdup (header))) 73748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 74748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (hdr); 75748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return MHD_NO; 76748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 77748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (NULL == (hdr->value = strdup (content))) 78748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 79748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (hdr->header); 80748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (hdr); 81748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return MHD_NO; 82748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 83748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat hdr->kind = kind; 84748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat hdr->next = response->first_header; 85748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->first_header = hdr; 86748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return MHD_YES; 87748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 88748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 89748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 90748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 91748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Add a header line to the response. 92748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 93748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param response response to add a header to 94748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param header the header to add 95748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param content value to add 96748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return #MHD_NO on error (i.e. invalid header or content format). 97748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @ingroup response 98748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 99748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratint 100748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_add_response_header (struct MHD_Response *response, 101748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat const char *header, const char *content) 102748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 103748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return add_response_entry (response, 104748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat MHD_HEADER_KIND, 105748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat header, 106748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat content); 107748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 108748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 109748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 110748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 111748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Add a footer line to the response. 112748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 113748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param response response to remove a header from 114748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param footer the footer to delete 115748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param content value to delete 116748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return #MHD_NO on error (i.e. invalid footer or content format). 117748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @ingroup response 118748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 119748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratint 120748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_add_response_footer (struct MHD_Response *response, 121748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat const char *footer, const char *content) 122748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 123748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return add_response_entry (response, 124748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat MHD_FOOTER_KIND, 125748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat footer, 126748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat content); 127748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 128748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 129748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 130748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 131748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Delete a header (or footer) line from the response. 132748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 133748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param response response to remove a header from 134748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param header the header to delete 135748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param content value to delete 136748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return #MHD_NO on error (no such header known) 137748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @ingroup response 138748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 139748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratint 140748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_del_response_header (struct MHD_Response *response, 141748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat const char *header, 142748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat const char *content) 143748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 144748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat struct MHD_HTTP_Header *pos; 145748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat struct MHD_HTTP_Header *prev; 146748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 147748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if ( (NULL == header) || (NULL == content) ) 148748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return MHD_NO; 149748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat prev = NULL; 150748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat pos = response->first_header; 151748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat while (pos != NULL) 152748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 153748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if ((0 == strcmp (header, pos->header)) && 154748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (0 == strcmp (content, pos->value))) 155748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 156748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (pos->header); 157748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (pos->value); 158748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (NULL == prev) 159748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->first_header = pos->next; 160748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat else 161748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat prev->next = pos->next; 162748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (pos); 163748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return MHD_YES; 164748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 165748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat prev = pos; 166748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat pos = pos->next; 167748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 168748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return MHD_NO; 169748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 170748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 171748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 172748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 173748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Get all of the headers (and footers) added to a response. 174748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 175748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param response response to query 176748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param iterator callback to call on each header; 177748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * maybe NULL (then just count headers) 178748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param iterator_cls extra argument to @a iterator 179748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return number of entries iterated over 180748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @ingroup response 181748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 182748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratint 183748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_get_response_headers (struct MHD_Response *response, 184748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat MHD_KeyValueIterator iterator, void *iterator_cls) 185748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 186748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat struct MHD_HTTP_Header *pos; 187748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat int numHeaders = 0; 188748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 189748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat for (pos = response->first_header; NULL != pos; pos = pos->next) 190748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 191748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat numHeaders++; 192748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if ((NULL != iterator) && 193748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (MHD_YES != iterator (iterator_cls, 194748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat pos->kind, pos->header, pos->value))) 195748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat break; 196748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 197748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return numHeaders; 198748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 199748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 200748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 201748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 202748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Get a particular header (or footer) from the response. 203748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 204748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param response response to query 205748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param key which header to get 206748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return NULL if header does not exist 207748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @ingroup response 208748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 209748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratconst char * 210748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_get_response_header (struct MHD_Response *response, 211748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat const char *key) 212748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 213748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat struct MHD_HTTP_Header *pos; 214748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 215748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (NULL == key) 216748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return NULL; 217748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat for (pos = response->first_header; NULL != pos; pos = pos->next) 218748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (0 == strcmp (key, pos->header)) 219748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return pos->value; 220748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return NULL; 221748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 222748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 223748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 224748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 225748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Create a response object. The response object can be extended with 226748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * header information and then be used any number of times. 227748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 228748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param size size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown 229748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param block_size preferred block size for querying crc (advisory only, 230748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * MHD may still call @a crc using smaller chunks); this 231748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * is essentially the buffer size used for IO, clients 232748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * should pick a value that is appropriate for IO and 233748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * memory performance requirements 234748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param crc callback to use to obtain response data 235748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param crc_cls extra argument to @a crc 236748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param crfc callback to call to free @a crc_cls resources 237748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return NULL on error (i.e. invalid arguments, out of memory) 238748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @ingroup response 239748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 240748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstruct MHD_Response * 241748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_create_response_from_callback (uint64_t size, 242748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat size_t block_size, 243748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat MHD_ContentReaderCallback crc, 244748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat void *crc_cls, 245748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat MHD_ContentReaderFreeCallback crfc) 246748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 247748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat struct MHD_Response *response; 248748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 249748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if ((NULL == crc) || (0 == block_size)) 250748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return NULL; 251748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (NULL == (response = malloc (sizeof (struct MHD_Response) + block_size))) 252748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return NULL; 253748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat memset (response, 0, sizeof (struct MHD_Response)); 254748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->fd = -1; 255748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->data = (void *) &response[1]; 256748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->data_buffer_size = block_size; 257748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (MHD_YES != MHD_mutex_create_ (&response->mutex)) 258748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 259748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (response); 260748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return NULL; 261748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 262748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->crc = crc; 263748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->crfc = crfc; 264748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->crc_cls = crc_cls; 265748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->reference_count = 1; 266748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->total_size = size; 267748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return response; 268748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 269748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 270748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 271748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 272748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Set special flags and options for a response. 273748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 274748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param response the response to modify 275748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param flags to set for the response 276748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param ... #MHD_RO_END terminated list of options 277748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return #MHD_YES on success, #MHD_NO on error 278748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 279748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratint 280748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_set_response_options (struct MHD_Response *response, 281748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat enum MHD_ResponseFlags flags, 282748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat ...) 283748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 284748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat va_list ap; 285748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat int ret; 286748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat enum MHD_ResponseOptions ro; 287748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 288748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat ret = MHD_YES; 289748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->flags = flags; 290748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat va_start (ap, flags); 291748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat while (MHD_RO_END != (ro = va_arg (ap, enum MHD_ResponseOptions))) 292748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 293748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat switch (ro) 294748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 295748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat default: 296748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat ret = MHD_NO; 297748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat break; 298748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 299748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 300748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat va_end (ap); 301748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return ret; 302748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 303748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 304748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 305748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 306748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Given a file descriptor, read data from the file 307748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * to generate the response. 308748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 309748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param cls pointer to the response 310748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param pos offset in the file to access 311748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param buf where to write the data 312748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param max number of bytes to write at most 313748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return number of bytes written 314748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 315748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstatic ssize_t 316748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratfile_reader (void *cls, uint64_t pos, char *buf, size_t max) 317748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 318748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat struct MHD_Response *response = cls; 319748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat ssize_t n; 320748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 321748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (void) lseek (response->fd, pos + response->fd_off, SEEK_SET); 322748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat n = read (response->fd, buf, max); 323748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (0 == n) 324748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return MHD_CONTENT_READER_END_OF_STREAM; 325748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (n < 0) 326748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return MHD_CONTENT_READER_END_WITH_ERROR; 327748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return n; 328748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 329748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 330748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 331748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 332748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Destroy file reader context. Closes the file 333748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * descriptor. 334748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 335748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param cls pointer to file descriptor 336748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 337748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstatic void 338748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratfree_callback (void *cls) 339748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 340748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat struct MHD_Response *response = cls; 341748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 342748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (void) close (response->fd); 343748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->fd = -1; 344748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 345748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 346748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 347748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 348748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Create a response object. The response object can be extended with 349748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * header information and then be used any number of times. 350748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 351748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param size size of the data portion of the response 352748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param fd file descriptor referring to a file on disk with the 353748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * data; will be closed when response is destroyed; 354748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * fd should be in 'blocking' mode 355748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param offset offset to start reading from in the file; 356748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Be careful! `off_t` may have been compiled to be a 357748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 64-bit variable for MHD, in which case your application 358748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * also has to be compiled using the same options! Read 359748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * the MHD manual for more details. 360748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return NULL on error (i.e. invalid arguments, out of memory) 361748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @ingroup response 362748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 363748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstruct MHD_Response * 364748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_create_response_from_fd_at_offset (size_t size, 365748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat int fd, 366748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat off_t offset) 367748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 368748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat struct MHD_Response *response; 369748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 370748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response = MHD_create_response_from_callback (size, 371748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 4 * 1024, 372748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat &file_reader, 373748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat NULL, 374748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat &free_callback); 375748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (NULL == response) 376748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return NULL; 377748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->fd = fd; 378748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->fd_off = offset; 379748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->crc_cls = response; 380748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return response; 381748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 382748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 383748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 384748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 385748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Create a response object. The response object can be extended with 386748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * header information and then be used any number of times. 387748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 388748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param size size of the data portion of the response 389748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param fd file descriptor referring to a file on disk with the data 390748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return NULL on error (i.e. invalid arguments, out of memory) 391748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @ingroup response 392748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 393748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstruct MHD_Response * 394748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_create_response_from_fd (size_t size, 395748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat int fd) 396748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 397748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return MHD_create_response_from_fd_at_offset (size, fd, 0); 398748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 399748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 400748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 401748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 402748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Create a response object. The response object can be extended with 403748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * header information and then be used any number of times. 404748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 405748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param size size of the @a data portion of the response 406748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param data the data itself 407748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param must_free libmicrohttpd should free data when done 408748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param must_copy libmicrohttpd must make a copy of @a data 409748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * right away, the data maybe released anytime after 410748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * this call returns 411748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return NULL on error (i.e. invalid arguments, out of memory) 412748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @deprecated use #MHD_create_response_from_buffer instead 413748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @ingroup response 414748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 415748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstruct MHD_Response * 416748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_create_response_from_data (size_t size, 417748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat void *data, int must_free, int must_copy) 418748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 419748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat struct MHD_Response *response; 420748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat void *tmp; 421748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 422748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if ((NULL == data) && (size > 0)) 423748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return NULL; 424748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (NULL == (response = malloc (sizeof (struct MHD_Response)))) 425748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return NULL; 426748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat memset (response, 0, sizeof (struct MHD_Response)); 427748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->fd = -1; 428748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (MHD_YES != MHD_mutex_create_ (&response->mutex)) 429748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 430748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (response); 431748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return NULL; 432748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 433748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if ((must_copy) && (size > 0)) 434748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 435748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (NULL == (tmp = malloc (size))) 436748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 437748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (void) MHD_mutex_destroy_ (&response->mutex); 438748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (response); 439748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return NULL; 440748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 441748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat memcpy (tmp, data, size); 442748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat must_free = MHD_YES; 443748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat data = tmp; 444748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 445748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->crc = NULL; 446748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->crfc = must_free ? &free : NULL; 447748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->crc_cls = must_free ? data : NULL; 448748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->reference_count = 1; 449748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->total_size = size; 450748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->data = data; 451748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->data_size = size; 452748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return response; 453748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 454748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 455748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 456748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 457748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Create a response object. The response object can be extended with 458748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * header information and then be used any number of times. 459748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 460748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param size size of the data portion of the response 461748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param buffer size bytes containing the response's data portion 462748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param mode flags for buffer management 463748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @return NULL on error (i.e. invalid arguments, out of memory) 464748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @ingroup response 465748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 466748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratstruct MHD_Response * 467748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_create_response_from_buffer (size_t size, 468748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat void *buffer, 469748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat enum MHD_ResponseMemoryMode mode) 470748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 471748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return MHD_create_response_from_data (size, 472748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat buffer, 473748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat mode == MHD_RESPMEM_MUST_FREE, 474748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat mode == MHD_RESPMEM_MUST_COPY); 475748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 476748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 477748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 478748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/** 479748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Destroy a response object and associated resources. Note that 480748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * libmicrohttpd may keep some of the resources around if the response 481748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * is still in the queue for some clients, so the memory may not 482748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * necessarily be freed immediatley. 483748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * 484748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @param response response to destroy 485748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @ingroup response 486748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */ 487748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratvoid 488748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_destroy_response (struct MHD_Response *response) 489748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 490748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat struct MHD_HTTP_Header *pos; 491748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 492748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (NULL == response) 493748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return; 494748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (void) MHD_mutex_lock_ (&response->mutex); 495748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (0 != --(response->reference_count)) 496748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 497748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (void) MHD_mutex_unlock_ (&response->mutex); 498748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat return; 499748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 500748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (void) MHD_mutex_unlock_ (&response->mutex); 501748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (void) MHD_mutex_destroy_ (&response->mutex); 502748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat if (response->crfc != NULL) 503748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->crfc (response->crc_cls); 504748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat while (NULL != response->first_header) 505748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat { 506748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat pos = response->first_header; 507748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat response->first_header = pos->next; 508748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (pos->header); 509748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (pos->value); 510748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (pos); 511748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat } 512748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat free (response); 513748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 514748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 515748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 516748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Eratvoid 517748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel EratMHD_increment_response_rc (struct MHD_Response *response) 518748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat{ 519748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (void) MHD_mutex_lock_ (&response->mutex); 520748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (response->reference_count)++; 521748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat (void) MHD_mutex_unlock_ (&response->mutex); 522748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat} 523748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 524748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat 525748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/* end of response.c */ 526