aboutsummaryrefslogtreecommitdiff
path: root/src/lib/request.c
blob: 0e280efa41913c1cc9876e1c097c8040f4c97146 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
     This file is part of libmicrohttpd
     Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
     version 2.1 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
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/
/**
 * @file requests.c
 * @brief  Methods for managing HTTP requests
 * @author Daniel Pittman
 * @author Christian Grothoff
 * @author Karlson2k (Evgeny Grin)
 */


/**
 * Get all of the headers from the request.
 *
 * @param request request to get values from
 * @param kind types of values to iterate over, can be a bitmask
 * @param iterator callback to call on each header;
 *        maybe NULL (then just count headers)
 * @param iterator_cls extra argument to @a iterator
 * @return number of entries iterated over
 * @ingroup request
 */
unsigned int
MHD_request_get_values (struct MHD_Request *request,
			enum MHD_ValueKind kind,
			MHD_KeyValueIterator iterator,
			void *iterator_cls)
{
  int ret;
  struct MHD_HTTP_Header *pos;

  if (NULL == request)
    return -1;
  ret = 0;
  for (pos = request->headers_received;
       NULL != pos;
       pos = pos->next)
    {
      if (0 != (pos->kind & kind))
	{
	  ret++;
	  if ( (NULL != iterator) &&
	       (MHD_YES != iterator (iterator_cls,
				     pos->kind,
				     pos->header,
				     pos->value)) )
	    return ret;
	}
    }
  return ret;
}


/**
 * This function can be used to add an entry to the HTTP headers of a
 * request (so that the #MHD_request_get_values function will
 * return them -- and the `struct MHD_PostProcessor` will also see
 * them).  This maybe required in certain situations (see Mantis
 * #1399) where (broken) HTTP implementations fail to supply values
 * needed by the post processor (or other parts of the application).
 *
 * This function MUST only be called from within the
 * request callbacks (otherwise, access maybe improperly
 * synchronized).  Furthermore, the client must guarantee that the key
 * and value arguments are 0-terminated strings that are NOT freed
 * until the connection is closed.  (The easiest way to do this is by
 * passing only arguments to permanently allocated strings.).
 *
 * @param request the request for which a
 *  value should be set
 * @param kind kind of the value
 * @param key key for the value
 * @param value the value itself
 * @return #MHD_NO if the operation could not be
 *         performed due to insufficient memory;
 *         #MHD_YES on success
 * @ingroup request
 */
enum MHD_Bool
MHD_request_set_value (struct MHD_Request *request,
		       enum MHD_ValueKind kind,
		       const char *key,
		       const char *value)
{
  struct MHD_HTTP_Header *pos;

  pos = MHD_pool_allocate (request->pool,
                           sizeof (struct MHD_HTTP_Header),
                           MHD_YES);
  if (NULL == pos)
    return MHD_NO;
  pos->header = (char *) key;
  pos->value = (char *) value;
  pos->kind = kind;
  pos->next = NULL;
  /* append 'pos' to the linked list of headers */
  if (NULL == request->headers_received_tail)
    {
      request->headers_received = pos;
      request->headers_received_tail = pos;
    }
  else
    {
      request->headers_received_tail->next = pos;
      request->headers_received_tail = pos;
    }
  return MHD_YES;
}


/**
 * Get a particular header value.  If multiple
 * values match the kind, return any one of them.
 *
 * @param request request to get values from
 * @param kind what kind of value are we looking for
 * @param key the header to look for, NULL to lookup 'trailing' value without a key
 * @return NULL if no such item was found
 * @ingroup request
 */
const char *
MHD_request_lookup_value (struct MHD_Request *request,
			  enum MHD_ValueKind kind,
			  const char *key)
{
  struct MHD_HTTP_Header *pos;

  if (NULL == request)
    return NULL;
  for (pos = request->headers_received;
       NULL != pos;
       pos = pos->next)
    {
      if ((0 != (pos->kind & kind)) &&
	  ( (key == pos->header) ||
	    ( (NULL != pos->header) &&
	      (NULL != key) &&
	      (MHD_str_equal_caseless_(key,
				       pos->header)))))
	return pos->value;
    }
  return NULL;
}


/* end of request.c */