Annotation of embedaddon/php/sapi/webjames/webjames.c, revision 1.1.1.3
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.3 ! misho 5: | Copyright (c) 1997-2014 The PHP Group |
1.1 misho 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: | license@php.net so we can mail you a copy immediately. |
14: +----------------------------------------------------------------------+
15: | Author: Alex Waugh <alex@alexwaugh.com> |
16: +----------------------------------------------------------------------+
17: */
18:
19:
20: #include "php.h"
21: #include "SAPI.h"
22: #include "php_main.h"
23: #include "php_variables.h"
24:
25: #define WEBJAMES_PHP_ONLY
26: #include "php_webjames.h"
27:
28: #include <unixlib/local.h>
29:
30: #define WEBJAMES_SAPI_VERSION "1.0.2"
31:
32: typedef struct {
33: struct connection *conn; /*structure holding all the details of the current request*/
34: int bodyread; /*amount of POST body read*/
35: closefn oldclose; /*function to call to close the connection*/
36: } php_webjames_globals;
37:
38: static php_webjames_globals webjames_globals;
39:
40: #define WG(v) (webjames_globals.v)
41:
42: static int sapi_webjames_ub_write(const char *str, uint str_length TSRMLS_DC)
43: /*unbuffered write - send data straight out to socket*/
44: {
45: int totalbytes = 0;
46:
47: do {
48: int bytes;
49: bytes = webjames_writebuffer(WG(conn),str,str_length);
50: if (bytes<0) {
51: PG(connection_status) = PHP_CONNECTION_ABORTED;
52: if (!PG(ignore_user_abort)) {
53: zend_bailout();
54: }
55: return bytes;
56: }
57: str += bytes;
58: str_length -= bytes;
59: totalbytes += bytes;
60: } while (str_length);
61: return totalbytes;
62: }
63:
64: static void sapi_webjames_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC)
65: /*send an HTTP header*/
66: {
67: char *header = sapi_header->header;
68: int len = sapi_header->header_len;
69: if (WG(conn)->flags.outputheaders) {
70: while (sapi_header && len > 0) {
71: int bytes;
72: bytes = webjames_writebuffer(WG(conn), header, len);
73: if (bytes<0) {
74: PG(connection_status) = PHP_CONNECTION_ABORTED;
75: if (!PG(ignore_user_abort)) {
76: zend_bailout();
77: }
78: return;
79: }
80: header += bytes;
81: len -= bytes;
82: }
83: webjames_writestring(WG(conn), "\r\n");
84: }
85: }
86:
87: static int sapi_webjames_read_post(char *buffer, uint count_bytes TSRMLS_DC)
88: /*read some of the post data*/
89: {
90: if (WG(conn)->body==NULL) return 0;
91: if (count_bytes+WG(bodyread)>WG(conn)->bodysize) count_bytes=WG(conn)->bodysize-WG(bodyread);
92: memcpy(buffer, WG(conn)->body+WG(bodyread), count_bytes);
93: WG(bodyread)+=count_bytes;
94: return count_bytes;
95: }
96:
97: static char *sapi_webjames_read_cookies(TSRMLS_D)
98: {
99: return WG(conn)->cookie;
100: }
101:
102: #define BUF_SIZE 512
103: #define ADD_STRING(name,string)\
104: php_register_variable(name, string, track_vars_array TSRMLS_CC)
105:
106: #define ADD_NUM(name,field) {\
107: snprintf(buf, BUF_SIZE, "%d", WG(conn)->field);\
108: php_register_variable(name, buf, track_vars_array TSRMLS_CC);\
109: }
110:
111: #define ADD_FIELD(name, field) \
112: if (WG(conn)->field) { \
113: php_register_variable(name, WG(conn)->field, track_vars_array TSRMLS_CC); \
114: }
115:
116: static void sapi_webjames_register_variables(zval *track_vars_array TSRMLS_DC)
117: {
118: char buf[BUF_SIZE + 1];
119: char *docroot;
120:
121: buf[BUF_SIZE] = '\0';
122:
123: ADD_STRING("SERVER_SOFTWARE", configuration.server);
124: ADD_STRING("SERVER_NAME", configuration.serverip);
125: ADD_FIELD("SERVER_PROTOCOL", protocol);
126: ADD_NUM("SERVER_PORT", port);
127: ADD_STRING("SERVER_ADMIN",configuration.webmaster);
128: ADD_STRING("GATEWAY_INTERFACE", "CGI/1.1");
129:
130: docroot = __unixify(WG(conn)->homedir,0,NULL,1024,0);
131: if (docroot) ADD_STRING("DOCUMENT_ROOT", docroot);
132:
133: ADD_FIELD("REQUEST_METHOD", methodstr);
134: ADD_FIELD("REQUEST_URI", requesturi);
135: ADD_STRING("PATH_TRANSLATED", SG(request_info).path_translated);
136: ADD_FIELD("SCRIPT_NAME", uri);
137: ADD_FIELD("PHP_SELF", uri);
138: ADD_FIELD("QUERY_STRING", args);
139:
140:
141: snprintf(buf, BUF_SIZE, "%d.%d.%d.%d", WG(conn)->ipaddr[0], WG(conn)->ipaddr[1], WG(conn)->ipaddr[2], WG(conn)->ipaddr[3]);
142: ADD_STRING("REMOTE_ADDR", buf);
143: if (WG(conn)->dnsstatus == DNS_OK) ADD_FIELD("REMOTE_HOST", host);
144:
145: if ((WG(conn)->method == METHOD_POST) || (WG(conn)->method == METHOD_PUT)) {
146: ADD_NUM("CONTENT_LENGTH", bodysize);
147: ADD_FIELD("CONTENT_TYPE", type);
148: }
149:
150: if ((WG(conn)->method == METHOD_PUT) || (WG(conn)->method == METHOD_DELETE)) ADD_FIELD("ENTITY_PATH", requesturi);
151:
152: if (WG(conn)->pwd) {
153: ADD_STRING("AUTH_TYPE", "basic");
154: ADD_FIELD("REMOTE_USER", authorization);
155: }
156:
157: ADD_FIELD("HTTP_COOKIE", cookie);
158: ADD_FIELD("HTTP_USER_AGENT", useragent);
159: ADD_FIELD("HTTP_REFERER", referer);
160: ADD_FIELD("HTTP_ACCEPT", accept);
161: ADD_FIELD("HTTP_ACCEPT_LANGUAGE", acceptlanguage);
162: ADD_FIELD("HTTP_ACCEPT_CHARSET", acceptcharset);
163: ADD_FIELD("HTTP_ACCEPT_ENCODING", acceptencoding);
164: }
165:
166: static void webjames_module_main(TSRMLS_D)
167: {
168: zend_file_handle file_handle;
169: FILE *fp=NULL;
170: char *path;
171:
172: /* Convert filename to Unix format*/
173: __riscosify_control|=__RISCOSIFY_STRICT_UNIX_SPECS;
174: path = __unixify(WG(conn)->filename,0,NULL,1024,0);
175: if (path) SG(request_info).path_translated = estrdup(path);
176:
177: SG(request_info).query_string = WG(conn)->args;
178: SG(request_info).request_uri = WG(conn)->requesturi;
179: SG(request_info).request_method = WG(conn)->methodstr;
180: if (WG(conn)->method==METHOD_HEAD) {
181: SG(request_info).headers_only = 1;
182: } else {
183: SG(request_info).headers_only = 0;
184: }
185: SG(sapi_headers).http_response_code = 200;
186: SG(request_info).content_type = WG(conn)->type;
187: SG(request_info).content_length = WG(conn)->bodysize;
188:
189: SG(request_info).auth_user = NULL;
190: SG(request_info).auth_password = NULL;
191: if (WG(conn)->authorization) {
192: char *colon=strchr(WG(conn)->authorization,':');
193: if (colon) {
194: SG(request_info).auth_user = emalloc(colon-WG(conn)->authorization+1);
195: if (SG(request_info).auth_user) {
196: memcpy(SG(request_info).auth_user,WG(conn)->authorization,colon-WG(conn)->authorization);
197: SG(request_info).auth_user[colon-WG(conn)->authorization]='\0';
198: SG(request_info).auth_password = estrdup(colon+1);
199: }
200: }
201: }
202:
203: /*ensure that syslog calls get logged separately from WebJames' main log */
204: openlog("PHP",0,0);
205:
206: file_handle.type = ZEND_HANDLE_FILENAME;
207: file_handle.filename = SG(request_info).path_translated;
208: file_handle.free_filename = 0;
209: file_handle.opened_path = NULL;
210:
211: if (php_request_startup(TSRMLS_C) == FAILURE) {
212: return;
213: }
214:
215: php_execute_script(&file_handle TSRMLS_CC);
216: php_request_shutdown(NULL);
217: }
218:
219: static void webjames_php_close(struct connection *conn, int force)
220: /*called by webjames if it wants to close the connection*/
221: {
222: TSRMLS_FETCH();
223:
224: php_request_shutdown(NULL);
225: WG(oldclose)(conn,force);
226: }
227:
228: void webjames_php_request(struct connection *conn)
229: /*called by WebJames to start handler*/
230: {
231: TSRMLS_FETCH();
232:
233: WG(conn) = conn;
234: WG(bodyread) = 0;
235: WG(oldclose) = conn->close;
236: conn->close=webjames_php_close;
237:
238: webjames_module_main(TSRMLS_C);
239:
240: WG(oldclose)(WG(conn), 0);
241: }
242:
243: static void php_info_webjames(ZEND_MODULE_INFO_FUNC_ARGS)
244: {
245: php_info_print_table_start();
246: php_info_print_table_row(2, "SAPI module version", WEBJAMES_SAPI_VERSION);
247: php_info_print_table_row(2, "WebJames version", WEBJAMES_VERSION " (" WEBJAMES_DATE ")");
248: php_info_print_table_end();
249: }
250:
251: static zend_module_entry php_webjames_module = {
252: #if ZEND_MODULE_API_NO >= 20010901
253: STANDARD_MODULE_HEADER,
254: #endif
255: "WebJames",
256: NULL,
257: NULL,
258: NULL,
259: NULL,
260: NULL,
261: php_info_webjames,
262: #if ZEND_MODULE_API_NO >= 20010901
263: WEBJAMES_SAPI_VERSION,
264: #endif
265: STANDARD_MODULE_PROPERTIES
266: };
267:
268:
269: static int php_webjames_startup(sapi_module_struct *sapi_module)
270: {
271: if(php_module_startup(sapi_module, &php_webjames_module, 1) == FAILURE) {
272: return FAILURE;
273: } else {
274: return SUCCESS;
275: }
276: }
277:
278: static sapi_module_struct sapi_module = {
279: "webjames", /* name */
280: "WebJames", /* pretty name */
281:
282: php_webjames_startup, /* startup */
283: php_module_shutdown_wrapper, /* shutdown */
284:
285: NULL, /* activate */
286: NULL, /* deactivate */
287:
288: sapi_webjames_ub_write, /* unbuffered write */
289: NULL, /* flush */
290: NULL, /* get uid */
291: NULL, /* getenv */
292:
293: php_error, /* error handler */
294:
295: NULL, /* header handler */
296: NULL, /* send headers handler */
297: sapi_webjames_send_header, /* send header handler */
298: sapi_webjames_read_post, /* read POST data */
299: sapi_webjames_read_cookies, /* read Cookies */
300:
301: sapi_webjames_register_variables, /* register server variables */
302: NULL, /* Log message */
303: NULL, /* Get request time */
304: NULL, /* Child terminate */
305:
306: STANDARD_SAPI_MODULE_PROPERTIES
307: };
308:
309: int webjames_php_init(void)
310: /*called when WebJames initialises*/
311: {
312: TSRMLS_FETCH();
313: if (strcmp(configuration.webjames_h_revision,WEBJAMES_H_REVISION)!=0) {
314: /*This file was compiled against a different revision of
315: webjames.h than webjames was, which could be bad news*/
316: webjames_writelog(0,"PHP module is compiled for WebJames (%s) and was linked with a different version (%s)",WEBJAMES_H_REVISION,configuration.webjames_h_revision);
317: return 0; /*failed to initialise*/
318: }
319: sapi_startup(&sapi_module);
320: sapi_module.startup(&sapi_module);
321: SG(server_context) = (void *) 1;
322: return 1; /*initialised correctly*/
323: }
324:
325: void webjames_php_shutdown(void)
326: /*called when WebJames is about to quit*/
327: {
328: sapi_module.shutdown(&sapi_module);
329: sapi_shutdown();
330: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>