1 /***********************************************************************************************************************************
2 HTTP Response
3 
4 Response created after a successful request. Once the content is read the underlying connection may be recycled but the headers,
5 cached content, etc. will still be available for the lifetime of the object.
6 ***********************************************************************************************************************************/
7 #ifndef COMMON_IO_HTTP_RESPONSE_H
8 #define COMMON_IO_HTTP_RESPONSE_H
9 
10 /***********************************************************************************************************************************
11 Object type
12 ***********************************************************************************************************************************/
13 typedef struct HttpResponse HttpResponse;
14 
15 #include "common/io/http/header.h"
16 #include "common/io/http/session.h"
17 #include "common/io/read.h"
18 #include "common/type/object.h"
19 
20 /***********************************************************************************************************************************
21 HTTP Response Constants
22 ***********************************************************************************************************************************/
23 #define HTTP_RESPONSE_CODE_PERMANENT_REDIRECT                       308
24 #define HTTP_RESPONSE_CODE_FORBIDDEN                                403
25 #define HTTP_RESPONSE_CODE_NOT_FOUND                                404
26 
27 /***********************************************************************************************************************************
28 Constructors
29 ***********************************************************************************************************************************/
30 HttpResponse *httpResponseNew(HttpSession *session, const String *verb, bool contentCache);
31 
32 /***********************************************************************************************************************************
33 Getters/Setters
34 ***********************************************************************************************************************************/
35 typedef struct HttpResponsePub
36 {
37     MemContext *memContext;                                         // Mem context
38     IoRead *contentRead;                                            // Read interface for response content
39     unsigned int code;                                              // Response code (e.g. 200, 404)
40     HttpHeader *header;                                             // Response headers
41     String *reason;                                                 // Response reason e.g. (OK, Not Found)
42 } HttpResponsePub;
43 
44 // Read interface used to get the response content. This is intended for reading content that may be very large and will not be held
45 // in memory all at once. If the content must be loaded completely for processing (e.g. XML) then httpResponseContent() is simpler.
46 __attribute__((always_inline)) static inline IoRead *
httpResponseIoRead(HttpResponse * const this)47 httpResponseIoRead(HttpResponse *const this)
48 {
49     return THIS_PUB(HttpResponse)->contentRead;
50 }
51 
52 // Response code
53 __attribute__((always_inline)) static inline unsigned int
httpResponseCode(const HttpResponse * const this)54 httpResponseCode(const HttpResponse *const this)
55 {
56     return THIS_PUB(HttpResponse)->code;
57 }
58 
59 // Response headers
60 __attribute__((always_inline)) static inline const HttpHeader *
httpResponseHeader(const HttpResponse * const this)61 httpResponseHeader(const HttpResponse *const this)
62 {
63     return THIS_PUB(HttpResponse)->header;
64 }
65 
66 // Response reason
67 __attribute__((always_inline)) static inline const String *
httpResponseReason(const HttpResponse * const this)68 httpResponseReason(const HttpResponse *const this)
69 {
70     return THIS_PUB(HttpResponse)->reason;
71 }
72 
73 /***********************************************************************************************************************************
74 Functions
75 ***********************************************************************************************************************************/
76 // Is this response code OK, i.e. 2XX?
77 __attribute__((always_inline)) static inline bool
httpResponseCodeOk(const HttpResponse * const this)78 httpResponseCodeOk(const HttpResponse *const this)
79 {
80     return httpResponseCode(this) / 100 == 2;
81 }
82 
83 // Fetch all response content. Content will be cached so it can be retrieved again without additional cost.
84 const Buffer *httpResponseContent(HttpResponse *this);
85 
86 // Move to a new parent mem context
87 __attribute__((always_inline)) static inline HttpResponse *
httpResponseMove(HttpResponse * const this,MemContext * const parentNew)88 httpResponseMove(HttpResponse *const this, MemContext *const parentNew)
89 {
90     return objMove(this, parentNew);
91 }
92 
93 /***********************************************************************************************************************************
94 Destructor
95 ***********************************************************************************************************************************/
96 __attribute__((always_inline)) static inline void
httpResponseFree(HttpResponse * const this)97 httpResponseFree(HttpResponse *const this)
98 {
99     objFree(this);
100 }
101 
102 /***********************************************************************************************************************************
103 Macros for function logging
104 ***********************************************************************************************************************************/
105 String *httpResponseToLog(const HttpResponse *this);
106 
107 #define FUNCTION_LOG_HTTP_RESPONSE_TYPE                                                                                            \
108     HttpResponse *
109 #define FUNCTION_LOG_HTTP_RESPONSE_FORMAT(value, buffer, bufferSize)                                                               \
110     FUNCTION_LOG_STRING_OBJECT_FORMAT(value, httpResponseToLog, buffer, bufferSize)
111 
112 #endif
113