UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2016 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef CGI_H 30 #define CGI_H 31 32 #include "../public/nsapi.h" 33 #include <cx/buffer.h> 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 enum CgiIOResult { 40 CGI_IO_COMPLETE = 0, 41 CGI_IO_NEED_READ, 42 CGI_IO_NEED_WRITE, 43 CGI_IO_ERROR 44 }; 45 46 typedef enum CgiIOResult CgiIOResult; 47 48 typedef struct { 49 int in[2]; 50 int out[2]; 51 int err[2]; 52 pid_t pid; 53 } CGIProcess; 54 55 typedef struct { 56 Session *sn; 57 Request *rq; 58 CxBuffer tmp; 59 int status; 60 char *msg; 61 size_t response_length; 62 WSBool cgiheader; 63 } CGIResponseParser; 64 65 typedef struct CGIHandler { 66 CGIProcess process; 67 CGIResponseParser *parser; 68 HttpResponseWriter *response; 69 70 /* 71 * request path (rq->vars path) 72 */ 73 char *path; 74 75 /* 76 * event object for pollin 77 * active by default and my be deactivated/reactivated in some cases 78 */ 79 Event *readev; 80 81 /* 82 * event object prepared for pollout 83 * only activated if write returns EWOULDBLOCK 84 */ 85 Event *writeev; 86 87 /* 88 * temp buffer used for parsing stderr lines 89 */ 90 char *stderr_tmp; 91 /* 92 * current length of stderr_tmp 93 */ 94 int stderr_tmplen; 95 96 /* 97 * allocation size of stderr_tmp 98 */ 99 int stderr_tmpalloc; 100 101 /* 102 * output buffer 103 */ 104 char *writebuf; 105 106 /* 107 * writebuf allocation size 108 */ 109 size_t writebuf_alloc; 110 111 /* 112 * currently used size of writebuf 113 */ 114 size_t writebuf_size; 115 116 /* 117 * current writebuf pos (writebuf_size - write_buf_pos = remaining) 118 */ 119 size_t writebuf_pos; 120 121 /* 122 * number of bytes of the response body sent to the client 123 * at the end count_write should have the same value as parser->response_length 124 */ 125 size_t count_write; 126 127 /* 128 * poll_out event active 129 */ 130 WSBool poll_out; 131 132 /* 133 * last read returned EWOULDBLOCK 134 * waiting for the next read event 135 */ 136 WSBool wait_read; 137 138 /* 139 * cgi pipe (stdout) EOF 140 */ 141 WSBool cgi_eof; 142 143 /* 144 * Last kill signal sent to the cgi process 145 */ 146 int cgi_kill; 147 148 WSBool debug_finished; 149 150 /* 151 * number of currently open events (stdout, stderr, [stdout]) 152 */ 153 int events; 154 155 /* 156 * error indicator 157 */ 158 int result; 159 } CGIHandler; 160 161 int send_cgi(pblock *pb, Session *sn, Request *rq); 162 163 char** cgi_add_vars(char **env, Session *sn, Request *rq); 164 165 int cgi_start(CGIProcess *p, char *path, char *const argv[], char *const envp[]); 166 167 int cgi_close(CGIProcess *p); 168 169 int cgi_stdout_readevent(EventHandler *ev, Event *event); 170 int cgi_stderr_readevent(EventHandler *ev, Event *event); 171 int cgi_event_finish(EventHandler *ev, Event *event); 172 int cgi_writeevent(EventHandler *ev, Event *event); 173 174 CgiIOResult cgi_read_output(CGIHandler *handler, EventHandler *ev, const char *debug_log); 175 176 CGIResponseParser* cgi_parser_new(Session *sn, Request *rq); 177 void cgi_parser_free(CGIResponseParser *parser); 178 int cgi_parse_response(CGIResponseParser *parser, char *buf, size_t len, size_t *bpos); 179 180 #ifdef __cplusplus 181 } 182 #endif 183 184 #endif /* CGI_H */ 185 186