1 #ifndef HTTP_RESPONSE_H
2 #define HTTP_RESPONSE_H
3 
4 #include "array.h"
5 
6 #include "http-header.h"
7 
8 #define HTTP_RESPONSE_STATUS_INTERNAL 9000
9 
10 enum http_response_payload_type {
11 	HTTP_RESPONSE_PAYLOAD_TYPE_ALLOWED,
12 	HTTP_RESPONSE_PAYLOAD_TYPE_NOT_PRESENT,
13 	HTTP_RESPONSE_PAYLOAD_TYPE_ONLY_UNSUCCESSFUL
14 };
15 
16 struct http_response {
17 	unsigned char version_major;
18 	unsigned char version_minor;
19 
20 	unsigned int status;
21 
22 	const char *reason;
23 	const char *location;
24 
25 	time_t date, retry_after;
26 	const struct http_header *header;
27 	struct istream *payload;
28 
29 	ARRAY_TYPE(const_string) connection_options;
30 
31 	bool connection_close:1;
32 };
33 
34 static inline bool
http_response_is_success(const struct http_response * resp)35 http_response_is_success(const struct http_response *resp)
36 {
37 	return ((resp->status / 100) == 2);
38 }
39 
40 static inline bool
http_response_is_internal_error(const struct http_response * resp)41 http_response_is_internal_error(const struct http_response *resp)
42 {
43 	return (resp->status >= HTTP_RESPONSE_STATUS_INTERNAL);
44 }
45 
46 void
47 http_response_init(struct http_response *resp,
48 	unsigned int status, const char *reason);
49 
50 static inline const struct http_header_field *
http_response_header_find(const struct http_response * resp,const char * name)51 http_response_header_find(const struct http_response *resp, const char *name)
52 {
53 	if (resp->header == NULL)
54 		return NULL;
55 	return http_header_field_find(resp->header, name);
56 }
57 
58 static inline const char *
http_response_header_get(const struct http_response * resp,const char * name)59 http_response_header_get(const struct http_response *resp, const char *name)
60 {
61 	if (resp->header == NULL)
62 		return NULL;
63 	return http_header_field_get(resp->header, name);
64 }
65 
ARRAY_TYPE(http_header_field)66 static inline const ARRAY_TYPE(http_header_field) *
67 http_response_header_get_fields(const struct http_response *resp)
68 {
69 	if (resp->header == NULL)
70 		return NULL;
71 	return http_header_get_fields(resp->header);
72 }
73 
74 static inline const char *
http_response_get_message(const struct http_response * resp)75 http_response_get_message(const struct http_response *resp)
76 {
77 	if (resp->status >= HTTP_RESPONSE_STATUS_INTERNAL)
78 		return resp->reason;
79 	return t_strdup_printf("%u %s", resp->status, resp->reason);
80 }
81 
82 bool http_response_has_connection_option(const struct http_response *resp,
83 	const char *option);
84 int http_response_get_payload_size(const struct http_response *resp,
85 	uoff_t *size_r);
86 
87 #endif
88