http_response.c
Go to the documentation of this file.
1 
9 #include "http_response.h"
10 #include "string_util.h"
11 #include "mcl_core/mcl_assert.h"
12 #include "mcl_core/mcl_memory.h"
13 #include <stdlib.h>
14 
15 static void _free_string(char **header);
16 
18  mcl_http_response_t **http_response)
19 {
20  mcl_error_t result = MCL_OK;
21 
22  MCL_DEBUG_ENTRY("mcl_list_t *header = <%p>, mcl_uint8_t *payload = <%p>, mcl_size_t payload_size = <%u>, E_MCL_HTTP_STATUS_CODE status_code = <%d>, "\
23  "mcl_http_response_t **http_response = <%p>", header, payload, payload_size, status_code, http_response);
24 
25  // Null check.
26  MCL_ASSERT_NOT_NULL(header, result);
27  MCL_ASSERT_NOT_NULL(http_response, result);
28 
29  // Create a new http response object.
30  MCL_NEW(*http_response);
31  MCL_ASSERT_CODE_MESSAGE(MCL_NULL != *http_response, MCL_OUT_OF_MEMORY, "Memory can not be allocated for http response object.");
32 
33  // Set members of the http_response object.
34  (*http_response)->header = header;
35  (*http_response)->payload = payload;
36  (*http_response)->payload_size = payload_size;
37  (*http_response)->status_code = status_code;
38 
40  MCL_DEBUG_LEAVE("retVal = <%d>", result);
41  return result;
42 }
43 
44 mcl_error_t mcl_http_response_get_header(mcl_http_response_t *http_response, const char *header_name, char **header_value)
45 {
46  mcl_error_t result = MCL_FAIL;
47 
48  MCL_DEBUG_ENTRY("mcl_http_response_t *http_response = <%p>, char *header_name = <%s>, char **header_value = <%p>",
49  http_response, header_name, header_value);
50 
51  // Null check.
52  MCL_ASSERT_NOT_NULL(http_response, result);
53  MCL_ASSERT_NOT_NULL(header_name, result);
54  MCL_ASSERT_NOT_NULL(header_value, result);
55 
56  // Reset the list in case it has been iterated over before.
57  mcl_list_reset(http_response->header);
58 
59  while (MCL_TRUE)
60  {
61  mcl_list_node_t *header_node = MCL_NULL;
62  mcl_size_t index = 0;
63  char *header;
64  mcl_bool_t found;
65  result = mcl_list_next(http_response->header, &header_node);
66  MCL_ASSERT_CODE_MESSAGE(MCL_OK == result, MCL_FAIL, "The header was not found.");
67 
68  // Null terminated header.
69  header = (char *) header_node->data;
70 
71  found = string_util_find_case_insensitive(header, header_name, &index);
72 
73  // If correct header is found then get the value.
74  if (MCL_TRUE == found)
75  {
76  mcl_size_t value_length;
77  mcl_size_t header_length = string_util_strlen(header);
78  string_util_find(header, ":", &index);
79 
80  // If there is a space after ":", index must show the next address.
81  if (' ' == header[index + 1])
82  {
83  ++index;
84  }
85 
86  *header_value = MCL_CALLOC(header_length - index, 1);
87  MCL_ASSERT_CODE_MESSAGE(MCL_NULL != *header_value, MCL_OUT_OF_MEMORY, "Could not allocate memory for *header_value.");
88 
89  value_length = header_length - index - 1;
90  string_util_strncpy(*header_value, header + index + 1, value_length);
91 
92  // Make sure there is null termination at the end.
93  (*header_value)[value_length] = '\0';
94  result = MCL_OK;
95 
96  break;
97  }
98  }
99 
101  MCL_DEBUG_LEAVE("retVal = <%d>", result);
102  return result;
103 }
104 
106 {
107  mcl_error_t code;
108 
109  MCL_DEBUG_ENTRY("mcl_http_response_t *http_response = <%p>", http_response);
110 
111  MCL_ASSERT_NOT_NULL(http_response, code);
112 
113  switch (http_response->status_code)
114  {
116  code = MCL_OK;
117  break;
118 
120  code = MCL_CREATED;
121  break;
122 
124  code = MCL_PARTIAL_CONTENT;
125  break;
126 
128  code = MCL_BAD_REQUEST;
129  break;
130 
132  code = MCL_UNAUTHORIZED;
133  break;
134 
136  code = MCL_FORBIDDEN;
137  break;
138 
140  code = MCL_NOT_FOUND;
141  break;
142 
144  code = MCL_CONFLICT;
145  break;
146 
148  code = MCL_PRECONDITION_FAIL;
149  break;
150 
153  break;
154 
156  code = MCL_TOO_MANY_REQUESTS;
157  break;
158 
160  code = MCL_SERVER_FAIL;
161  break;
162 
163  default:
165  MCL_INFO("Server responded with unexpected HTTP status code %d.", http_response->status_code);
166  break;
167  }
168 
170  MCL_DEBUG_LEAVE("retVal = <%d>", code);
171  return code;
172 }
173 
175 {
176  MCL_DEBUG_ENTRY("mcl_http_response_t **http_response = <%p>", http_response);
177 
178  if (MCL_NULL != *http_response)
179  {
180  // Destroy http_response together with its members.
182  MCL_FREE((*http_response)->payload);
183  MCL_FREE(*http_response);
184 
185  MCL_DEBUG("Http response is successfully destroyed.");
186  }
187  else
188  {
189  MCL_DEBUG("Http response is already NULL.");
190  }
191 
192  MCL_DEBUG_LEAVE("retVal = void");
193 }
194 
195 static void _free_string(char **header)
196 {
197  MCL_FREE(*header);
198 }
#define MCL_FUNCTION_LEAVE_LABEL
mcl_list_t * header
Header of http response.
size_t mcl_size_t
E_MCL_HTTP_STATUS_CODE status_code
Status code of http response.
Assert module header file.
Success.
#define MCL_DEBUG(...)
Definition: mcl_log_util.h:114
void mcl_http_response_destroy(mcl_http_response_t **http_response)
If the response of server is HTTP 409.
#define MCL_CALLOC(count, bytes)
Definition: mcl_memory.h:56
mcl_int32_t mcl_error_t
If the response of server is unexpected.
If the response of server is HTTP 412.
If the response of server is HTTP 429.
mcl_bool_t string_util_find(const char *source, const char *target, mcl_size_t *start_index)
Definition: string_util.c:308
mcl_error_t mcl_http_response_get_header(mcl_http_response_t *http_response, const char *header_name, char **header_value)
Definition: http_response.c:44
#define MCL_DEBUG_ENTRY(...)
Definition: mcl_log_util.h:115
void string_util_strncpy(char *destination, const char *source, mcl_size_t count)
Definition: string_util.c:83
void(* mcl_list_item_destroy_callback)(void **item)
Definition: mcl_list.h:61
mcl_bool_t string_util_find_case_insensitive(const char *source, const char *target, mcl_size_t *start_index)
Definition: string_util.c:357
If the response of server is HTTP 206.
String utility module header file.
static void _free_string(char **header)
MCL_CORE_EXPORT mcl_error_t mcl_list_next(mcl_list_t *list, mcl_list_node_t **node)
Definition: list.c:76
#define MCL_ASSERT_CODE_MESSAGE(condition, return_code,...)
Definition: mcl_assert.h:77
If the response of server is HTTP 401.
#define MCL_NEW(p)
Definition: mcl_memory.h:55
#define MCL_NULL
If the response of server is HTTP 413.
If the response of server is HTTP 201.
#define MCL_FREE(p)
Definition: mcl_memory.h:59
MCL_CORE_EXPORT void mcl_list_destroy_with_content(mcl_list_t **list, mcl_list_item_destroy_callback callback)
Definition: list.c:302
If the response of server is HTTP 400.
uint8_t mcl_uint8_t
#define MCL_ASSERT_NOT_NULL(argument, return_variable)
Definition: mcl_assert.h:38
Internal server error.
MCL_CORE_EXPORT void mcl_list_reset(mcl_list_t *list)
Definition: list.c:276
If the response of server is HTTP 403.
mcl_error_t mcl_http_response_get_status(mcl_http_response_t *http_response)
mcl_uint8_t mcl_bool_t
Memory allocation fail.
#define MCL_DEBUG_LEAVE(...)
Definition: mcl_log_util.h:116
#define MCL_TRUE
Internal failure in MCL.
void * data
Data of the node.
Definition: mcl_list.h:27
mcl_error_t mcl_http_response_initialize(mcl_list_t *header, mcl_uint8_t *payload, mcl_size_t payload_size, E_MCL_HTTP_STATUS_CODE status_code, mcl_http_response_t **http_response)
Definition: http_response.c:17
mcl_size_t string_util_strlen(const char *buffer)
Definition: string_util.c:35
HTTP response module header file.
#define MCL_INFO(...)
Definition: mcl_log_util.h:126
If the response of server is HTTP 404.
E_MCL_HTTP_STATUS_CODE
Memory module interface header file.