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 } else {
47 header->name = strdup(name);
48 header->value = strdup(value);
49 }
50 return header;
51}
52
54 assert(header);
55 assert(header->name);
56 assert(header->value);
57
58 free(header->name);
59 free(header->value);
60 free(header);
61}
62
63HTTPHeader_t* HTTPHeader_basicauth(const char* login, const char* pass) {
64 assert(login);
65 assert(pass);
66
67 /* Prepare basic authentication */
68 char* auth_encoded;
69 char* auth;
70 {
71 if (NULL==(auth=malloc(strlen("Basic ")+strlen(login)+1+strlen(pass)+1))) {
72 perror("HTTPHeader_basicauth");
73 return NULL;
74 };
75 /* strcpy/strcat expected to be faster than sprintf */
76 strcpy(auth,login);
77 strcat(auth,":");
78 strcat(auth,pass);
79 auth_encoded=base64_encode(auth);
80 free(auth);
81 }
82
83 if (NULL==(auth=malloc(strlen("Basic ")+strlen(auth_encoded)+1))) {
84 perror("HTTPHeader_basicauth");
85 free(auth_encoded);
86 return NULL;
87 };
88 strcpy(auth,"Basic ");
89 strcat(auth, auth_encoded);
90 return HTTPHeader_new("Authorization",auth);
91}
92
94 assert(header);
95 return header->name;
96}
97
99 assert(header);
100 return header->value;
101}
102
104 HTTP_t* retval;
105
106 if (NULL==(retval=malloc(sizeof(struct HTTP_s)))) {
107 perror("HTTP_new HTTP_s");
108 return NULL;
109 }
110
111 if (NULL==(retval->body=malloc(1))) {
112 perror("HTTP_new body");
113 free(retval);
114 return NULL;
115 };
116 retval->body[0]=0;
117
118 if (NULL==(retval->headers = sclist_new())) {
119 perror("HTTP_new headers");
120 free(retval->body);
121 free(retval);
122 return NULL;
123 }
124
125 return retval;
126}
127
128
129
130
131
132
133
134
135typedef struct HTTPHeaders_s {
136 char* name;
137 char* value;
139
140void HTTP_del(HTTP_t* http) {
141 sclistrecord_t* current;
142
143 assert(http);
144 assert(http->headers);
145 assert(http->body);
146
147 /* Use sclist_remrecord() and sclist_del() */
148 current = sclist_firstrecord(http->headers);
149 while (current) {
150 HTTPHeaders_t* header=sclist_getvalue(current);
151 if (header->name)
152 free(header->name);
153 if (header->value)
154 free(header->value);
155 current = sclist_nextrecord(current);
156 }
157
158 free(http->body);
159 free(http);
160}
161
162
163void HTTP_addheader(HTTP_t* http, const char* name, const char* value) {
164 HTTPHeaders_t* headers;
165
166 assert(http);
167 assert(http->headers);
168 assert(http->body);
169
170 if (NULL==(headers=malloc(sizeof(struct HTTPHeaders_s)))) {
171 perror("HTTP_addheader");
172 exit(EXIT_FAILURE);
173 }
174 if (NULL==(headers->name=malloc(strlen(name)+1))) {
175 perror("HTTP_addheader name malloc");
176 exit(EXIT_FAILURE);
177 }
178 strcpy(headers->name,name);
179 if (NULL==(headers->value=malloc(strlen(value)+1))) {
180 perror("HTTP_addheader value malloc");
181 exit(EXIT_FAILURE);
182 }
183 strcpy(headers->value,value);
184 sclist_addrecord(http->headers,headers);
185}
186
187char* HTTP_getheaders(const HTTP_t* http) {
188 sclistrecord_t* current = NULL;
189 char* retval;
190
191 assert(http);
192 assert(http->headers);
193 assert(http->body);
194
195 if (NULL==(retval=malloc(1))) {
196 perror("HTTP_getheaders initial malloc");
197 exit(EXIT_FAILURE);
198 };
199 retval[0]=0;
200
201 current = sclist_firstrecord(http->headers);
202 while (current) {
203 HTTPHeaders_t* header=sclist_getvalue(current);
204 if (header->name && header->value) {
205 char* newretval;
206 if (NULL==(newretval=realloc(retval,strlen(retval)+strlen(header->name)+2+strlen(header->value)+2+1))) {
207 perror("HTTP_getheaders inner loop");
208 exit(EXIT_FAILURE);
209 }
210 retval=newretval;
211 strcat(retval,header->name);
212 strcat(retval,": ");
213 strcat(retval,header->value);
214 strcat(retval,"\r\n");
215 }
216 current=sclist_nextrecord(current);
217 }
218 return retval;
219}
220
221char* HTTP_getrequest(const HTTPMethod_t method, const char* uri, const HTTPVersion_t version) {
222 char* retval;
223
224 assert(method<=HTTPMETHOD_INVALID);
225 assert(version<=HTTPVERSION_INVALID);
226
227 if (NULL==(retval=malloc(7+1+strlen(uri)+1+8+1))) {
228 perror("HTTP_getrequest");
229 exit(EXIT_FAILURE);
230 }
231 retval[0]=0;
232
233 switch(method) {
234 case HTTPMETHOD_GET:
235 strcat(retval, "GET");
236 break;;
237 case HTTPMETHOD_HEAD:
238 case HTTPMETHOD_POST:
239 case HTTPMETHOD_PUT:
243 case HTTPMETHOD_TRACE:
244 case HTTPMETHOD_PATCH:
246 default:
247 fprintf(stderr,"HTTP method not supported\n");
248 exit(EXIT_FAILURE);
249 break;;
250 }
251 strcat(retval," ");
252
253 /* NULL URI allowed, as an empty string */
254 if (uri)
255 strcat(retval, uri);
256
257 strcat(retval," HTTP/");
258 switch(version) {
261 strcat(retval, "1.1");
262 break;;
268 default:
269 fprintf(stderr,"HTTP version not supported\n");
270 exit(EXIT_FAILURE);
271 break;;
272 }
273 strcat(retval, "\r\n");
274 return retval;
275}
276
277void HTTP_setbody(HTTP_t* http, const char* body) {
278 char* newbody;
279
280 assert(http);
281 assert(http->body);
282
283 if (NULL==(newbody=realloc(http->body,strlen(body)+1))) {
284 perror("HTTP_setbody");
285 exit(EXIT_FAILURE);
286 }
287
288 http->body = newbody;
289 strcpy(http->body, body);
290}
291
292char* HTTP_getbody(HTTP_t* http) {
293 assert(http);
294 assert(http->body);
295
296 return http->body;
297}
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 * HTTPHeader_getvalue(HTTPHeader_t *header)
Definition: libhttp.c:98
void HTTPHeader_del(HTTPHeader_t *header)
Definition: libhttp.c:53
void HTTP_del(HTTP_t *http)
Definition: libhttp.c:140
void HTTP_addheader(HTTP_t *http, const char *name, const char *value)
Definition: libhttp.c:163
struct HTTP_s HTTP_t
HTTP_t * HTTP_new()
Definition: libhttp.c:103
struct HTTPHeaders_s HTTPHeaders_t
char * HTTP_getheaders(const HTTP_t *http)
Definition: libhttp.c:187
HTTPHeader_t * HTTPHeader_basicauth(const char *login, const char *pass)
Definition: libhttp.c:63
struct HTTPHeader_s HTTPHeader_t
void HTTP_setbody(HTTP_t *http, const char *body)
Definition: libhttp.c:277
char * HTTP_getbody(HTTP_t *http)
Definition: libhttp.c:292
HTTPHeader_t * HTTPHeader_new(const char *name, const char *value)
Definition: libhttp.c:38
char * HTTPHeader_getname(HTTPHeader_t *header)
Definition: libhttp.c:93
char * HTTP_getrequest(const HTTPMethod_t method, const char *uri, const HTTPVersion_t version)
Definition: libhttp.c:221
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
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
char * value
Definition: libhttp.c:137
char * name
Definition: libhttp.c:136
Opaque sclist structure.
Definition: sclist.c:34
Private list record structure.
Definition: sclist.c:27