Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_command_local_request.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Framework
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
9 
10 #include "afw.h"
12 
13 /* Declares and rti/inf defines for interface afw_request */
14 #define AFW_IMPLEMENTATION_ID "afw_command_local"
17 
32 /*
33  * Implementation of method release for interface afw_request.
34  */
35 void
36 impl_afw_request_release(
37  const afw_request_t * instance,
38  afw_xctx_t *xctx)
39 {
40  /* Resource will be release when execution context (xctx) is released. */
41 }
42 
43 
44 
45 /*
46  * Implementation of method set_error_info for interface afw_request.
47  */
48 void
49 impl_afw_request_set_error_info(
50  const afw_request_t * instance,
51  const afw_object_t * error_info,
52  afw_xctx_t *xctx)
53 {
56 
57  self->pub.error_info = error_info;
58 }
59 
60 
61 
62 /*
63  * Implementation of method read_raw_request_body for interface afw_request.
64  */
65 void
66 impl_afw_request_read_raw_request_body(
67  const afw_request_t * instance,
68  afw_size_t buffer_size,
69  void * buffer,
70  afw_size_t * size,
71  afw_boolean_t * more_to_read,
72  afw_xctx_t *xctx)
73 {
76 
77  /* Make sure in correct state then set it. */
78  if (self->state > afw_request_state_content_read) {
79  AFW_THROW_ERROR_Z(general,
80  "read_request_body() called out of order", xctx);
81  }
82  self->state = afw_request_state_content_read;
83 
84  *size = buffer_size;
85  if (*size > self->remaining_body) {
86  *size = self->remaining_body;
87  }
88 
89  if (*size > 0) {
90  memcpy(buffer,
91  self->body->ptr + self->body->size - self->remaining_body,
92  *size);
93  self->remaining_body -= *size;
94  }
95 
96  *more_to_read = self->remaining_body > 0;
97 }
98 
99 
100 
101 /*
102  * Implementation of method set_response_status_code for interface afw_request.
103  */
104 void
105 impl_afw_request_set_response_status_code(
106  const afw_request_t * instance,
107  const afw_utf8_t * code,
108  const afw_utf8_t * reason,
109  afw_xctx_t *xctx)
110 {
113 
114  /* Ignore status if already past state. */
115  if (self->state >= afw_request_state_status_set) {
116  return;
117  }
118  self->state = afw_request_state_status_set;
119 
120  /* Save reason and code */
121  self->status_code = code;
122  self->status_reason = reason;
123 }
124 
125 
126 
127 /*
128  * Implementation of method write_response_header for interface afw_request.
129  */
130 void
131 impl_afw_request_write_response_header(
132  const afw_request_t * instance,
133  const afw_utf8_t * name,
134  const afw_utf8_t * value,
135  afw_xctx_t *xctx)
136 {
139 
140  /* Make sure in correct state then set it. */
141  if (self->state > afw_request_state_header_written) {
142  AFW_THROW_ERROR_Z(general,
143  "write_response_header() called out of order", xctx);
144  }
145  self->state = afw_request_state_header_written;
146 
147  /* Push name and value on response_headers array. */
148  if (!self->response_headers) {
149  self->response_headers = apr_array_make(
150  afw_pool_get_apr_pool(xctx->p), 5, sizeof(afw_utf8_t *));
151  }
152  APR_ARRAY_PUSH(self->response_headers, const afw_utf8_t *) = name;
153  APR_ARRAY_PUSH(self->response_headers, const afw_utf8_t *) = value;
154 }
155 
156 
157 
158 /*
159  * Implementation of method write_raw_response_body for interface afw_request.
160  */
161 void
162 impl_afw_request_write_raw_response_body(
163  const afw_request_t * instance,
164  afw_size_t size,
165  const void * buffer,
166  afw_xctx_t *xctx)
167 {
170 
171  /* Make sure in correct state. */
172  if (self->state > afw_request_state_response_written) {
173  AFW_THROW_ERROR_Z(general,
174  "write_response_body() called out of order", xctx);
175  }
176  self->state = afw_request_state_response_written;
177 
178  /* Write response body. */
179  afw_command_local_server_write_result(
180  self->server_self,
181  "%" AFW_UTF8_FMT,
182  (int)size, (const char *)buffer);
183 }
184 
185 
186 
187 /*
188  * Implementation of method flush_response for interface afw_request.
189  */
190 void
191 impl_afw_request_flush_response(
192  const afw_request_t * instance,
193  afw_xctx_t *xctx)
194 {
195  /* Nothing needs to be done since every write is flushed. */
196 }
197 
198 
199 
200 /*
201  * Implementation of method finish_response for interface afw_request.
202  */
203 void
204 impl_afw_request_finish_response(
205  const afw_request_t * instance,
206  afw_xctx_t *xctx)
207 {
210 
211  /* Make sure in correct state then set it. */
212  if (self->state >= afw_request_state_response_finished) {
213  AFW_THROW_ERROR_Z(general,
214  "finish_response() called out of order", xctx);
215  }
216  self->state = afw_request_state_response_finished;
217 
218  /* Write end. */
219  afw_command_local_server_write_end(self->server_self);
220 }
221 
222 
223 
224 static afw_size_t
225 impl_read_content_cb(
226  void *context,
227  const void * buffer,
228  afw_size_t size,
229  afw_boolean_t *more_to_read,
230  const afw_pool_t *p,
231  afw_xctx_t *xctx)
232 {
233  afw_size_t size_read;
234 
235  impl_afw_request_read_raw_request_body(
236  (const afw_request_t *)context,
237  size, (void *)buffer, &size_read, more_to_read, xctx);
238 
239  return size_read;
240 }
241 
242 
243 
244 static afw_size_t
245 impl_write_content_cb(
246  void *context,
247  const void * buffer,
248  afw_size_t size,
249  const afw_pool_t *p,
250  afw_xctx_t *xctx)
251 {
252  impl_afw_request_write_raw_response_body(
253  (const afw_request_t *)context, size, buffer, xctx);
254 
255  return size;
256 }
257 
258 
259 
261 afw_command_local_request_create(
262  afw_command_local_server_self_t *server_self,
263  const afw_memory_t *body,
264  const afw_object_t *properties,
265  afw_xctx_t *xctx)
266 {
268  const afw_pool_t *p = xctx->p;
269 
270  const afw_utf8_t *s;
271  const afw_value_t *value;
272 
273  /* Allocate memory for self. */
275 
276  /* Initialize Self. */
277  self->pub.inf = &impl_afw_request_inf;
278  self->pub.xctx = xctx;
279  self->server_self = server_self;
280  self->pub.read_content_cb = impl_read_content_cb;
281  self->pub.write_content_cb = impl_write_content_cb;
282  self->pub.properties = properties;
283 
284  /* Payload. */
285  self->pub.content_length = body->size;
286  self->body = body;
287  self->remaining_body = body->size;
288 
289  /* Method */
290  self->pub.method = afw_object_old_get_property_as_string(
291  properties, &afw_s_REQUEST_METHOD, xctx);
292  if (!self->pub.method) {
293  self->pub.method = &afw_s_POST;
295  properties, &afw_s_REQUEST_METHOD, self->pub.method, xctx);
296  }
297 
298  /* Request URI. */
300  properties, &afw_s_REQUEST_URI, xctx);
301  if (!self->pub.uri) {
302  self->pub.uri = &afw_s_a_slash_afw;
304  properties, &afw_s_REQUEST_URI, self->pub.uri, xctx);
305  }
306 
307  /* Content type. */
308  self->pub.content_type = afw_object_old_get_property_as_string(
309  properties, &afw_s_CONTENT_TYPE, xctx);
310  if (!self->pub.content_type) {
311  self->pub.content_type = afw_object_old_get_property_as_string(
312  properties, &afw_s_CONTENT_TYPE, xctx);
313  if (!self->pub.content_type) {
314  self->pub.content_type = &afw_s_a_application_json;
315  }
317  properties, &afw_s_CONTENT_TYPE, self->pub.content_type, xctx);
318  }
319 
320  /* Query string */
321  self->pub.query_string = afw_object_old_get_property_as_string(
322  properties, &afw_s_QUERY_STRING, xctx);
323 
324  /* Overwrite CONTENT_LENGTH */
325  value = afw_value_create_integer(
326  (afw_integer_t)self->pub.content_length, p, xctx);
327  s = afw_value_as_utf8(value, p, xctx);
329  properties, &afw_s_CONTENT_LENGTH, s, xctx);
330 
331  /* accept */
332  s = afw_object_old_get_property_as_string(properties, &afw_s_ACCEPT, xctx);
333  if (!s) {
335  properties, &afw_s_HTTP_ACCEPT, xctx);
336  if (!s) {
337  s = &afw_s_a_application_json;
338  }
340  properties, &afw_s_ACCEPT, s, xctx);
341  }
342  self->pub.accept = afw_utf8_parse_csv(s, p, xctx);
343 
344  return (const afw_request_t *)self;
345 }
346 
Adaptive Framework Core API.
#define AFW_COMMAND_DECLARE_INTERNAL(type)
Declare an internal function for /src/afw_command/ source*.h files.
Implementation for interface afw_command_local.
Interface afw_interface implementation declares.
afw_value_create_integer(afw_integer_t internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type integer value.
#define afw_object_old_get_property_as_string(object, property_name, xctx)
Get property function for data type string value.
afw_object_set_property_as_string(const afw_object_t *object, const afw_utf8_t *property_name, const afw_utf8_t *internal, afw_xctx_t *xctx)
Set property function for data type string values.
_Bool afw_boolean_t
Definition: afw_common.h:373
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
Definition: afw_common.h:588
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
apr_int64_t afw_integer_t
typedef for big signed int.
Definition: afw_common.h:321
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:283
#define afw_pool_get_apr_pool(instance)
Call method get_apr_pool of interface afw_pool.
afw_utf8_parse_csv(const afw_utf8_t *s, const afw_pool_t *p, afw_xctx_t *xctx)
Check to see if a string equals a utf8_z string.
Definition: afw_utf8.c:1149
afw_value_as_utf8(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Definition: afw_value.c:456
#define afw_xctx_calloc_type(type, xctx)
Macro to allocate cleared memory to hold type in xctx's pool.
Definition: afw_xctx.h:199
Self typedef for afw_command_local implementation of afw_request.
Self typedef for afw_command_local implementation of afw_server.
Struct for memory pointer and size.
Definition: afw_common.h:505
Interface afw_object public struct.
Interface afw_pool public struct.
Interface afw_request public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
Interface afw_value public struct.
Interface afw_xctx public struct.