rsstats 0.0.1
Redis Enterprise Statistic collector
libhttp.c
Go to the documentation of this file.
1
19#include "libhttp.h"
20#include "sclist.h"
21#include "base64.h" /* Base64 encoder and decoder */
22
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#include <assert.h>
27
28typedef struct HTTP_s {
30 char* body;
32
33typedef struct HTTPHeader_s {
34 char* name;
35 char* value;
37
38HTTPHeader_t* HTTPHeader_new(const char* name, const char* value) {
39 HTTPHeader_t* header;
40
41 assert(name);
42 assert(value);
43
44 if (NULL==(header=malloc(sizeof(struct HTTPHeader_s)))) {
45 perror("HTTPHeader_new");
46 return NULL;
47 }
48 if (NULL==(header->name = strdup(name))) {
49 perror("HTTPHeader_new name");
50 free(header);
51 return NULL;
52 }
53 if (NULL==(header->value = strdup(value))) {
54 perror("HTTPHeader_new value");
55 free(header->name);
56 free(header);
57 return NULL;
58 }
59 return header;
60}
61
63 assert(header);
64 assert(header->name);
65 assert(header->value);
66
67 free(header->name);
68 free(header->value);
69 free(header);
70}
71
72HTTPHeader_t* HTTPHeader_basicauth(const char* login, const char* pass) {
73 char* auth_encoded;
74 char* auth;
75
76 assert(login);
77 assert(pass);
78
79 if (NULL==(auth=malloc(strlen("Basic ")+strlen(login)+1+strlen(pass)+1))) {
80 perror("HTTPHeader_basicauth");
81 return NULL;
82 }
83 /* strcpy/strcat expected to be faster than sprintf */
84 strcpy(auth,login);
85 strcat(auth,":");
86 strcat(auth,pass);
87 auth_encoded=base64_encode(auth);
88 free(auth);
89
90 if (NULL==(auth=malloc(strlen("Basic ")+strlen(auth_encoded)+1))) {
91 perror("HTTPHeader_basicauth");
92 free(auth_encoded);
93 return NULL;
94 }
95 strcpy(auth,"Basic ");
96 strcat(auth, auth_encoded);
97
98 return HTTPHeader_new("Authorization",auth);
99}
100
102 assert(header);
103 return header->name;
104}
105
107 assert(header);
108 return header->value;
109}
110
112 HTTP_t* retval;
113
114 if (NULL==(retval=malloc(sizeof(struct HTTP_s)))) {
115 perror("HTTP_new HTTP_s");
116 return NULL;
117 }
118
119 if (NULL==(retval->body=malloc(1))) {
120 perror("HTTP_new body");
121 free(retval);
122 return NULL;
123 };
124 retval->body[0]=0;
125
126 if (NULL==(retval->headers = sclist_new())) {
127 perror("HTTP_new headers");
128 free(retval->body);
129 free(retval);
130 return NULL;
131 }
132
133 return retval;
134}
135
136void HTTP_del(HTTP_t* http) {
137 sclistrecord_t* current;
138
139 assert(http);
140 assert(http->headers);
141 assert(http->body);
142
143 current = sclist_firstrecord(http->headers);
144 while (current) {
145 HTTPHeader_t* header=sclist_getvalue(current);
146 if (header->name)
147 free(header->name);
148 if (header->value)
149 free(header->value);
150 sclistrecord_t* tmp = current;
151 current = sclist_nextrecord(current);
152 sclist_remrecord(http->headers,tmp);
153 }
154
155 free(http->body);
156 free(http);
157}
158
159char* HTTP_setbody(HTTP_t* http, const char* body) {
160 char* newbody;
161
162 assert(http);
163 assert(body);
164 assert(http->body);
165
166 if (NULL==(newbody=realloc(http->body,strlen(body)+1))) {
167 perror("HTTP_setbody");
168 return NULL;
169 }
170
171 http->body = newbody;
172 strcpy(http->body, body);
173 return http->body;
174}
175
176char* HTTP_getbody(HTTP_t* http) {
177 assert(http);
178 assert(http->body);
179
180 return http->body;
181}
182
183
184
185
186
187
188
189
190void HTTP_addheader(HTTP_t* http, const char* name, const char* value) {
191 HTTPHeader_t* headers;
192
193 assert(http);
194 assert(http->headers);
195 assert(http->body);
196
197 if (NULL==(headers=malloc(sizeof(struct HTTPHeader_s)))) {
198 perror("HTTP_addheader");
199 exit(EXIT_FAILURE);
200 }
201 if (NULL==(headers->name=malloc(strlen(name)+1))) {
202 perror("HTTP_addheader name malloc");
203 exit(EXIT_FAILURE);
204 }
205 strcpy(headers->name,name);
206 if (NULL==(headers->value=malloc(strlen(value)+1))) {
207 perror("HTTP_addheader value malloc");
208 exit(EXIT_FAILURE);
209 }
210 strcpy(headers->value,value);
211 sclist_addrecord(http->headers,headers);
212}
213
214char* HTTP_getheaders(const HTTP_t* http) {
215 sclistrecord_t* current = NULL;
216 char* retval;
217
218 assert(http);
219 assert(http->headers);
220 assert(http->body);
221
222 if (NULL==(retval=malloc(1))) {
223 perror("HTTP_getheaders initial malloc");
224 exit(EXIT_FAILURE);
225 };
226 retval[0]=0;
227
228 current = sclist_firstrecord(http->headers);
229 while (current) {
230 HTTPHeader_t* header=sclist_getvalue(current);
231 if (header->name && header->value) {
232 char* newretval;
233 if (NULL==(newretval=realloc(retval,strlen(retval)+strlen(header->name)+2+strlen(header->value)+2+1))) {
234 perror("HTTP_getheaders inner loop");
235 exit(EXIT_FAILURE);
236 }
237 retval=newretval;
238 strcat(retval,header->name);
239 strcat(retval,": ");
240 strcat(retval,header->value);
241 strcat(retval,"\r\n");
242 }
243 current=sclist_nextrecord(current);
244 }
245 return retval;
246}
247
248char* HTTP_getrequest(const HTTPMethod_t method, const char* uri, const HTTPVersion_t version) {
249 char* retval;
250
251 assert(method<=HTTPMETHOD_INVALID);
252 assert(version<=HTTPVERSION_INVALID);
253
254 /* NULL URI allowed, as an empty string */
255 if (NULL==(retval=malloc(7+1+(uri?strlen(uri)+1:0)+8+1))) {
256 perror("HTTP_getrequest");
257 exit(EXIT_FAILURE);
258 }
259 retval[0]=0;
260
261 switch(method) {
262 case HTTPMETHOD_GET:
263 strcat(retval, "GET");
264 break;;
265 case HTTPMETHOD_HEAD:
266 case HTTPMETHOD_POST:
267 case HTTPMETHOD_PUT:
271 case HTTPMETHOD_TRACE:
272 case HTTPMETHOD_PATCH:
274 default:
275 fprintf(stderr,"HTTP method not supported\n");
276 exit(EXIT_FAILURE);
277 break;;
278 }
279
280 /* NULL URI allowed, as an empty string */
281 if (uri) {
282 strcat(retval," ");
283 strcat(retval, uri);
284 }
285
286 strcat(retval," HTTP/");
287 switch(version) {
290 strcat(retval, "1.1");
291 break;;
297 default:
298 fprintf(stderr,"HTTP version not supported\n");
299 exit(EXIT_FAILURE);
300 break;;
301 }
302 strcat(retval, "\r\n");
303 return retval;
304}
305
char * base64_encode(char *plain)
Encode a zero terminated C string in Base64.
Definition: base64.c:39
Simple Base64 encoding and decoding functions.
const char *const name
Definition: cJSON.h:268
char * HTTP_setbody(HTTP_t *http, const char *body)
Definition: libhttp.c:159
char * HTTPHeader_getvalue(HTTPHeader_t *header)
Definition: libhttp.c:106
void HTTPHeader_del(HTTPHeader_t *header)
Definition: libhttp.c:62
void HTTP_del(HTTP_t *http)
Definition: libhttp.c:136
void HTTP_addheader(HTTP_t *http, const char *name, const char *value)
Definition: libhttp.c:190
struct HTTP_s HTTP_t
HTTP_t * HTTP_new()
Definition: libhttp.c:111
char * HTTP_getheaders(const HTTP_t *http)
Definition: libhttp.c:214
HTTPHeader_t * HTTPHeader_basicauth(const char *login, const char *pass)
Definition: libhttp.c:72
struct HTTPHeader_s HTTPHeader_t
char * HTTP_getbody(HTTP_t *http)
Definition: libhttp.c:176
HTTPHeader_t * HTTPHeader_new(const char *name, const char *value)
Definition: libhttp.c:38
char * HTTPHeader_getname(HTTPHeader_t *header)
Definition: libhttp.c:101
char * HTTP_getrequest(const HTTPMethod_t method, const char *uri, const HTTPVersion_t version)
Definition: libhttp.c:248
HTTP parsing and building library.
enum HTTPVersion_e HTTPVersion_t
@ HTTPMETHOD_PUT
Definition: libhttp.h:75
@ HTTPMETHOD_POST
Definition: libhttp.h:74
@ HTTPMETHOD_CONNECT
Definition: libhttp.h:77
@ HTTPMETHOD_TRACE
Definition: libhttp.h:79
@ HTTPMETHOD_PATCH
Definition: libhttp.h:80
@ HTTPMETHOD_DELETE
Definition: libhttp.h:76
@ HTTPMETHOD_OPTIONS
Definition: libhttp.h:78
@ HTTPMETHOD_GET
Definition: libhttp.h:72
@ HTTPMETHOD_INVALID
Definition: libhttp.h:81
@ HTTPMETHOD_HEAD
Definition: libhttp.h:73
@ HTTPVERSION_HTTP11b
Definition: libhttp.h:65
@ HTTPVERSION_INVALID
Definition: libhttp.h:68
@ HTTPVERSION_HTTP09
Definition: libhttp.h:62
@ HTTPVERSION_HTTP2
Definition: libhttp.h:66
@ HTTPVERSION_HTTP10
Definition: libhttp.h:63
@ HTTPVERSION_HTTP3
Definition: libhttp.h:67
@ HTTPVERSION_HTTP11
Definition: libhttp.h:64
enum HTTPMethod_e HTTPMethod_t
#define NULL
Definition: rsstats-opts.c:64
void * sclist_getvalue(sclistrecord_t *record)
Returns the value pointer stored in the record.
Definition: sclist.c:127
sclist_t * sclist_new()
Allocate and initialize the internal list structure.
Definition: sclist.c:39
sclistrecord_t * sclist_nextrecord(const sclistrecord_t *record)
Returns the pointer on the record following the specified one.
Definition: sclist.c:121
sclistrecord_t * sclist_addrecord(sclist_t *sclist, void *value)
Add a value at the end of the list.
Definition: sclist.c:62
sclistrecord_t * sclist_firstrecord(const sclist_t *sclist)
Returns the pointer on the first list record.
Definition: sclist.c:115
void sclist_remrecord(sclist_t *sclist, sclistrecord_t *record)
Remove a record in a list.
Definition: sclist.c:90
Basic single chained generic list.
Definition: libhttp.c:28
char * body
Definition: libhttp.c:30
sclist_t * headers
Definition: libhttp.c:29
char * value
Definition: libhttp.c:35
char * name
Definition: libhttp.c:34
Opaque sclist structure.
Definition: sclist.c:34
Private list record structure.
Definition: sclist.c:27