|
| 1 | +/* |
| 2 | + +----------------------------------------------------------------------+ |
| 3 | + | PHP Version 7 | |
| 4 | + +----------------------------------------------------------------------+ |
| 5 | + | Copyright (c) 1997-2016 The PHP Group | |
| 6 | + +----------------------------------------------------------------------+ |
| 7 | + | This source file is subject to version 3.01 of the PHP license, | |
| 8 | + | that is bundled with this package in the file LICENSE, and is | |
| 9 | + | available through the world-wide-web at the following url: | |
| 10 | + | http://www.php.net/license/3_01.txt | |
| 11 | + | If you did not receive a copy of the PHP license and are unable to | |
| 12 | + | obtain it through the world-wide-web, please send a note to | |
| 13 | + | [email protected] so we can mail you a copy immediately. | |
| 14 | + +----------------------------------------------------------------------+ |
| 15 | + | Authors: Dmitry Stogov <[email protected]> | |
| 16 | + +----------------------------------------------------------------------+ |
| 17 | +*/ |
| 18 | + |
| 19 | +/* $Id$ */ |
| 20 | + |
| 21 | +/* FastCGI protocol */ |
| 22 | + |
| 23 | +#define FCGI_VERSION_1 1 |
| 24 | + |
| 25 | +#define FCGI_MAX_LENGTH 0xffff |
| 26 | + |
| 27 | +#define FCGI_KEEP_CONN 1 |
| 28 | + |
| 29 | +/* this is near the perfect hash function for most useful FastCGI variables |
| 30 | + * which combines efficiency and minimal hash collisions |
| 31 | + */ |
| 32 | + |
| 33 | +#define FCGI_HASH_FUNC(var, var_len) \ |
| 34 | + (UNEXPECTED(var_len < 3) ? var_len : \ |
| 35 | + (((unsigned int)var[3]) << 2) + \ |
| 36 | + (((unsigned int)var[var_len-2]) << 4) + \ |
| 37 | + (((unsigned int)var[var_len-1]) << 2) + \ |
| 38 | + var_len) |
| 39 | + |
| 40 | +#define FCGI_GETENV(request, name) \ |
| 41 | + fcgi_quick_getenv(request, name, sizeof(name)-1, FCGI_HASH_FUNC(name, sizeof(name)-1)) |
| 42 | + |
| 43 | +#define FCGI_PUTENV(request, name, value) \ |
| 44 | + fcgi_quick_putenv(request, name, sizeof(name)-1, FCGI_HASH_FUNC(name, sizeof(name)-1), value) |
| 45 | + |
| 46 | +typedef enum _fcgi_role { |
| 47 | + FCGI_RESPONDER = 1, |
| 48 | + FCGI_AUTHORIZER = 2, |
| 49 | + FCGI_FILTER = 3 |
| 50 | +} fcgi_role; |
| 51 | + |
| 52 | +enum { |
| 53 | + FCGI_DEBUG = 1, |
| 54 | + FCGI_NOTICE = 2, |
| 55 | + FCGI_WARNING = 3, |
| 56 | + FCGI_ERROR = 4, |
| 57 | + FCGI_ALERT = 5, |
| 58 | +}; |
| 59 | + |
| 60 | +typedef enum _fcgi_request_type { |
| 61 | + FCGI_BEGIN_REQUEST = 1, /* [in] */ |
| 62 | + FCGI_ABORT_REQUEST = 2, /* [in] (not supported) */ |
| 63 | + FCGI_END_REQUEST = 3, /* [out] */ |
| 64 | + FCGI_PARAMS = 4, /* [in] environment variables */ |
| 65 | + FCGI_STDIN = 5, /* [in] post data */ |
| 66 | + FCGI_STDOUT = 6, /* [out] response */ |
| 67 | + FCGI_STDERR = 7, /* [out] errors */ |
| 68 | + FCGI_DATA = 8, /* [in] filter data (not supported) */ |
| 69 | + FCGI_GET_VALUES = 9, /* [in] */ |
| 70 | + FCGI_GET_VALUES_RESULT = 10 /* [out] */ |
| 71 | +} fcgi_request_type; |
| 72 | + |
| 73 | +typedef enum _fcgi_protocol_status { |
| 74 | + FCGI_REQUEST_COMPLETE = 0, |
| 75 | + FCGI_CANT_MPX_CONN = 1, |
| 76 | + FCGI_OVERLOADED = 2, |
| 77 | + FCGI_UNKNOWN_ROLE = 3 |
| 78 | +} dcgi_protocol_status; |
| 79 | + |
| 80 | +/* FastCGI client API */ |
| 81 | + |
| 82 | +typedef void (*fcgi_apply_func)(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg); |
| 83 | + |
| 84 | +#define FCGI_HASH_TABLE_SIZE 128 |
| 85 | +#define FCGI_HASH_TABLE_MASK (FCGI_HASH_TABLE_SIZE - 1) |
| 86 | +#define FCGI_HASH_SEG_SIZE 4096 |
| 87 | + |
| 88 | +typedef struct _fcgi_header { |
| 89 | + unsigned char version; |
| 90 | + unsigned char type; |
| 91 | + unsigned char requestIdB1; |
| 92 | + unsigned char requestIdB0; |
| 93 | + unsigned char contentLengthB1; |
| 94 | + unsigned char contentLengthB0; |
| 95 | + unsigned char paddingLength; |
| 96 | + unsigned char reserved; |
| 97 | +} fcgi_header; |
| 98 | + |
| 99 | +typedef struct _fcgi_end_request { |
| 100 | + unsigned char appStatusB3; |
| 101 | + unsigned char appStatusB2; |
| 102 | + unsigned char appStatusB1; |
| 103 | + unsigned char appStatusB0; |
| 104 | + unsigned char protocolStatus; |
| 105 | + unsigned char reserved[3]; |
| 106 | +} fcgi_end_request; |
| 107 | + |
| 108 | +typedef struct _fcgi_end_request_rec { |
| 109 | + fcgi_header hdr; |
| 110 | + fcgi_end_request body; |
| 111 | +} fcgi_end_request_rec; |
| 112 | + |
| 113 | + |
| 114 | +typedef struct _fcgi_data_seg { |
| 115 | + char *pos; |
| 116 | + char *end; |
| 117 | + struct _fcgi_data_seg *next; |
| 118 | + char data[1]; |
| 119 | +} fcgi_data_seg; |
| 120 | + |
| 121 | +typedef struct _fcgi_hash_bucket { |
| 122 | + unsigned int hash_value; |
| 123 | + unsigned int var_len; |
| 124 | + char *var; |
| 125 | + unsigned int val_len; |
| 126 | + char *val; |
| 127 | + struct _fcgi_hash_bucket *next; |
| 128 | + struct _fcgi_hash_bucket *list_next; |
| 129 | +} fcgi_hash_bucket; |
| 130 | + |
| 131 | +typedef struct _fcgi_hash_buckets { |
| 132 | + unsigned int idx; |
| 133 | + struct _fcgi_hash_buckets *next; |
| 134 | + struct _fcgi_hash_bucket data[FCGI_HASH_TABLE_SIZE]; |
| 135 | +} fcgi_hash_buckets; |
| 136 | + |
| 137 | + |
| 138 | +typedef struct _fcgi_hash { |
| 139 | + fcgi_hash_bucket *hash_table[FCGI_HASH_TABLE_SIZE]; |
| 140 | + fcgi_hash_bucket *list; |
| 141 | + fcgi_hash_buckets *buckets; |
| 142 | + fcgi_data_seg *data; |
| 143 | +} fcgi_hash; |
| 144 | + |
| 145 | +typedef struct _fcgi_req_hook fcgi_req_hook; |
| 146 | + |
| 147 | +struct _fcgi_req_hook { |
| 148 | + void(*on_accept)(); |
| 149 | + void(*on_read)(); |
| 150 | + void(*on_close)(); |
| 151 | +}; |
| 152 | + |
| 153 | +struct _fcgi_request { |
| 154 | + int listen_socket; |
| 155 | + int tcp; |
| 156 | + int fd; |
| 157 | + int id; |
| 158 | + int keep; |
| 159 | +#ifdef TCP_NODELAY |
| 160 | + int nodelay; |
| 161 | +#endif |
| 162 | + int closed; |
| 163 | + int in_len; |
| 164 | + int in_pad; |
| 165 | + |
| 166 | + fcgi_header *out_hdr; |
| 167 | + |
| 168 | + unsigned char *out_pos; |
| 169 | + unsigned char out_buf[1024*8]; |
| 170 | + unsigned char reserved[sizeof(fcgi_end_request_rec)]; |
| 171 | + |
| 172 | + fcgi_req_hook hook; |
| 173 | + |
| 174 | + int has_env; |
| 175 | + fcgi_hash env; |
| 176 | +}; |
| 177 | + |
| 178 | +typedef struct _fcgi_request fcgi_request; |
| 179 | + |
| 180 | +int fcgi_init(void); |
| 181 | +void fcgi_shutdown(void); |
| 182 | +int fcgi_is_fastcgi(void); |
| 183 | +int fcgi_is_closed(fcgi_request *req); |
| 184 | +void fcgi_close(fcgi_request *req, int force, int destroy); |
| 185 | +int fcgi_in_shutdown(void); |
| 186 | +void fcgi_terminate(void); |
| 187 | +int fcgi_listen(const char *path, int backlog); |
| 188 | +fcgi_request* fcgi_init_request(int listen_socket, void(*on_accept)(), void(*on_read)(), void(*on_close)()); |
| 189 | +void fcgi_destroy_request(fcgi_request *req); |
| 190 | +void fcgi_set_allowed_clients(char *ip); |
| 191 | +int fcgi_accept_request(fcgi_request *req); |
| 192 | +int fcgi_finish_request(fcgi_request *req, int force_close); |
| 193 | +const char *fcgi_get_last_client_ip(); |
| 194 | +void fcgi_set_in_shutdown(int new_value); |
| 195 | + |
| 196 | +#ifndef HAVE_ATTRIBUTE_WEAK |
| 197 | +typedef void (*fcgi_logger)(int type, const char *fmt, ...); |
| 198 | +void fcgi_set_logger(fcgi_logger lg); |
| 199 | +#endif |
| 200 | + |
| 201 | +int fcgi_has_env(fcgi_request *req); |
| 202 | +char* fcgi_getenv(fcgi_request *req, const char* var, int var_len); |
| 203 | +char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val); |
| 204 | +char* fcgi_quick_getenv(fcgi_request *req, const char* var, int var_len, unsigned int hash_value); |
| 205 | +char* fcgi_quick_putenv(fcgi_request *req, char* var, int var_len, unsigned int hash_value, char* val); |
| 206 | +void fcgi_loadenv(fcgi_request *req, fcgi_apply_func load_func, zval *array); |
| 207 | + |
| 208 | +int fcgi_read(fcgi_request *req, char *str, int len); |
| 209 | + |
| 210 | +int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len); |
| 211 | +int fcgi_flush(fcgi_request *req, int close); |
| 212 | + |
| 213 | +#ifdef PHP_WIN32 |
| 214 | +void fcgi_impersonate(void); |
| 215 | +#endif |
| 216 | + |
| 217 | +void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len); |
| 218 | +void fcgi_free_mgmt_var_cb(zval *zv); |
| 219 | + |
| 220 | +/* |
| 221 | + * Local variables: |
| 222 | + * tab-width: 4 |
| 223 | + * c-basic-offset: 4 |
| 224 | + * End: |
| 225 | + * vim600: sw=4 ts=4 fdm=marker |
| 226 | + * vim<600: sw=4 ts=4 |
| 227 | + */ |
| 228 | + |
0 commit comments