1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * @file mod_isapi.h
19  * @brief ISAPI module extension to Apache
20  *
21  * @defgroup MOD_ISAPI mod_isapi
22  * @ingroup  APACHE_MODS
23  * @{
24  */
25 
26 #ifndef MOD_ISAPI_H
27 #define MOD_ISAPI_H
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 /* The Version Information storage passed to a module on startup
34  * via the GetExtensionVersion() entry point.
35  */
36 typedef struct HSE_VERSION_INFO {
37     apr_uint32_t dwExtensionVersion;
38     char         lpszExtensionDesc[256];
39 } HSE_VERSION_INFO;
40 
41 /* The startup entry point that must be exported by every ISAPI handler
42  */
43 int APR_THREAD_FUNC GetExtensionVersion(HSE_VERSION_INFO *ver_info);
44 typedef int (APR_THREAD_FUNC *PFN_GETEXTENSIONVERSION)(HSE_VERSION_INFO *ver_info);
45 
46 /* Our internal 'HCONN' representation, always opaque to the user.
47  */
48 typedef struct isapi_cid isapi_cid;
49 typedef struct isapi_cid *HCONN;
50 
51 /* Prototypes of the essential functions exposed by mod_isapi
52  * for the module to communicate with Apache.
53  */
54 typedef int (APR_THREAD_FUNC
55                 *PFN_GETSERVERVARIABLE)(HCONN         cid,
56                                         char         *variable_name,
57                                         void         *buf_data,
58                                         apr_uint32_t *buf_size);
59 typedef int (APR_THREAD_FUNC
60                 *PFN_WRITECLIENT)(HCONN         cid,
61                                   void         *buf_data,
62                                   apr_uint32_t *buf_size,
63                                   apr_uint32_t  flags);
64 typedef int (APR_THREAD_FUNC
65                 *PFN_READCLIENT)(HCONN         cid,
66                                  void         *buf_data,
67                                  apr_uint32_t *buf_size);
68 typedef int (APR_THREAD_FUNC
69                 *PFN_SERVERSUPPORTFUNCTION)(HCONN         cid,
70                                             apr_uint32_t  HSE_code,
71                                             void         *buf_data,
72                                             apr_uint32_t *buf_size,
73                                             apr_uint32_t *flags);
74 
75 /* The ecb structure is passed on each invocation of the module
76  */
77 typedef struct EXTENSION_CONTROL_BLOCK {
78     apr_uint32_t   cbSize;
79     apr_uint32_t   dwVersion;
80     HCONN          ConnID;
81     apr_uint32_t   dwHttpStatusCode;
82     char           lpszLogData[80];
83     char          *lpszMethod;
84     char          *lpszQueryString;
85     char          *lpszPathInfo;
86     char          *lpszPathTranslated;
87     apr_uint32_t   cbTotalBytes;
88     apr_uint32_t   cbAvailable;
89     unsigned char *lpbData;
90     char          *lpszContentType;
91 
92     PFN_GETSERVERVARIABLE     GetServerVariable;
93     PFN_WRITECLIENT           WriteClient;
94     PFN_READCLIENT            ReadClient;
95     PFN_SERVERSUPPORTFUNCTION ServerSupportFunction;
96 } EXTENSION_CONTROL_BLOCK;
97 
98 /* Status/Headers structure to pass to HSE_SEND_HEADER_EX,
99  * an MS extension to ServerSupportFunction
100  */
101 typedef struct HSE_SEND_HEADER_EX_INFO {
102     const char * pszStatus; /* HTTP status text, such as "200 OK" */
103     const char * pszHeader; /* HTTP header lines text, such as
104                              *   "Content-type: text/plain\r\n"
105                              *   "Content-Language: en\r\n"
106                              * Note that (in spite of cchFoo lengths below)
107                              * NULL characters will interfere in headers.
108                              */
109     apr_uint32_t cchStatus; /* length of pszStatus text */
110     apr_uint32_t cchHeader; /* length of pszHeader text */
111     int          fKeepConn; /* Ignored: used to set keep-alive status,
112                              * but Apache follows the client's negotiated
113                              * HTTP contract to decide.
114                              */
115 } HSE_SEND_HEADER_EX_INFO;
116 
117 /* Our only 'supported' MS extended flag bit for TransmitFile,
118  * HSE_IO_SEND_HEADERS indicates that Status+Headers are present
119  * in the pszStatusCode member of the HSE_TF_INFO structure.
120  */
121 #define HSE_IO_SEND_HEADERS 8
122 
123 /* The remaining flags are MS extended flag bits that bear little
124  * relation to Apache; the rules that the Apache server obeys follow
125  * its own design and HTTP protocol filter rules.
126  *
127  * We do not support async, however, we fake it.  If HSE_IO_SYNC is
128  * not passed, and a completion context was defined, we will invoke the
129  * completion function immediately following the transfer, and then
130  * return to the caller.  If HSE_IO_SYNC is passed, there is no call
131  * necessary to the completion context.
132  */
133 #define HSE_IO_SYNC  1
134 #define HSE_IO_ASYNC 2
135 #define HSE_IO_DISCONNECT_AFTER_SEND 4
136 #define HSE_IO_NODELAY 4096
137 
138 /* The Completion function prototype.  This callback may be fixed with
139  * the HSE_REQ_IO_COMPLETION ServerSupportFunction call, or overriden
140  * for the HSE_REQ_TRANSMIT_FILE call.
141  */
142 typedef void (APR_THREAD_FUNC *PFN_HSE_IO_COMPLETION)
143                                   (EXTENSION_CONTROL_BLOCK *ecb,
144                                    void                    *ctxt,
145                                    apr_uint32_t             cbIO,
146                                    apr_uint32_t             dwError);
147 
148 /* TransmitFile structure to pass to HSE_REQ_TRANSMIT_FILE, an MS extension
149  */
150 typedef struct HSE_TF_INFO {
151     PFN_HSE_IO_COMPLETION pfnHseIO;      /* Overrides the default setting of
152                                           * HSE_REQ_IO_COMPLETION if not NULL
153                                           */
154     void                 *pContext;
155     apr_os_file_t         hFile;         /* HANDLE/fd to transmit */
156     const char           *pszStatusCode; /* Ignored if HSE_IO_SEND_HEADERS is
157                                           * not set.  Includes HTTP status text
158                                           * plus header text lines, such as
159                                           *   "200 OK\r\n"
160                                           *   "Content-type: text/plain\r\n"
161                                           */
162     apr_uint32_t          BytesToWrite;  /* 0 is write-all */
163     apr_uint32_t          Offset;        /* File Offset */
164     void                 *pHead;         /* Prefix with *pHead body text */
165     apr_uint32_t          HeadLength;    /* Length of *pHead body text */
166     void                 *pTail;         /* Prefix with *pTail body text */
167     apr_uint32_t          TailLength;    /* Length of *pTail body text */
168     apr_uint32_t          dwFlags;       /* bit flags described above */
169 } HSE_TF_INFO;
170 
171 typedef struct HSE_URL_MAPEX_INFO {
172     char         lpszPath[260];
173     apr_uint32_t dwFlags;
174     apr_uint32_t cchMatchingPath;
175     apr_uint32_t cchMatchingURL;
176     apr_uint32_t dwReserved1;
177     apr_uint32_t dwReserved2;
178 } HSE_URL_MAPEX_INFO;
179 
180 /* Original ISAPI ServerSupportFunction() HSE_code methods */
181 #define HSE_REQ_SEND_URL_REDIRECT_RESP   1
182 #define HSE_REQ_SEND_URL                 2
183 #define HSE_REQ_SEND_RESPONSE_HEADER     3
184 #define HSE_REQ_DONE_WITH_SESSION        4
185 
186 /* MS Extented methods to ISAPI ServerSupportFunction() HSE_code */
187 #define HSE_REQ_MAP_URL_TO_PATH          1001 /* Emulated */
188 #define HSE_REQ_GET_SSPI_INFO            1002 /* Not Supported */
189 #define HSE_APPEND_LOG_PARAMETER         1003 /* Supported */
190 #define HSE_REQ_IO_COMPLETION            1005 /* Emulated */
191 #define HSE_REQ_TRANSMIT_FILE            1006 /* Async Emulated */
192 #define HSE_REQ_REFRESH_ISAPI_ACL        1007 /* Not Supported */
193 #define HSE_REQ_IS_KEEP_CONN             1008 /* Supported */
194 #define HSE_REQ_ASYNC_READ_CLIENT        1010 /* Emulated */
195 /*   Added with ISAPI 4.0 */
196 #define HSE_REQ_GET_IMPERSONATION_TOKEN  1011 /* Not Supported */
197 #define HSE_REQ_MAP_URL_TO_PATH_EX       1012 /* Emulated */
198 #define HSE_REQ_ABORTIVE_CLOSE           1014 /* Ignored */
199 /*   Added after ISAPI 4.0 in IIS 5.0 */
200 #define HSE_REQ_GET_CERT_INFO_EX         1015 /* Not Supported */
201 #define HSE_REQ_SEND_RESPONSE_HEADER_EX  1016 /* Supported (no nulls!) */
202 #define HSE_REQ_CLOSE_CONNECTION         1017 /* Ignored */
203 #define HSE_REQ_IS_CONNECTED             1018 /* Supported */
204 #define HSE_REQ_EXTENSION_TRIGGER        1020 /* Not Supported */
205 
206 /* The request entry point that must be exported by every ISAPI handler
207  */
208 apr_uint32_t APR_THREAD_FUNC HttpExtensionProc(EXTENSION_CONTROL_BLOCK *ecb);
209 typedef apr_uint32_t (APR_THREAD_FUNC
210                         *PFN_HTTPEXTENSIONPROC)(EXTENSION_CONTROL_BLOCK *ecb);
211 
212 /* Allowable return values from HttpExtensionProc (apparently 0 is also
213  * accepted by MS IIS, and we will respect it as Success.)
214  * If the HttpExtensionProc returns HSE_STATUS_PENDING, we will create
215  * a wait mutex and lock on it, until HSE_REQ_DONE_WITH_SESSION is called.
216  */
217 #define HSE_STATUS_SUCCESS                1
218 #define HSE_STATUS_SUCCESS_AND_KEEP_CONN  2 /* 1 vs 2 Ignored, we choose */
219 #define HSE_STATUS_PENDING                3 /* Emulated (thread lock) */
220 #define HSE_STATUS_ERROR                  4
221 
222 /* Anticipated error code for common faults within mod_isapi itself
223  */
224 #ifndef ERROR_INSUFFICIENT_BUFFER
225 #define ERROR_INSUFFICIENT_BUFFER ENOBUFS
226 #endif
227 #ifndef ERROR_INVALID_INDEX
228 #define ERROR_INVALID_INDEX EINVAL
229 #endif
230 #ifndef ERROR_INVALID_PARAMETER
231 #define ERROR_INVALID_PARAMETER EINVAL
232 #endif
233 #ifndef ERROR_READ_FAULT
234 #define ERROR_READ_FAULT EIO
235 #endif
236 #ifndef ERROR_WRITE_FAULT
237 #define ERROR_WRITE_FAULT EIO
238 #endif
239 #ifndef ERROR_SUCCESS
240 #define ERROR_SUCCESS 0
241 #endif
242 
243 /* Valid flags passed with TerminateExtension()
244  */
245 #define HSE_TERM_MUST_UNLOAD      1
246 #define HSE_TERM_ADVISORY_UNLOAD  2
247 
248 /* The shutdown entry point optionally exported by an ISAPI handler, passed
249  * HSE_TERM_MUST_UNLOAD or HSE_TERM_ADVISORY_UNLOAD.  The module may return
250  * if passed HSE_TERM_ADVISORY_UNLOAD, and the module will remain loaded.
251  * If the module returns 1 to HSE_TERM_ADVISORY_UNLOAD it is immediately
252  * unloaded.  If the module is passed HSE_TERM_MUST_UNLOAD, its return value
253  * is ignored.
254  */
255 int APR_THREAD_FUNC TerminateExtension(apr_uint32_t flags);
256 typedef int (APR_THREAD_FUNC *PFN_TERMINATEEXTENSION)(apr_uint32_t flags);
257 
258 /* Module may return 0 if passed HSE_TERM_ADVISORY_UNLOAD, and the module
259  * will remain loaded, or 1 if it consents to being unloaded. If the module
260  * is passed HSE_TERM_MUST_UNLOAD, its return value is ignored.
261  */
262 #define HSE_TERM_MUST_UNLOAD      1
263 #define HSE_TERM_ADVISORY_UNLOAD  2
264 
265 #ifdef __cplusplus
266 }
267 #endif
268 
269 #endif  /* !MOD_ISAPI_H */
270 /** @} */
271 
272