-
Notifications
You must be signed in to change notification settings - Fork 21
/
sagui.h
2399 lines (2163 loc) · 84.2 KB
/
sagui.h
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* _
* ___ __ _ __ _ _ _(_)
* / __|/ _` |/ _` | | | | |
* \__ \ (_| | (_| | |_| | |
* |___/\__,_|\__, |\__,_|_|
* |___/
*
* Cross-platform library which helps to develop web servers or frameworks.
*
* Copyright (C) 2016-2024 Silvio Clecio <[email protected]>
*
* Sagui 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.
*
* Sagui 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 Sagui library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* \mainpage
* \li \ref sg_api
*/
/** \defgroup sg_api API reference
* The API reference grouped by feature.
**/
#ifndef SAGUI_H
#define SAGUI_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#ifndef SG_EXTERN
#ifdef _WIN32
#ifdef BUILDING_LIBSAGUI
#define SG_EXTERN __declspec(dllexport) extern
#else /* _WIN32 */
#define SG_EXTERN __declspec(dllimport) extern
#endif /* _WIN32 */
#else /* BUILDING_LIBSAGUI */
#define SG_EXTERN extern
#endif /* BUILDING_LIBSAGUI */
#endif /* SG_EXTERN */
#ifndef __SG_UNUSED
#define __SG_UNUSED __attribute__((unused))
#endif /* __SG_UNUSED */
#ifndef __SG_MALLOC
#define __SG_MALLOC __attribute__((malloc))
#endif /* __SG_MALLOC */
#ifndef __SG_FORMAT
#define __SG_FORMAT(...) __attribute__((format(printf, __VA_ARGS__)))
#endif /* __SG_FORMAT */
#define SG_VERSION_MAJOR 3
#define SG_VERSION_MINOR 5
#define SG_VERSION_PATCH 1
#define SG_VERSION_HEX \
((SG_VERSION_MAJOR << 16) | (SG_VERSION_MINOR << 8) | (SG_VERSION_PATCH))
#define SG_ERR_SIZE 256
/**
* \ingroup sg_api
* \defgroup sg_utils Utilities
* All utility functions of the library.
* \{
*/
/**
* Callback signature used to override the function which allocates a new
* memory space.
* \param[in] size Memory size to be allocated.
* \return Pointer of the allocated memory.
* \retval NULL If size is `0` or no memory space.
*/
typedef void *(*sg_malloc_func)(size_t size);
/**
* Callback signature used to override the function which reallocates an
* existing memory block.
* \param[in] ptr Pointer of the memory to be reallocated.
* \param[in] size Memory size to be reallocated.
* \return Pointer of the reallocated memory.
*/
typedef void *(*sg_realloc_func)(void *ptr, size_t size);
/**
* Callback signature used to override the function which frees a memory space
* previously allocated by #sg_malloc(), #sg_alloc() or #sg_realloc().
* \param[in] ptr Pointer of the memory to be freed.
*/
typedef void (*sg_free_func)(void *ptr);
/**
* Callback signature used to override the function which returns the value of
* `x` raised to the power of `y`.
* \param[in] x Floating point base value.
* \param[in] y Floating point power value.
* \return Value of `x` raised to the power of `y`.
*/
typedef double (*sg_pow_func)(double x, double y);
/**
* Callback signature used to override the function which returns the remainder
* of `x` divided by `y`.
* \param[in] x Floating point value with the division numerator.
* \param[in] y Floating point value with the division denominator.
* \return Remainder of `x` divided by `y`.
*/
typedef double (*sg_fmod_func)(double x, double y);
/**
* Callback signature used by functions that handle errors.
* \param[out] cls User-defined closure.
* \param[out] err Error message.
*/
typedef void (*sg_err_cb)(void *cls, const char *err);
/**
* Callback signature used by functions that write streams.
* \param[out] handle Stream handle.
* \param[out] offset Current stream offset.
* \param[out] buf Current buffer to be written.
* \param[out] size Size of the current buffer to be written.
* \return Total written buffer.
*/
typedef ssize_t (*sg_write_cb)(void *handle, uint64_t offset, const char *buf,
size_t size);
/**
* Callback signature used by functions that read streams.
* \param[out] handle Stream handle.
* \param[out] offset Current stream offset.
* \param[out] buf Current read buffer.
* \param[out] size Size of the current read buffer.
* \return Total read buffer.
*/
typedef ssize_t (*sg_read_cb)(void *handle, uint64_t offset, char *buf,
size_t size);
/**
* Callback signature used by functions that free streams.
* \param[out] handle Stream handle.
*/
typedef void (*sg_free_cb)(void *handle);
/**
* Callback signature used by functions that save streams.
* \param[out] handle Stream handle.
* \param[out] overwritten Overwrite an already existed stream.
* \retval 0 Success.
* \retval E<ERROR> User-defined error to abort the saving.
*/
typedef int (*sg_save_cb)(void *handle, bool overwritten);
/**
* Callback signature used by functions that save streams. It allows to specify
* the destination file path.
* \param[out] handle Stream handle.
* \param[out] path Absolute path to store the stream.
* \param[out] overwritten Overwrite an already existed stream.
* \retval 0 Success.
* \retval E<ERROR> User-defined error to abort the saving.
*/
typedef int (*sg_save_as_cb)(void *handle, const char *path, bool overwritten);
/**
* Returns the library version number.
* \return Library version packed into a single integer.
*/
SG_EXTERN unsigned int sg_version(void);
/**
* Returns the library version number as string in the format
* `<MAJOR>.<MINOR>.<PATCH>`.
* \return Library version packed into a null-terminated string.
*/
SG_EXTERN const char *sg_version_str(void);
/**
* Overrides the standard functions
* [malloc(3)](https://linux.die.net/man/3/malloc),
* [realloc(3)](https://linux.die.net/man/3/realloc) and
* [free(3)](https://linux.die.net/man/3/free) set by default in the memory
* manager.
* \param[in] malloc_func Reference to override the function `malloc()`.
* \param[in] realloc_func Reference to override the function `realloc()`.
* \param[in] free_func Reference to override the function `free()`.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \note It must be called before any other Sagui function or after all
* resources have been freed.
*/
SG_EXTERN int sg_mm_set(sg_malloc_func malloc_func,
sg_realloc_func realloc_func, sg_free_func free_func);
/**
* Allocates a new memory space.
* \param[in] size Memory size to be allocated.
* \return Pointer of the allocated memory.
* \retval NULL If size is `0` or no memory space.
* \note Equivalent to [malloc(3)](https://linux.die.net/man/3/malloc).
*/
SG_EXTERN void *sg_malloc(size_t size) __SG_MALLOC;
/**
* Allocates a new zero-initialized memory space.
* \param[in] size Memory size to be allocated.
* \return Pointer of the zero-initialized allocated memory.
* \retval NULL If size is `0` or no memory space.
*/
SG_EXTERN void *sg_alloc(size_t size) __SG_MALLOC;
/**
* Reallocates an existing memory block.
* \param[in] ptr Pointer of the memory to be reallocated.
* \param[in] size Memory size to be reallocated.
* \return Pointer of the reallocated memory.
* \note Equivalent to [realloc(3)](https://linux.die.net/man/3/realloc).
*/
SG_EXTERN void *sg_realloc(void *ptr, size_t size) __SG_MALLOC;
/**
* Frees a memory space previously allocated by #sg_malloc(), #sg_alloc() or
* #sg_realloc().
* \param[in] ptr Pointer of the memory to be freed.
* \note Equivalent to [free(3)](https://linux.die.net/man/3/free).
*/
SG_EXTERN void sg_free(void *ptr);
/**
* Overrides the standard functions [pow(3)](https://linux.die.net/man/3/pow)
* and [fmod(3)](https://linux.die.net/man/3/fmod) set by default in the math
* manager.
* \param[in] pow_func Reference to override the function `pow()`.
* \param[in] fmod_func Reference to override the function `fmod()`.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \note It must be called before any other Sagui function or after all
* resources have been freed.
*/
SG_EXTERN int sg_math_set(sg_pow_func pow_func, sg_fmod_func fmod_func);
/**
* Returns string describing an error number.
* \param[in] errnum Error number.
* \param[in,out] errmsg Pointer of a string to store the error message.
* \param[in] errlen Length of the error message.
* \return Pointer to \pr{errmsg}.
*/
SG_EXTERN char *sg_strerror(int errnum, char *errmsg, size_t errlen);
/**
* Checks if a string is a HTTP post method.
* \param[in] method Null-terminated string.
* \retval true If \pr{method} is `POST`, `PUT`, `DELETE` or `OPTIONS`.
*/
SG_EXTERN bool sg_is_post(const char *method);
/**
* Extracts the entry-point of a path or resource. For example, given a path
* `/api1/customer`, the part considered as entry-point is `/api1`.
* \param path Path as a null-terminated string.
* \return Entry-point as a null-terminated string.
* \retval NULL If no memory space is available.
* \warning The caller must free the returned value.
*/
SG_EXTERN char *sg_extract_entrypoint(const char *path) __SG_MALLOC;
/**
* Returns the system temporary directory.
* \return Temporary directory as a null-terminated string.
* \retval NULL If no memory space is available.
* \warning The caller must free the returned value.
*/
SG_EXTERN char *sg_tmpdir(void) __SG_MALLOC;
/**
* Indicates the end-of-read processed in #sg_httpres_sendstream().
* \param[in] err `true` to return a value indicating a stream reading error.
* \return Value to end a stream reading.
*/
SG_EXTERN ssize_t sg_eor(bool err);
/**
* Obtains the IP of a socket handle (e.g. the one returned by
* #sg_httpreq_client()) into a null-terminated string.
* \param[in] socket Socket handle.
* \param[out] buf Pointer of the string to store the IP.
* \param[in] size Size of the string to store the IP.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \retval EAFNOSUPPORT Address family not supported by protocol.
* \retval ENOSPC No space left on device.
*/
SG_EXTERN int sg_ip(const void *socket, char *buf, size_t size);
/** \} */
/**
* \ingroup sg_api
* \defgroup sg_str String
* String handle and its related functions.
* \{
*/
/**
* Handle for the string structure used to represent a HTML body, POST payload
* and more.
* \struct sg_str
*/
struct sg_str;
/**
* Creates a new zero-initialized string handle.
* \return String handle.
* \retval NULL If no memory space is available.
*/
SG_EXTERN struct sg_str *sg_str_new(void) __SG_MALLOC;
/**
* Frees the string handle previously allocated by #sg_str_new().
* \param[in] str Pointer of the string handle to be freed.
*/
SG_EXTERN void sg_str_free(struct sg_str *str);
/**
* Writes a null-terminated string to the string handle \pr{str}. All strings
* previously written are kept.
* \param[in] str String handle.
* \param[in] val String to be written.
* \param[in] len Length of the string to be written.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
*/
SG_EXTERN int sg_str_write(struct sg_str *str, const char *val, size_t len);
/**
* Prints a null-terminated formatted string from the argument list to the
* string handle \pr{str}.
* \param[in] str String handle.
* \param[in] fmt Formatted string (following the same
* [`printf()`](https://linux.die.net/man/3/printf) format specification).
* \param[in] ap Arguments list (handled by
* [`va_start()`](https://linux.die.net/man/3/va_start)/
* [`va_end()`](https://linux.die.net/man/3/va_end)).
* \retval 0 Success.
* \retval EINVAL Invalid argument.
*/
SG_EXTERN int sg_str_printf_va(struct sg_str *str, const char *fmt, va_list ap);
/**
* Prints a null-terminated formatted string to the string handle \pr{str}. All
* strings previously written are kept.
* \param[in] str String handle.
* \param[in] fmt Formatted string (following the same
* [`printf()`](https://linux.die.net/man/3/printf) format specification).
* \param[in] ... Additional arguments (following the same
* [`printf()`](https://linux.die.net/man/3/printf) arguments specification).
* \retval 0 Success.
* \retval EINVAL Invalid argument.
*/
SG_EXTERN int sg_str_printf(struct sg_str *str, const char *fmt, ...)
__SG_FORMAT(2, 3);
/**
* Returns the null-terminated string content from the string handle \pr{str}.
* \param[in] str String handle.
* \return Content as a null-terminated string.
* \retval NULL If the \pr{str} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_str_content(struct sg_str *str);
/**
* Returns the total string length from the handle \pr{str}.
* \param[in] str String handle.
* \return Total string length.
* \retval EINVAL Invalid argument.
*/
SG_EXTERN size_t sg_str_length(struct sg_str *str);
/**
* Clears all existing content in the string handle \pr{str}.
* \param[in] str String handle.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
*/
SG_EXTERN int sg_str_clear(struct sg_str *str);
/** \} */
/**
* \ingroup sg_api
* \defgroup sg_strmap String map
* String map handle and its related functions.
* \{
*/
/**
* Handle for hash table that maps name-value pairs. It is useful to represent
* posting fields, query-string parameter, client cookies and more.
* \struct sg_strmap
*/
struct sg_strmap;
/**
* Callback signature used by #sg_strmap_iter() to iterate pairs of strings.
* \param[out] cls User-defined closure.
* \param[out] pair Current iterated pair.
* \retval 0 Success.
* \retval E<ERROR> User-defined error to stop pairs iteration.
*/
typedef int (*sg_strmap_iter_cb)(void *cls, struct sg_strmap *pair);
/**
* Callback signature used by #sg_strmap_sort() to sort pairs of strings.
* \param[out] cls User-defined closure.
* \param[out] pair_a Current left pair (A).
* \param[out] pair_b Current right pair (B).
* \retval -1 A < B.
* \retval 0 A == B.
* \retval 1 A > B.
*/
typedef int (*sg_strmap_sort_cb)(void *cls, struct sg_strmap *pair_a,
struct sg_strmap *pair_b);
/**
* Returns a name from the \pr{pair}.
* \param[in] pair Pair of name-value.
* \return Name as a null-terminated string.
* \retval NULL If the \pr{pair} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_strmap_name(struct sg_strmap *pair);
/**
* Returns a value from the \pr{pair}.
* \param[in] pair Pair of name-value.
* \return Value as a null-terminated string.
* \retval NULL If the \pr{pair} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_strmap_val(struct sg_strmap *pair);
/**
* Adds a pair of name-value to the string \pr{map}.
* \param[in,out] map Pairs map pointer to add a new pair.
* \param[in] name Pair name.
* \param[in] val Pair value.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \retval ENOMEM Out of memory.
* \note It cannot check if a name already exists in a pair added to the
* \pr{map}, then the uniqueness must be managed by the application.
*/
SG_EXTERN int sg_strmap_add(struct sg_strmap **map, const char *name,
const char *val);
/**
* Sets a pair of name-value to the string \pr{map}.
* \param[in,out] map Pairs map pointer to set a new pair.
* \param[in] name Pair name.
* \param[in] val Pair value.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \retval ENOMEM Out of memory.
* \note If a name already exists in a pair previously added into the \pr{map},
* then the function replaces its value, otherwise it is added as a new pair.
*/
SG_EXTERN int sg_strmap_set(struct sg_strmap **map, const char *name,
const char *val);
/**
* Finds a pair by name.
* \param[in] map Pairs map.
* \param[in] name Name to find the pair.
* \param[in,out] pair Pointer of the variable to store the found pair.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \retval ENOENT Pair not found.
* \retval ENOMEM Out of memory.
*/
SG_EXTERN int sg_strmap_find(struct sg_strmap *map, const char *name,
struct sg_strmap **pair);
/**
* Gets a pair by name and returns the value.
* \param[in] map Pairs map.
* \param[in] name Name to get the pair.
* \return Pair value as a null-terminated string.
* \retval NULL If \pr{map} or \pr{name} is null or pair is not found.
*/
SG_EXTERN const char *sg_strmap_get(struct sg_strmap *map, const char *name);
/**
* Removes a pair by name.
* \param[in] map Pointer to the pairs map.
* \param[in] name Name to find and then remove the pair.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \retval ENOENT Pair already removed.
* \retval ENOMEM Out of memory.
*/
SG_EXTERN int sg_strmap_rm(struct sg_strmap **map, const char *name);
/**
* Iterates over pairs map.
* \param[in] map Pairs map.
* \param[in] cb Callback to iterate the pairs.
* \param[in,out] cls User-specified value.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \return Callback result when it is different from `0`.
*/
SG_EXTERN int sg_strmap_iter(struct sg_strmap *map, sg_strmap_iter_cb cb,
void *cls);
/**
* Sorts the pairs map.
* \param[in,out] map Pointer to the pairs map.
* \param[in] cb Callback to sort the pairs.
* \param[in,out] cls User-specified value.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
*/
SG_EXTERN int sg_strmap_sort(struct sg_strmap **map, sg_strmap_sort_cb cb,
void *cls);
/**
* Counts the total pairs in the map.
* \param[in] map Pairs map.
* \return Total of pairs.
* \retval 0 If the list is empty or null.
*/
SG_EXTERN unsigned int sg_strmap_count(struct sg_strmap *map);
/**
* Returns the next pair in the map.
* \param[in,out] next Pointer to the next pair.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
*/
SG_EXTERN int sg_strmap_next(struct sg_strmap **next);
/**
* Cleans the entire map.
* \param[in,out] map Pointer to the pairs map.
*/
SG_EXTERN void sg_strmap_cleanup(struct sg_strmap **map);
/** \} */
/**
* \ingroup sg_api
* \defgroup sg_httpsrv HTTP server
* Fast event-driven HTTP server.
* \{
*/
/**
* Handle for the HTTP basic authentication.
* \struct sg_httpauth
*/
struct sg_httpauth;
/**
* Handle for the upload handling. It is used to represent a single upload or a
* list of uploads.
* \struct sg_httpupld
*/
struct sg_httpupld;
/**
* Handle for the request handling. It contains headers, cookies, query-string,
* fields, payloads, uploads and other data sent by the client.
* \struct sg_httpreq
*/
struct sg_httpreq;
/**
* Handle for the response handling. It dispatches headers, contents, binaries,
* files and other data to the client.
* \struct sg_httpres
*/
struct sg_httpres;
/**
* Handle for the fast event-driven HTTP server.
* \struct sg_httpsrv
*/
struct sg_httpsrv;
/**
* Callback signature used to handle client connection events.
* \param[out] cls User-defined closure.
* \param[out] client Socket handle of the client.
* \param[in,out] closed Indicates if the client is connected allowing to
* close it.
*/
typedef void (*sg_httpsrv_cli_cb)(void *cls, const void *client, bool *closed);
/**
* Callback signature used to grant or deny the user access to the server
* resources.
* \param[out] cls User-defined closure.
* \param[out] auth Authentication handle.
* \param[out] req Request handle.
* \param[out] res Response handle.
* \retval true Grants the user access.
* \retval false Denies the user access.
*/
typedef bool (*sg_httpauth_cb)(void *cls, struct sg_httpauth *auth,
struct sg_httpreq *req, struct sg_httpres *res);
/**
* Callback signature used to handle uploaded files and/or fields.
* \param[out] cls User-defined closure.
* \param[in,out] handle Stream handle pointer.
* \param[out] dir Directory to store the uploaded files.
* \param[out] field Posted field.
* \param[out] name Uploaded file name.
* \param[out] mime Uploaded file content-type (e.g.: `text/plain`, `image/png`,
* `application/json` etc.).
* \param[out] encoding Uploaded file transfer-encoding (e.g.: `chunked`,
* `deflate`, `gzip` etc.).
* \retval 0 Success.
* \retval E<ERROR> User-defined error to refuse the upload.
*/
typedef int (*sg_httpupld_cb)(void *cls, void **handle, const char *dir,
const char *field, const char *name,
const char *mime, const char *encoding);
/**
* Callback signature used to iterate uploaded files.
* \param[out] cls User-defined closure.
* \param[out] upld Current upload item.
* \retval 0 Success.
* \retval E<ERROR> User-defined error to stop list iteration.
*/
typedef int (*sg_httpuplds_iter_cb)(void *cls, struct sg_httpupld *upld);
/**
* Callback signature used to handle requests and responses.
* \param[out] cls User-defined closure.
* \param[out] req Request handle.
* \param[out] res Response handle.
*/
typedef void (*sg_httpreq_cb)(void *cls, struct sg_httpreq *req,
struct sg_httpres *res);
/**
* Sets the authentication protection space (realm).
* \param[in] auth Authentication handle.
* \param[in] realm Realm string.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \retval EALREADY Realm already set.
* \retval ENOMEM Out of memory.
*/
SG_EXTERN int sg_httpauth_set_realm(struct sg_httpauth *auth,
const char *realm);
/**
* Gets the authentication protection space (realm).
* \param[in] auth Authentication handle.
* \return Realm as a null-terminated string.
* \retval NULL If \pr{auth} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_httpauth_realm(struct sg_httpauth *auth);
/**
* Deny the authentication sending the reason to the user.
* \param[in] auth Authentication handle.
* \param[in] reason Denial reason.
* \param[in] content_type Content type.
* \param[in] status HTTP status code.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \retval EALREADY Already denied.
* \retval ENOMEM Out of memory.
*/
SG_EXTERN int sg_httpauth_deny2(struct sg_httpauth *auth, const char *reason,
const char *content_type, unsigned int status);
/**
* Deny the authentication sending the reason to the user.
* \param[in] auth Authentication handle.
* \param[in] reason Denial reason.
* \param[in] content_type Content type.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \retval EALREADY Already denied.
* \retval ENOMEM Out of memory.
*/
SG_EXTERN int sg_httpauth_deny(struct sg_httpauth *auth, const char *reason,
const char *content_type);
/**
* Cancels the authentication loop while the user is trying to access
* the server.
* \param[in] auth Authentication handle.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
*/
SG_EXTERN int sg_httpauth_cancel(struct sg_httpauth *auth);
/**
* Returns the authentication user.
* \param[in] auth Authentication handle.
* \return User as a null-terminated string.
* \retval NULL If \pr{auth} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_httpauth_usr(struct sg_httpauth *auth);
/**
* Returns the authentication password.
* \param[in] auth Authentication handle.
* \return Password as a null-terminated string.
* \retval NULL If \pr{auth} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_httpauth_pwd(struct sg_httpauth *auth);
/**
* Iterates over all the upload items in the \pr{uplds} list.
* \param[in] uplds Uploads list handle.
* \param[in] cb Callback to iterate over upload items.
* \param[in] cls User-defined closure.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \retval E<ERROR> User-defined error to abort the list iteration.
*/
SG_EXTERN int sg_httpuplds_iter(struct sg_httpupld *uplds,
sg_httpuplds_iter_cb cb, void *cls);
/**
* Gets the next upload item starting from the first item pointer \pr{upld}.
* \param[in,out] upld Next upload item starting from the first item pointer.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
*/
SG_EXTERN int sg_httpuplds_next(struct sg_httpupld **upld);
/**
* Counts the total upload items in the list \pr{uplds}.
* \param[in] uplds Uploads list.
* \return Total of items.
* \retval 0 If the list is empty or null.
*/
SG_EXTERN unsigned int sg_httpuplds_count(struct sg_httpupld *uplds);
/**
* Returns the stream handle of the upload handle \pr{upld}.
* \param[in] upld Upload handle.
* \return Stream handle.
* \retval NULL If \pr{upld} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN void *sg_httpupld_handle(struct sg_httpupld *upld);
/**
* Returns the directory of the upload handle \pr{upld}.
* \param[in] upld Upload handle.
* \return Upload directory as a null-terminated string.
* \retval NULL If \pr{upld} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_httpupld_dir(struct sg_httpupld *upld);
/**
* Returns the field of the upload handle \pr{upld}.
* \param[in] upld Upload handle.
* \return Upload field as a null-terminated string.
* \retval NULL If \pr{upld} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_httpupld_field(struct sg_httpupld *upld);
/**
* Returns the name of the upload handle \pr{upld}.
* \param[in] upld Upload handle.
* \return Upload name as a null-terminated string.
* \retval NULL If \pr{upld} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_httpupld_name(struct sg_httpupld *upld);
/**
* Returns the MIME (content-type) of the upload.
* \param[in] upld Upload handle.
* \return Upload MIME as a null-terminated string.
* \retval NULL If \pr{upld} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_httpupld_mime(struct sg_httpupld *upld);
/**
* Returns the encoding (transfer-encoding) of the upload.
* \param[in] upld Upload handle.
* \return Upload encoding as a null-terminated string.
* \retval NULL If \pr{upld} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_httpupld_encoding(struct sg_httpupld *upld);
/**
* Returns the size of the upload.
* \param[in] upld Upload handle.
* \return Upload size into `uint64`. If \pr{upld} is null, set the `errno` to
* `EINVAL`.
*/
SG_EXTERN uint64_t sg_httpupld_size(struct sg_httpupld *upld);
/**
* Saves the uploaded file defining the destination path by upload name and
* directory.
* \param[in] upld Upload handle.
* \param[in] overwritten Overwrite upload file if it exists.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \retval EEXIST File already exists (if \pr{overwritten} is `false`).
* \retval EISDIR Destination file is a directory.
*/
SG_EXTERN int sg_httpupld_save(struct sg_httpupld *upld, bool overwritten);
/**
* Saves the uploaded file allowing to define the destination path.
* \param[in] upld Upload handle.
* \param[in] path Absolute destination path.
* \param[in] overwritten Overwrite upload file if it exists.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \retval EEXIST File already exists (if \pr{overwritten} is `true`).
* \retval EISDIR Destination file is a directory.
*/
SG_EXTERN int sg_httpupld_save_as(struct sg_httpupld *upld, const char *path,
bool overwritten);
/**
* Returns the server instance.
* \param[in] req Request handle.
* \return Reference to the server instance.
* \retval NULL If \pr{req} is null and set the `errno` to `EINVAL`
*/
SG_EXTERN struct sg_httpsrv *sg_httpreq_srv(struct sg_httpreq *req);
/**
* Returns the client headers into #sg_strmap map.
* \param[in] req Request handle.
* \return Reference to the client headers map.
* \retval NULL If \pr{req} is null and set the `errno` to `EINVAL`
* \note The headers map is automatically freed by the library.
*/
SG_EXTERN struct sg_strmap **sg_httpreq_headers(struct sg_httpreq *req);
/**
* Returns the client cookies into #sg_strmap map.
* \param[in] req Request handle.
* \return Reference to the client cookies map.
* \retval NULL If \pr{req} is null and set the `errno` to `EINVAL`
* \note The cookies map is automatically freed by the library.
*/
SG_EXTERN struct sg_strmap **sg_httpreq_cookies(struct sg_httpreq *req);
/**
* Returns the query-string into #sg_strmap map.
* \param[in] req Request handle.
* \return Reference to the query-string map.
* \retval NULL If \pr{req} is null and set the `errno` to `EINVAL`
* \note The query-string map is automatically freed by the library.
*/
SG_EXTERN struct sg_strmap **sg_httpreq_params(struct sg_httpreq *req);
/**
* Returns the fields of a HTML form into #sg_strmap map.
* \param[in] req Request handle.
* \return Reference to the form fields map.
* \retval NULL If \pr{req} is null and set the `errno` to `EINVAL`
* \note The form fields map is automatically freed by the library.
*/
SG_EXTERN struct sg_strmap **sg_httpreq_fields(struct sg_httpreq *req);
/**
* Returns the HTTP version.
* \param[in] req Request handle.
* \return HTTP version as a null-terminated string.
* \retval NULL If \pr{req} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_httpreq_version(struct sg_httpreq *req);
/**
* Returns the HTTP method.
* \param[in] req Request handle.
* \return HTTP method as a null-terminated string.
* \retval NULL If \pr{req} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_httpreq_method(struct sg_httpreq *req);
/**
* Returns the path component.
* \param[in] req Request handle.
* \return Path component as a null-terminated string.
* \retval NULL If \pr{req} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const char *sg_httpreq_path(struct sg_httpreq *req);
/**
* Returns the posting payload into a #sg_str instance.
* \param[in] req Request handle.
* \return Instance of the payload.
* \retval NULL If \pr{req} is null and set the `errno` to `EINVAL`.
* \note The form payload instance is automatically freed by the library.
*/
SG_EXTERN struct sg_str *sg_httpreq_payload(struct sg_httpreq *req);
/**
* Checks if the client is uploading data.
* \param[in] req Request handle.
* \retval true If the client is uploading data, `false` otherwise. If \pr{req}
* is null, set the `errno` to `EINVAL`.
*/
SG_EXTERN bool sg_httpreq_is_uploading(struct sg_httpreq *req);
/**
* Returns the list of the uploaded files.
* \param[in] req Request handle.
* \return List of the uploaded files.
* \retval NULL If \pr{req} is null and set the `errno` to `EINVAL`.
* \note The uploads list is automatically freed by the library.
*/
SG_EXTERN struct sg_httpupld *sg_httpreq_uploads(struct sg_httpreq *req);
/**
* Gets the socket handle of the client.
* \param[in] req Request handle.
* \return Socket address of the client.
* \retval NULL If \pr{req} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN const void *sg_httpreq_client(struct sg_httpreq *req);
#ifdef SG_HTTPS_SUPPORT
/**
* Returns the [GnuTLS](https://gnutls.org) session handle.
* \param[in] req Request handle.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
*/
SG_EXTERN void *sg_httpreq_tls_session(struct sg_httpreq *req);
#endif /* SG_HTTPS_SUPPORT */
/**
* Isolates a request from the main event loop to an own dedicated thread,
* bringing it back when the request finishes.
* \param[in] req Request handle.
* \param[in] cb Callback to handle requests and responses isolated from the
* main event loop.
* \param[in] cls User-defined closure.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
* \retval ENOMEM Out of memory.
* \retval E<ERROR> Any returned error from the OS threading library.
* \note Isolated requests will not time out.
* \note While a request is isolated, the library will not detect disconnects
* by the client.
*/
SG_EXTERN int sg_httpreq_isolate(struct sg_httpreq *req, sg_httpreq_cb cb,
void *cls);
/**
* Sets user data to the request handle.
* \param[in] req Request handle.
* \param[in] data User data pointer.
* \retval 0 Success.
* \retval EINVAL Invalid argument.
*/
SG_EXTERN int sg_httpreq_set_user_data(struct sg_httpreq *req, void *data);
/**
* Gets user data from the request handle.
* \param[in] req Request handle.
* \return User data pointer.
* \retval NULL If \pr{req} is null and set the `errno` to `EINVAL`.
*/
SG_EXTERN void *sg_httpreq_user_data(struct sg_httpreq *req);
/**