mod_isapi.c revision d4f351074a8f7af5e41aa0a70410816436608e3d
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny/* ====================================================================
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * The Apache Software License, Version 1.1
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * reserved.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * Redistribution and use in source and binary forms, with or without
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * modification, are permitted provided that the following conditions
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * are met:
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * 1. Redistributions of source code must retain the above copyright
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * notice, this list of conditions and the following disclaimer.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * 2. Redistributions in binary form must reproduce the above copyright
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * notice, this list of conditions and the following disclaimer in
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * the documentation and/or other materials provided with the
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * distribution.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * 3. The end-user documentation included with the redistribution,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * if any, must include the following acknowledgment:
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * "This product includes software developed by the
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * Apache Software Foundation (http://www.apache.org/)."
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * Alternately, this acknowledgment may appear in the software itself,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * if and wherever such third-party acknowledgments normally appear.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * 4. The names "Apache" and "Apache Software Foundation" must
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * not be used to endorse or promote products derived from this
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * software without prior written permission. For written
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * permission, please contact apache@apache.org.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * 5. Products derived from this software may not be called "Apache",
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * nor may "Apache" appear in their name, without prior written
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * permission of the Apache Software Foundation.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * SUCH DAMAGE.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * ====================================================================
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * This software consists of voluntary contributions made by many
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * individuals on behalf of the Apache Software Foundation. For more
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * information on the Apache Software Foundation, please see
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * <http://www.apache.org/>.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * Portions of this software are based upon public domain software
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * originally written at the National Center for Supercomputing Applications,
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * University of Illinois, Urbana-Champaign.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek */
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek/*
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * mod_isapi.c - Internet Server Application (ISA) module for Apache
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * by Alexei Kosut <akosut@apache.org>
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * This module implements Microsoft's ISAPI, allowing Apache (when running
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * under Windows) to load Internet Server Applications (ISAPI extensions).
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * It implements all of the ISAPI 2.0 specification, except for the
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * "Microsoft-only" extensions dealing with asynchronous I/O. All ISAPI
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * extensions that use only synchronous I/O and are compatible with the
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * ISAPI 2.0 specification should work (most ISAPI 1.0 extensions should
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * function as well).
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * To load, simply place the ISA in a location in the document tree.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * Then add an "AddHandler isapi-isa dll" into your config file.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * You should now be able to load ISAPI DLLs just be reffering to their
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * URLs. Make sure the ExecCGI option is active in the directory
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * the ISA is in.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek */
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "apr_strings.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "apr_portable.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "apr_buckets.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "ap_config.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "httpd.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "http_config.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "http_core.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "http_protocol.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "http_request.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "http_log.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "util_script.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "mod_core.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek/* We use the exact same header file as the original */
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include <HttpExt.h>
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#if !defined(HSE_REQ_MAP_URL_TO_PATH_EX) \
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek || !defined(HSE_REQ_SEND_RESPONSE_HEADER_EX)
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#pragma message("WARNING: This build of Apache is missing the recent changes")
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#pragma message("in the Microsoft Win32 Platform SDK; some mod_isapi features")
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#pragma message("will be disabled. To obtain the latest Platform SDK files,")
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#pragma message("please refer to:")
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#pragma message("http://msdn.microsoft.com/downloads/sdks/platform/platform.asp")
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#endif
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek/* TODO: Unknown errors that must be researched for correct codes */
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#define TODO_ERROR 1
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek/* Seems IIS does not enforce the requirement for \r\n termination on HSE_REQ_SEND_RESPONSE_HEADER,
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek define this to conform */
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#define RELAX_HEADER_RULE
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozekmodule isapi_module;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek/* Declare the ISAPI functions */
b5825c74b6bf7a99ae2172392dbecb51179013a6Jakub Hrozek
b5825c74b6bf7a99ae2172392dbecb51179013a6Jakub HrozekBOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer);
50936fc7230a9b3f01e285e72c4182013542f53eJakub HrozekBOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek DWORD dwReserved);
50936fc7230a9b3f01e285e72c4182013542f53eJakub HrozekBOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize);
50936fc7230a9b3f01e285e72c4182013542f53eJakub HrozekBOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek LPVOID lpvBuffer, LPDWORD lpdwSize,
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek LPDWORD lpdwDataType);
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek/*
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek The optimiser blows it totally here. What happens is that autos are addressed relative to the
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek stack pointer, which, of course, moves around. The optimiser seems to lose track of it somewhere
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek between setting HttpExtensionProc's address and calling through it. We work around the problem by
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek forcing it to use frame pointers.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek The revisions below may eliminate this artifact.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek*/
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#pragma optimize("y",off)
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek/* Our isapi server config structure */
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozektypedef struct {
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek HANDLE lock;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek apr_array_header_t *loaded;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek DWORD ReadAheadBuffer;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek int LogNotSupported;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek int AppendLogToErrors;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek int AppendLogToQuery;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek} isapi_server_conf;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek/* Our loaded isapi module description structure */
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozektypedef struct {
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek const char *filename;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek apr_dso_handle_t *handle;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek HSE_VERSION_INFO *pVer;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek PFN_GETEXTENSIONVERSION GetExtensionVersion;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek PFN_HTTPEXTENSIONPROC HttpExtensionProc;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek PFN_TERMINATEEXTENSION TerminateExtension;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek int refcount;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek DWORD timeout;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek BOOL fakeasync;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek DWORD reportversion;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek} isapi_loaded;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek/* Our "Connection ID" structure */
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozektypedef struct {
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek LPEXTENSION_CONTROL_BLOCK ecb;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek isapi_server_conf *sconf;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek isapi_loaded *isa;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek request_rec *r;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek PFN_HSE_IO_COMPLETION completion;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek PVOID completion_arg;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek HANDLE complete;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek} isapi_cid;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozekstatic BOOL isapi_unload(isapi_loaded* isa, int force);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozekstatic apr_status_t cleanup_isapi_server_config(void *sconfv)
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek{
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek isapi_server_conf *sconf = sconfv;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek size_t n;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek isapi_loaded **isa;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek n = sconf->loaded->nelts;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek isa = (isapi_loaded **)sconf->loaded->elts;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek while(n--) {
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek if ((*isa)->handle)
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek isapi_unload(*isa, TRUE);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek ++isa;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek }
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek CloseHandle(sconf->lock);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek return APR_SUCCESS;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek}
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozekstatic void *create_isapi_server_config(apr_pool_t *p, server_rec *s)
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek{
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek isapi_server_conf *sconf = apr_palloc(p, sizeof(isapi_server_conf));
f191a6f9f3313df88eaf3debf52eebfe5d3dee59Michal Židek sconf->loaded = apr_array_make(p, 20, sizeof(isapi_loaded*));
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek sconf->lock = CreateMutex(NULL, FALSE, NULL);
877b92e80bde510d5cd9f03dbf01e2bcf73ab072Michal Židek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek sconf->ReadAheadBuffer = 49152;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek sconf->LogNotSupported = -1;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek sconf->AppendLogToErrors = 0;
877b92e80bde510d5cd9f03dbf01e2bcf73ab072Michal Židek sconf->AppendLogToQuery = 0;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_pool_cleanup_register(p, sconf, cleanup_isapi_server_config,
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_pool_cleanup_null);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek return sconf;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek}
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozekstatic int compare_loaded(const void *av, const void *bv)
877b92e80bde510d5cd9f03dbf01e2bcf73ab072Michal Židek{
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek const isapi_loaded **a = av;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek const isapi_loaded **b = bv;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek return strcmp((*a)->filename, (*b)->filename);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek}
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozekstatic void isapi_post_config(apr_pool_t *p, apr_pool_t *plog,
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_pool_t *ptemp, server_rec *s)
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek{
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek isapi_server_conf *sconf = ap_get_module_config(s->module_config,
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek &isapi_module);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek isapi_loaded **elts = (isapi_loaded **)sconf->loaded->elts;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek int nelts = sconf->loaded->nelts;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek /* sort the elements of the main_server, by filename */
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek qsort(elts, nelts, sizeof(isapi_loaded*), compare_loaded);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny /* and make the virtualhosts share the same thing */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny for (s = s->next; s; s = s->next) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny ap_set_module_config(s->module_config, &isapi_module, sconf);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny}
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorcestatic apr_status_t isapi_load(apr_pool_t *p, isapi_server_conf *sconf,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny request_rec *r, const char *fpath,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny isapi_loaded** isa)
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose{
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek isapi_loaded **found = (isapi_loaded **)sconf->loaded->elts;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose apr_status_t rv;
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek int n;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce for (n = 0; n < sconf->loaded->nelts; ++n) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (strcasecmp(fpath, (*found)->filename) == 0) {
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose break;
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose }
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose ++found;
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose }
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose if (n < sconf->loaded->nelts)
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek {
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek *isa = *found;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if ((*isa)->handle)
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny ++(*isa)->refcount;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny return APR_SUCCESS;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny /* Otherwise we fall through and have to reload the resource
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * into this existing mod_isapi cache bucket.
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny else
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *isa = apr_pcalloc(p, sizeof(isapi_module));
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce (*isa)->filename = fpath;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny (*isa)->pVer = apr_pcalloc(p, sizeof(HSE_VERSION_INFO));
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny /* TODO: These need to become overrideable, so that we
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * assure a given isapi can be fooled into behaving well.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny (*isa)->timeout = INFINITE; /* microsecs */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny (*isa)->fakeasync = TRUE;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce (*isa)->reportversion = MAKELONG(0, 5); /* Revision 5.0 */
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
b5825c74b6bf7a99ae2172392dbecb51179013a6Jakub Hrozek rv = apr_dso_load(&(*isa)->handle, fpath, p);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if (rv)
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce "ISAPI %s failed to load", fpath);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny (*isa)->handle = NULL;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny return rv;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce rv = apr_dso_sym((void**)&(*isa)->GetExtensionVersion, (*isa)->handle,
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce "GetExtensionVersion");
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce if (rv)
7fe69bb6ec70bce439c6b975a9a0044c98ff502bSimo Sorce {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "ISAPI %s is missing GetExtensionVersion()",
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny fpath);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_dso_unload((*isa)->handle);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny (*isa)->handle = NULL;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny return rv;
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce }
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny rv = apr_dso_sym((void**)&(*isa)->HttpExtensionProc, (*isa)->handle,
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce "HttpExtensionProc");
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce if (rv)
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce {
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce "ISAPI %s is missing HttpExtensionProc()",
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny fpath);
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose apr_dso_unload((*isa)->handle);
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose (*isa)->handle = NULL;
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose return rv;
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek }
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek /* TerminateExtension() is an optional interface */
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose rv = apr_dso_sym((void**)&(*isa)->TerminateExtension, (*isa)->handle,
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose "TerminateExtension");
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose SetLastError(0);
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek /* Run GetExtensionVersion() */
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek if (!((*isa)->GetExtensionVersion)((*isa)->pVer)) {
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek apr_status_t rv = apr_get_os_error();
2bbc9d6f8d5f2c1b07fd6968314b7f530b7f3a4dMichal Židek ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
2bbc9d6f8d5f2c1b07fd6968314b7f530b7f3a4dMichal Židek "ISAPI %s call GetExtensionVersion() failed",
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce fpath);
b5825c74b6bf7a99ae2172392dbecb51179013a6Jakub Hrozek apr_dso_unload((*isa)->handle);
b5825c74b6bf7a99ae2172392dbecb51179013a6Jakub Hrozek (*isa)->handle = NULL;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce return rv;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ++(*isa)->refcount;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce return APR_SUCCESS;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce}
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorcestatic int isapi_unload(isapi_loaded* isa, int force)
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce{
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce /* All done with the DLL... get rid of it...
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce *
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce * If optionally cached, pass HSE_TERM_ADVISORY_UNLOAD,
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce * and if it returns TRUE, unload, otherwise, cache it.
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov if ((--isa->refcount > 0) && !force)
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce return FALSE;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if (isa->TerminateExtension) {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if (force)
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce (*isa->TerminateExtension)(HSE_TERM_MUST_UNLOAD);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce else if (!(*isa->TerminateExtension)(HSE_TERM_ADVISORY_UNLOAD))
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce return FALSE;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_dso_unload(isa->handle);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce isa->handle = NULL;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov return TRUE;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov}
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorceapr_status_t isapi_handler (request_rec *r)
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce{
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce isapi_server_conf * sconf;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_table_t *e;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_status_t rv;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce isapi_loaded *isa;
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose isapi_cid *cid;
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose const char *val;
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose DWORD read;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov int res;
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov if(strcmp(r->handler, "isapi-isa"))
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose return DECLINED;
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose sconf = ap_get_module_config(r->server->module_config, &isapi_module);
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek e = r->subprocess_env;
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek /* Use similar restrictions as CGIs
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek *
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov * If this fails, it's pointless to load the isapi dll.
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek */
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek if (!(ap_allow_options(r) & OPT_EXECCGI))
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek return HTTP_FORBIDDEN;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose if (r->finfo.filetype == APR_NOFILE)
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose return HTTP_NOT_FOUND;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov if (r->finfo.filetype != APR_REG)
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov return HTTP_FORBIDDEN;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose /* Load the isapi extention without caching (sconf == NULL)
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose * but note that we will recover an existing cached module.
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose */
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose if (isapi_load(r->pool, sconf, r, r->filename, &isa) != APR_SUCCESS)
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose return HTTP_INTERNAL_SERVER_ERROR;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose /* Set up variables */
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose ap_add_common_vars(r);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose ap_add_cgi_vars(r);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose apr_table_setn(e, "UNMAPPED_REMOTE_USER", "REMOTE_USER");
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if ((val = apr_table_get(e, "HTTPS")) && strcmp(val, "on"))
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose apr_table_setn(e, "SERVER_PORT_SECURE", "1");
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose else
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose apr_table_setn(e, "SERVER_PORT_SECURE", "0");
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose apr_table_setn(e, "URL", r->uri);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose /* Set up connection structure and ecb */
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid = apr_pcalloc(r->pool, sizeof(isapi_cid));
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->sconf = ap_get_module_config(r->server->module_config, &isapi_module);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->ecb = apr_pcalloc(r->pool, sizeof(struct _EXTENSION_CONTROL_BLOCK));
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->ecb->ConnID = (HCONN)cid;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->isa = isa;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->r = r;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->r->status = 0;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->complete = NULL;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->completion = NULL;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->ecb->cbSize = sizeof(EXTENSION_CONTROL_BLOCK);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->ecb->dwVersion = isa->reportversion;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->ecb->dwHttpStatusCode = 0;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose strcpy(cid->ecb->lpszLogData, "");
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose // TODO: are copies really needed here?
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->ecb->lpszMethod = apr_pstrdup(r->pool, (char*) r->method);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->ecb->lpszQueryString = apr_pstrdup(r->pool,
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose (char*) apr_table_get(e, "QUERY_STRING"));
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek cid->ecb->lpszPathInfo = apr_pstrdup(r->pool,
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek (char*) apr_table_get(e, "PATH_INFO"));
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek cid->ecb->lpszPathTranslated = apr_pstrdup(r->pool,
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek (char*) apr_table_get(e, "PATH_TRANSLATED"));
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek cid->ecb->lpszContentType = apr_pstrdup(r->pool,
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek (char*) apr_table_get(e, "CONTENT_TYPE"));
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek /* Set up the callbacks */
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce cid->ecb->GetServerVariable = GetServerVariable;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce cid->ecb->WriteClient = WriteClient;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce cid->ecb->ReadClient = ReadClient;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce cid->ecb->ServerSupportFunction = ServerSupportFunction;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek /* Set up client input */
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek res = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if (res) {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce isapi_unload(isa, FALSE);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce return res;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (ap_should_client_block(r)) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny /* Time to start reading the appropriate amount of data,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * and allow the administrator to tweak the number
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek * TODO: add the httpd.conf option for ReadAheadBuffer.
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (r->remaining) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny cid->ecb->cbTotalBytes = (apr_size_t)r->remaining;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (cid->ecb->cbTotalBytes > cid->sconf->ReadAheadBuffer)
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny cid->ecb->cbAvailable = cid->sconf->ReadAheadBuffer;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny else
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny cid->ecb->cbAvailable = cid->ecb->cbTotalBytes;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce else
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny cid->ecb->cbTotalBytes = 0xffffffff;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny cid->ecb->cbAvailable = cid->sconf->ReadAheadBuffer;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny cid->ecb->lpbData = apr_pcalloc(r->pool, cid->ecb->cbAvailable + 1);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce read = 0;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny while (read < cid->ecb->cbAvailable &&
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ((res = ap_get_client_block(r, cid->ecb->lpbData + read,
17195241500e46272018d7897d6e87249870caf2Pavel Reichl cid->ecb->cbAvailable - read)) > 0)) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny read += res;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (res < 0) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny isapi_unload(isa, FALSE);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny return HTTP_INTERNAL_SERVER_ERROR;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce /* Although it's not to spec, IIS seems to null-terminate
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce * its lpdData string. So we will too.
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny */
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (res == 0)
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny cid->ecb->cbAvailable = cid->ecb->cbTotalBytes = read;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny else
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce cid->ecb->cbAvailable = read;
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce cid->ecb->lpbData[read] = '\0';
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny else {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny cid->ecb->cbTotalBytes = 0;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny cid->ecb->cbAvailable = 0;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny cid->ecb->lpbData = NULL;
cb388d52f49f54963379cc20a25e14d17fe6e9a3Simo Sorce }
cb388d52f49f54963379cc20a25e14d17fe6e9a3Simo Sorce
cb388d52f49f54963379cc20a25e14d17fe6e9a3Simo Sorce /* All right... try and run the sucker */
cb388d52f49f54963379cc20a25e14d17fe6e9a3Simo Sorce rv = (*isa->HttpExtensionProc)(cid->ecb);
cb388d52f49f54963379cc20a25e14d17fe6e9a3Simo Sorce
cb388d52f49f54963379cc20a25e14d17fe6e9a3Simo Sorce /* Check for a log message - and log it */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov if (cid->ecb->lpszLogData && *cid->ecb->lpszLogData)
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny "ISAPI %s: %s", r->filename, cid->ecb->lpszLogData);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny switch(rv) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny case 0: /* Strange, but MS isapi accepts this as success */
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce case HSE_STATUS_SUCCESS:
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce case HSE_STATUS_SUCCESS_AND_KEEP_CONN:
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce /* Ignore the keepalive stuff; Apache handles it just fine without
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce * the ISA's "advice".
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce * Per Microsoft: "In IIS versions 4.0 and later, the return
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce * values HSE_STATUS_SUCCESS and HSE_STATUS_SUCCESS_AND_KEEP_CONN
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce * are functionally identical: Keep-Alive connections are
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce * maintained, if supported by the client."
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce * ... so we were pat all this time
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce */
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce break;
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny case HSE_STATUS_PENDING:
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny /* emulating async behavior...
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce *
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce * Create a cid->completed event and wait on it for some timeout
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce * so that the app thinks is it running async.
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce *
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce * All async ServerSupportFunction calls will be handled through
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce * the registered IO_COMPLETION hook.
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny */
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (!isa->fakeasync) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (cid->sconf->LogNotSupported)
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny "ISAPI %s asynch I/O request refused",
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce r->filename);
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce cid->r->status = HTTP_INTERNAL_SERVER_ERROR;
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce }
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce }
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce else {
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce cid->complete = CreateEvent(NULL, FALSE, FALSE, NULL);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (WaitForSingleObject(cid->complete, isa->timeout)
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny == WAIT_TIMEOUT) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny /* TODO: Now what... if this hung, then do we kill our own
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny * thread to force its death? For now leave timeout = -1
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny */
17195241500e46272018d7897d6e87249870caf2Pavel Reichl }
17195241500e46272018d7897d6e87249870caf2Pavel Reichl }
17195241500e46272018d7897d6e87249870caf2Pavel Reichl break;
17195241500e46272018d7897d6e87249870caf2Pavel Reichl
17195241500e46272018d7897d6e87249870caf2Pavel Reichl case HSE_STATUS_ERROR:
17195241500e46272018d7897d6e87249870caf2Pavel Reichl /* end response if we have yet to do so.
17195241500e46272018d7897d6e87249870caf2Pavel Reichl */
17195241500e46272018d7897d6e87249870caf2Pavel Reichl cid->r->status = HTTP_INTERNAL_SERVER_ERROR;
17195241500e46272018d7897d6e87249870caf2Pavel Reichl break;
17195241500e46272018d7897d6e87249870caf2Pavel Reichl
17195241500e46272018d7897d6e87249870caf2Pavel Reichl default:
17195241500e46272018d7897d6e87249870caf2Pavel Reichl /* TODO: log unrecognized retval for debugging
17195241500e46272018d7897d6e87249870caf2Pavel Reichl */
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->r->status = HTTP_INTERNAL_SERVER_ERROR;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose break;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose /* Set the status (for logging) */
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (cid->ecb->dwHttpStatusCode) {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cid->r->status = cid->ecb->dwHttpStatusCode;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose /* All done with the DLL... get rid of it... */
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose isapi_unload(isa, FALSE);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose return OK; /* NOT r->status, even if it has changed. */
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose}
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose#pragma optimize("",on)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit BoseBOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,
9ac2a33f4cdc4941fa63118dcffe8058854f33c4Michal Židek LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose{
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose request_rec *r = ((isapi_cid *)hConn)->r;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose const char *result;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose DWORD len;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (!strcmp(lpszVariableName, "ALL_HTTP"))
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose /* lf delimited, colon split, comma seperated and
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose * null terminated list of HTTP_ vars
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose */
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose const char * const *env = (const char* const *) apr_table_elts(r->subprocess_env)->elts;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose int nelts = 2 * apr_table_elts(r->subprocess_env)->nelts;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose int i;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose for (len = 0, i = 0; i < nelts; i += 2)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (!strncmp(env[i], "HTTP_", 5))
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose len += strlen(env[i]) + strlen(env[i + 1]) + 2;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (*lpdwSizeofBuffer < len + 1) {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose *lpdwSizeofBuffer = len + 1;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose SetLastError(ERROR_INSUFFICIENT_BUFFER);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose return FALSE;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose for (i = 0; i < nelts; i += 2)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (!strncmp(env[i], "HTTP_", 5)) {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose strcpy(lpvBuffer, env[i]);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose ((char*)lpvBuffer) += strlen(env[i]);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose *(((char*)lpvBuffer)++) = ':';
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose strcpy(lpvBuffer, env[i + 1]);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose ((char*)lpvBuffer) += strlen(env[i + 1]);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose *(((char*)lpvBuffer)++) = '\n';
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose *(((char*)lpvBuffer)++) = '\0';
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose *lpdwSizeofBuffer = len;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose return TRUE;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (!strcmp(lpszVariableName, "ALL_RAW"))
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose /* lf delimited, colon split, comma seperated and
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose * null terminated list of the raw request header
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose */
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose const char * const *raw = (const char* const *) apr_table_elts(r->headers_in)->elts;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose int nelts = 2 * apr_table_elts(r->headers_in)->nelts;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose int i;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose for (len = 0, i = 0; i < nelts; i += 2)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose len += strlen(raw[i]) + strlen(raw[i + 1]) + 2;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (*lpdwSizeofBuffer < len + 1) {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose *lpdwSizeofBuffer = len + 1;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose SetLastError(ERROR_INSUFFICIENT_BUFFER);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose return FALSE;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose for (i = 0; i < nelts; i += 2) {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose strcpy(lpvBuffer, raw[i]);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose ((char*)lpvBuffer) += strlen(raw[i]);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose *(((char*)lpvBuffer)++) = ':';
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose *(((char*)lpvBuffer)++) = ' ';
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose strcpy(lpvBuffer, raw[i + 1]);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose ((char*)lpvBuffer) += strlen(raw[i + 1]);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose *(((char*)lpvBuffer)++) = '\n';
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose i += 2;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny *(((char*)lpvBuffer)++) = '\0';
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny *lpdwSizeofBuffer = len;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny return TRUE;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce /* Not a special case */
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek result = apr_table_get(r->subprocess_env, lpszVariableName);
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek if (result) {
17195241500e46272018d7897d6e87249870caf2Pavel Reichl len = strlen(result);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (*lpdwSizeofBuffer < len + 1) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny *lpdwSizeofBuffer = len + 1;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny SetLastError(ERROR_INSUFFICIENT_BUFFER);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny return FALSE;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny strcpy(lpvBuffer, result);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny *lpdwSizeofBuffer = len;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny return TRUE;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny /* Not Found */
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny SetLastError(ERROR_INVALID_INDEX);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny return FALSE;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny}
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan ZelenyBOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny DWORD dwReserved)
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce{
0754ff886f909f0404038eb9c99dd61be1acf5b9Simo Sorce request_rec *r = ((isapi_cid *)ConnID)->r;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny apr_bucket_brigade *bb;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny apr_bucket *b;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (dwReserved == HSE_IO_SYNC)
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ; /* XXX: Fake it */
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce bb = apr_brigade_create(r->pool);
7fe69bb6ec70bce439c6b975a9a0044c98ff502bSimo Sorce b = apr_bucket_transient_create(Buffer, *lpwdwBytes);
7fe69bb6ec70bce439c6b975a9a0044c98ff502bSimo Sorce APR_BRIGADE_INSERT_TAIL(bb, b);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny b = apr_bucket_flush_create();
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny APR_BRIGADE_INSERT_TAIL(bb, b);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ap_pass_brigade(r->output_filters, bb);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny return TRUE;
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce}
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
c03b28a38b14fdb59f74864ae4dc56affe256508Simo SorceBOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize)
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny{
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny request_rec *r = ((isapi_cid *)ConnID)->r;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny DWORD read = 0;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny int res;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (r->remaining < *lpdwSize) {
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce *lpdwSize = (apr_size_t)r->remaining;
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce }
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce while (read < *lpdwSize &&
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ((res = ap_get_client_block(r, (char*)lpvBuffer + read,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny *lpdwSize - read)) > 0)) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny read += res;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce *lpdwSize = read;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny return TRUE;
c03b28a38b14fdb59f74864ae4dc56affe256508Simo Sorce}
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zelenystatic apr_ssize_t SendResponseHeaderEx(isapi_cid *cid, const char *stat,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny const char *head, apr_size_t statlen,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny apr_size_t headlen)
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny{
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny int termarg;
17195241500e46272018d7897d6e87249870caf2Pavel Reichl char *termch;
17195241500e46272018d7897d6e87249870caf2Pavel Reichl
17195241500e46272018d7897d6e87249870caf2Pavel Reichl if (!stat || statlen == 0 || !*stat) {
17195241500e46272018d7897d6e87249870caf2Pavel Reichl stat = "Status: 200 OK";
17195241500e46272018d7897d6e87249870caf2Pavel Reichl }
17195241500e46272018d7897d6e87249870caf2Pavel Reichl else {
17195241500e46272018d7897d6e87249870caf2Pavel Reichl char *newstat;
17195241500e46272018d7897d6e87249870caf2Pavel Reichl newstat = apr_palloc(cid->r->pool, statlen + 9);
17195241500e46272018d7897d6e87249870caf2Pavel Reichl strcpy(newstat, "Status: ");
17195241500e46272018d7897d6e87249870caf2Pavel Reichl apr_cpystrn(newstat + 8, stat, statlen + 1);
17195241500e46272018d7897d6e87249870caf2Pavel Reichl stat = newstat;
17195241500e46272018d7897d6e87249870caf2Pavel Reichl }
17195241500e46272018d7897d6e87249870caf2Pavel Reichl
17195241500e46272018d7897d6e87249870caf2Pavel Reichl if (!head || headlen == 0 || !*head) {
17195241500e46272018d7897d6e87249870caf2Pavel Reichl head = "\r\n";
17195241500e46272018d7897d6e87249870caf2Pavel Reichl }
17195241500e46272018d7897d6e87249870caf2Pavel Reichl else
17195241500e46272018d7897d6e87249870caf2Pavel Reichl {
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek if (head[headlen]) {
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek /* Whoops... not NULL terminated */
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek head = apr_pstrndup(cid->r->pool, head, headlen);
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek }
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek }
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek /* Parse them out, or die trying */
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek cid->r->status= ap_scan_script_header_err_strs(cid->r, NULL, &termch,
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek &termarg, stat, head, NULL);
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek cid->ecb->dwHttpStatusCode = cid->r->status;
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek if (cid->r->status == HTTP_INTERNAL_SERVER_ERROR)
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek return -1;
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek /* Headers will actually go when they are good and ready */
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek /* If all went well, tell the caller we consumed the headers complete */
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek if (!termch)
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek return(headlen);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny /* Any data left is sent directly by the caller, all we
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny * give back is the size of the headers we consumed
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny */
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (termch && (termarg == 1) && head + headlen > termch) {
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce return termch - head;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov return 0;
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce}
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan ZelenyBOOL WINAPI ServerSupportFunction(HCONN hConn, DWORD dwHSERequest,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny LPVOID lpvBuffer, LPDWORD lpdwSize,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny LPDWORD lpdwDataType)
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny{
3b0e0352d8076909608d04750d3ea6b0d9ba33f6Jakub Hrozek isapi_cid *cid = (isapi_cid *)hConn;
3b0e0352d8076909608d04750d3ea6b0d9ba33f6Jakub Hrozek request_rec *r = cid->r;
3b0e0352d8076909608d04750d3ea6b0d9ba33f6Jakub Hrozek request_rec *subreq;
3b0e0352d8076909608d04750d3ea6b0d9ba33f6Jakub Hrozek
3b0e0352d8076909608d04750d3ea6b0d9ba33f6Jakub Hrozek switch (dwHSERequest) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny case 1: /* HSE_REQ_SEND_URL_REDIRECT_RESP */
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny /* Set the status to be returned when the HttpExtensionProc()
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny * is done.
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny * WARNING: Microsoft now advertises HSE_REQ_SEND_URL_REDIRECT_RESP
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny * and HSE_REQ_SEND_URL as equivalant per the Jan 2000 SDK.
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny * They most definately are not, even in their own samples.
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny */
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce apr_table_set (r->headers_out, "Location", lpvBuffer);
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce cid->r->status = cid->ecb->dwHttpStatusCode
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce = HTTP_MOVED_TEMPORARILY;
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose return TRUE;
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek case 2: /* HSE_REQ_SEND_URL */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny /* Soak up remaining input */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (r->remaining > 0) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny char argsbuffer[HUGE_STRING_LEN];
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce while (ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN));
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce }
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce /* Reset the method to GET */
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce r->method = apr_pstrdup(r->pool, "GET");
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce r->method_number = M_GET;
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek /* Don't let anyone think there's still data */
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose apr_table_unset(r->headers_in, "Content-Length");
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce /* AV fault per PR3598 - redirected path is lost! */
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce (char*)lpvBuffer = apr_pstrdup(r->pool, (char*)lpvBuffer);
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose ap_internal_redirect((char*)lpvBuffer, r);
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce return TRUE;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce case 3: /* HSE_REQ_SEND_RESPONSE_HEADER */
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce {
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose /* Parse them out, or die trying */
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek apr_size_t statlen = 0, headlen = 0;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose apr_ssize_t ate;
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek if (lpvBuffer)
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek statlen = strlen((char*) lpvBuffer);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (lpdwDataType)
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny headlen = strlen((char*) lpdwDataType);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny ate = SendResponseHeaderEx(cid, (char*) lpvBuffer,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny (char*) lpdwDataType,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny statlen, headlen);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (ate < 0) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny SetLastError(TODO_ERROR);
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce return FALSE;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce }
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce else if ((apr_size_t)ate < headlen) {
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce apr_bucket_brigade *bb;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce apr_bucket *b;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce bb = apr_brigade_create(cid->r->pool);
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce b = apr_bucket_transient_create((char*) lpdwDataType + ate,
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce headlen - ate);
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce APR_BRIGADE_INSERT_TAIL(bb, b);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny b = apr_bucket_flush_create();
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny APR_BRIGADE_INSERT_TAIL(bb, b);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny ap_pass_brigade(cid->r->output_filters, bb);
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce }
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce return TRUE;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce }
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce case 4: /* HSE_REQ_DONE_WITH_SESSION */
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce /* Signal to resume the thread completing this request
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce */
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce if (cid->complete)
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce SetEvent(cid->complete);
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose return TRUE;
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose case 1001: /* HSE_REQ_MAP_URL_TO_PATH */
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek {
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce /* Map a URL to a filename */
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce char *file = (char *)lpvBuffer;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny DWORD len;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce subreq = ap_sub_req_lookup_uri(apr_pstrndup(r->pool, file, *lpdwSize),
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce r, NULL);
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce len = apr_cpystrn(file, subreq->filename, *lpdwSize) - file;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce /* IIS puts a trailing slash on directories, Apache doesn't */
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce if (subreq->finfo.filetype == APR_DIR) {
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce if (len < *lpdwSize - 1) {
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce file[len++] = '\\';
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce file[len] = '\0';
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce }
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce }
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce *lpdwSize = len;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce return TRUE;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce }
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce case 1002: /* HSE_REQ_GET_SSPI_INFO */
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce if (cid->sconf->LogNotSupported)
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce "ISAPI ServerSupportFunction HSE_REQ_GET_SSPI_INFO "
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce "is not supported: %s", r->filename);
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose SetLastError(ERROR_INVALID_PARAMETER);
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose return FALSE;
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose case 1003: /* HSE_APPEND_LOG_PARAMETER */
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose /* Log lpvBuffer, of lpdwSize bytes, in the URI Query (cs-uri-query) field
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose */
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek apr_table_set(r->notes, "isapi-parameter", (char*) lpvBuffer);
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek if (cid->sconf->AppendLogToQuery) {
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek if (r->args)
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek r->args = apr_pstrcat(r->pool, r->args, (char*) lpvBuffer, NULL);
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek else
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose r->args = apr_pstrdup(r->pool, (char*) lpvBuffer);
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose }
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose if (cid->sconf->AppendLogToErrors)
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r,
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose "ISAPI %s: %s", cid->r->filename,
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose (char*) lpvBuffer);
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose return TRUE;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek case 1005: /* HSE_REQ_IO_COMPLETION */
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek /* Emulates a completion port... Record callback address and
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek * user defined arg, we will call this after any async request
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek * (e.g. transmitfile) as if the request executed async.
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek * Per MS docs... HSE_REQ_IO_COMPLETION replaces any prior call
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek * to HSE_REQ_IO_COMPLETION, and lpvBuffer may be set to NULL.
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (!cid->isa->fakeasync) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (cid->sconf->LogNotSupported)
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek "ISAPI ServerSupportFunction HSE_REQ_IO_COMPLETION "
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek "is not supported: %s", r->filename);
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce SetLastError(ERROR_INVALID_PARAMETER);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny return FALSE;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny cid->completion = (PFN_HSE_IO_COMPLETION) lpvBuffer;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce cid->completion_arg = (PVOID) lpdwDataType;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce return TRUE;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny case 1006: /* HSE_REQ_TRANSMIT_FILE */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny {
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce HSE_TF_INFO *tf = (HSE_TF_INFO*)lpvBuffer;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce apr_status_t rv;
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose apr_bucket_brigade *bb;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce apr_bucket *b;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce apr_file_t *fd;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce if (!cid->isa->fakeasync && (tf->dwFlags & HSE_IO_ASYNC)) {
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce if (cid->sconf->LogNotSupported)
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce "ISAPI ServerSupportFunction HSE_REQ_TRANSMIT_FILE "
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce "as HSE_IO_ASYNC is not supported: %s", r->filename);
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce SetLastError(ERROR_INVALID_PARAMETER);
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce return FALSE;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce }
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if ((rv = apr_os_file_put(&fd, tf->hFile, r->pool)) != APR_SUCCESS) {
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce return FALSE;
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce }
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce /* apr_dupfile_oshandle (&fd, tf->hFile, r->pool); */
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce bb = apr_brigade_create(r->pool);
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce if (tf->dwFlags & HSE_IO_SEND_HEADERS)
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce {
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce /* According to MS: if calling HSE_REQ_TRANSMIT_FILE with the
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce * HSE_IO_SEND_HEADERS flag, then you can't otherwise call any
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce * HSE_SEND_RESPONSE_HEADERS* fn, but if you don't use the flag,
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce * you must have done so. They document that the pHead headers
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce * option is valid only for HSE_IO_SEND_HEADERS - we are a bit
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce * more flexible and assume with the flag, pHead are the
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce * response headers, and without, pHead simply contains text
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce * (handled after this case).
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_ssize_t ate = SendResponseHeaderEx(cid, tf->pszStatusCode,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny (char*)tf->pHead,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny strlen(tf->pszStatusCode),
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny tf->HeadLength);
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce if (ate < 0)
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny {
c03b28a38b14fdb59f74864ae4dc56affe256508Simo Sorce apr_brigade_destroy(bb);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny SetLastError(TODO_ERROR);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny return FALSE;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if ((apr_size_t)ate < tf->HeadLength)
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce {
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce b = apr_bucket_transient_create((char*)tf->pHead + ate,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny tf->HeadLength - ate);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny APR_BRIGADE_INSERT_TAIL(bb, b);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny else if (tf->pHead && tf->HeadLength) {
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce b = apr_bucket_transient_create((char*)tf->pHead,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny tf->HeadLength);
c03b28a38b14fdb59f74864ae4dc56affe256508Simo Sorce APR_BRIGADE_INSERT_TAIL(bb, b);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny b = apr_bucket_file_create(fd, tf->Offset,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny tf->BytesToWrite, r->pool);
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose APR_BRIGADE_INSERT_TAIL(bb, b);
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose if (tf->pTail && tf->TailLength) {
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose b = apr_bucket_transient_create((char*)tf->pTail,
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose tf->TailLength);
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose APR_BRIGADE_INSERT_TAIL(bb, b);
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose }
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose b = apr_bucket_flush_create();
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose APR_BRIGADE_INSERT_TAIL(bb, b);
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose ap_pass_brigade(r->output_filters, bb);
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose /* we do nothing with (tf->dwFlags & HSE_DISCONNECT_AFTER_SEND)
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose */
09d7c105839bfc7447ea0f766413ed86675ca075Sumit Bose
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek if (tf->dwFlags & HSE_IO_ASYNC) {
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek /* XXX: Fake async response,
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek * use tf->pfnHseIO, or if NULL, then use cid->fnIOComplete
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek * pass pContect to the HseIO callback.
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek */
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek }
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek return TRUE;
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek }
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek case 1007: /* HSE_REQ_REFRESH_ISAPI_ACL */
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek if (cid->sconf->LogNotSupported)
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek "ISAPI ServerSupportFunction "
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek "HSE_REQ_REFRESH_ISAPI_ACL "
b3458bbb5315b05d7ac1abc58f1c380761756603Jakub Hrozek "is not supported: %s", r->filename);
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose SetLastError(ERROR_INVALID_PARAMETER);
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose return FALSE;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose case 1008: /* HSE_REQ_IS_KEEP_CONN */
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose *((LPBOOL) lpvBuffer) = (r->connection->keepalive == 1);
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose return TRUE;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose case 1010: /* XXX: Fake it : HSE_REQ_ASYNC_READ_CLIENT */
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose if (cid->sconf->LogNotSupported)
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose "ISAPI asynchronous I/O not supported: %s",
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose r->filename);
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose SetLastError(ERROR_INVALID_PARAMETER);
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose return FALSE;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek case 1011: /* HSE_REQ_GET_IMPERSONATION_TOKEN Added in ISAPI 4.0 */
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek if (cid->sconf->LogNotSupported)
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek "ISAPI ServerSupportFunction "
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek "HSE_REQ_GET_IMPERSONATION_TOKEN "
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek "is not supported: %s", r->filename);
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek SetLastError(ERROR_INVALID_PARAMETER);
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek return FALSE;
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek#ifdef HSE_REQ_MAP_URL_TO_PATH_EX
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek case 1012: /* HSE_REQ_MAP_URL_TO_PATH_EX */
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek {
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek /* Map a URL to a filename */
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek LPHSE_URL_MAPEX_INFO info = (LPHSE_URL_MAPEX_INFO) lpdwDataType;
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek char* test_uri = apr_pstrndup(r->pool, (char *)lpvBuffer, *lpdwSize);
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny subreq = ap_sub_req_lookup_uri(test_uri, r, NULL);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny info->cchMatchingURL = strlen(test_uri);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov info->cchMatchingPath = apr_cpystrn(info->lpszPath, subreq->filename,
1187a07ed4207c1c326fdf83915dddfe472b8620Simo Sorce MAX_PATH) - info->lpszPath;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny /* Mapping started with assuming both strings matched.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * Now roll on the path_info as a mismatch and handle
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * terminating slashes for directory matches.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (subreq->path_info && *subreq->path_info) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_cpystrn(info->lpszPath + info->cchMatchingPath,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny subreq->path_info, MAX_PATH - info->cchMatchingPath);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny info->cchMatchingURL -= strlen(subreq->path_info);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (subreq->finfo.filetype == APR_DIR
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny && info->cchMatchingPath < MAX_PATH - 1) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny /* roll forward over path_info's first slash */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny ++info->cchMatchingPath;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce ++info->cchMatchingURL;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny else if (subreq->finfo.filetype == APR_DIR
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce && info->cchMatchingPath < MAX_PATH - 1) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny /* Add a trailing slash for directory */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny info->lpszPath[info->cchMatchingPath++] = '/';
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny info->lpszPath[info->cchMatchingPath] = '\0';
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny /* If the matched isn't a file, roll match back to the prior slash */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (subreq->finfo.filetype == APR_NOFILE) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov while (info->cchMatchingPath && info->cchMatchingURL) {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if (info->lpszPath[info->cchMatchingPath - 1] == '/')
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce break;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny --info->cchMatchingPath;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny --info->cchMatchingURL;
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny /* Paths returned with back slashes */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov for (test_uri = info->lpszPath; *test_uri; ++test_uri)
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (*test_uri == '/')
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *test_uri = '\\';
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny /* is a combination of:
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * HSE_URL_FLAGS_READ 0x001 Allow read
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * HSE_URL_FLAGS_WRITE 0x002 Allow write
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * HSE_URL_FLAGS_EXECUTE 0x004 Allow execute
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose * HSE_URL_FLAGS_SSL 0x008 Require SSL
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose * HSE_URL_FLAGS_DONT_CACHE 0x010 Don't cache (VRoot only)
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose * HSE_URL_FLAGS_NEGO_CERT 0x020 Allow client SSL cert
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose * HSE_URL_FLAGS_REQUIRE_CERT 0x040 Require client SSL cert
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose * HSE_URL_FLAGS_MAP_CERT 0x080 Map client SSL cert to account
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose * HSE_URL_FLAGS_SSL128 0x100 Require 128-bit SSL cert
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose * HSE_URL_FLAGS_SCRIPT 0x200 Allow script execution
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose *
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose * XxX: As everywhere, EXEC flags could use some work...
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose * and this could go further with more flags, as desired.
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose info->dwFlags = (subreq->finfo.protection & APR_UREAD ? 0x001 : 0)
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose | (subreq->finfo.protection & APR_UWRITE ? 0x002 : 0)
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose | (subreq->finfo.protection & APR_UEXECUTE ? 0x204 : 0);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return TRUE;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose }
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose#endif
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose case 1014: /* HSE_REQ_ABORTIVE_CLOSE */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose if (cid->sconf->LogNotSupported)
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose "ISAPI ServerSupportFunction HSE_REQ_ABORTIVE_CLOSE"
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose " is not supported: %s", r->filename);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose SetLastError(ERROR_INVALID_PARAMETER);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return FALSE;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose case 1015: /* HSE_REQ_GET_CERT_INFO_EX Added in ISAPI 4.0 */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose if (cid->sconf->LogNotSupported)
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose "ISAPI ServerSupportFunction "
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose "HSE_REQ_GET_CERT_INFO_EX "
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose "is not supported: %s", r->filename);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose SetLastError(ERROR_INVALID_PARAMETER);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return FALSE;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose#ifdef HSE_REQ_SEND_RESPONSE_HEADER_EX
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose case 1016: /* HSE_REQ_SEND_RESPONSE_HEADER_EX Added in ISAPI 4.0 */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose {
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose LPHSE_SEND_HEADER_EX_INFO shi
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose = (LPHSE_SEND_HEADER_EX_INFO) lpvBuffer;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose /* XXX: ignore shi->fKeepConn? We shouldn't need the advise */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose /* r->connection->keepalive = shi->fKeepConn; */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose apr_ssize_t ate = SendResponseHeaderEx(cid, shi->pszStatus,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose shi->pszHeader,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose shi->cchStatus,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose shi->cchHeader);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose if (ate < 0) {
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose SetLastError(TODO_ERROR);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return FALSE;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose }
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose else if ((apr_size_t)ate < shi->cchHeader) {
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose apr_bucket_brigade *bb;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose apr_bucket *b;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose bb = apr_brigade_create(cid->r->pool);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose b = apr_bucket_transient_create(shi->pszHeader + ate,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose shi->cchHeader - ate);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose APR_BRIGADE_INSERT_TAIL(bb, b);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose b = apr_bucket_flush_create();
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose APR_BRIGADE_INSERT_TAIL(bb, b);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose ap_pass_brigade(cid->r->output_filters, bb);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose }
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return TRUE;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose }
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose#endif
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose case 1017: /* HSE_REQ_CLOSE_CONNECTION Added after ISAPI 4.0 */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose if (cid->sconf->LogNotSupported)
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose "ISAPI ServerSupportFunction "
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose "HSE_REQ_CLOSE_CONNECTION "
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose "is not supported: %s", r->filename);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose SetLastError(ERROR_INVALID_PARAMETER);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return FALSE;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose case 1018: /* HSE_REQ_IS_CONNECTED Added after ISAPI 4.0 */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose /* Returns True if client is connected c.f. MSKB Q188346
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose * assuming the identical return mechanism as HSE_REQ_IS_KEEP_CONN
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose *((LPBOOL) lpvBuffer) = (r->connection->aborted == 0);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return TRUE;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose case 1020: /* HSE_REQ_EXTENSION_TRIGGER Added after ISAPI 4.0 */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose /* Undocumented - defined by the Microsoft Jan '00 Platform SDK
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose if (cid->sconf->LogNotSupported)
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose "ISAPI ServerSupportFunction "
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose "HSE_REQ_EXTENSION_TRIGGER "
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose "is not supported: %s", r->filename);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose SetLastError(ERROR_INVALID_PARAMETER);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return FALSE;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose default:
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose if (cid->sconf->LogNotSupported)
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose "ISAPI ServerSupportFunction (%d) not supported: "
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose "%s", dwHSERequest, r->filename);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose SetLastError(ERROR_INVALID_PARAMETER);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return FALSE;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose }
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose}
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose/*
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose * Command handler for the ISAPIReadAheadBuffer directive, which is TAKE1
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bosestatic const char *isapi_cmd_readaheadbuffer(cmd_parms *cmd, void *config,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose char *arg)
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose{
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose isapi_server_conf *sconf = ap_get_module_config(cmd->server->module_config,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose &isapi_module);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose char *scan;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose long val;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose if (((val = strtol(arg, (char **) &scan, 10)) <= 0) || *scan)
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return "ISAPIReadAheadBuffer must be a legitimate value.";
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose sconf->ReadAheadBuffer = val;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return NULL;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose}
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose/*
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose * Command handler for the ISAPIReadAheadBuffer directive, which is TAKE1
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose */
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bosestatic const char *isapi_cmd_lognotsupported(cmd_parms *cmd, void *config,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose char *arg)
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose{
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose isapi_server_conf *sconf = ap_get_module_config(cmd->server->module_config,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose &isapi_module);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose if (strcasecmp(arg, "on") == 0) {
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose sconf->LogNotSupported = -1;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose }
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose else if (strcasecmp(arg, "off") == 0) {
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose sconf->LogNotSupported = 0;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose }
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose else {
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return "ISAPILogNotSupported must be on or off";
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose }
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose return NULL;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose}
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bosestatic const char *isapi_cmd_appendlogtoerrors(cmd_parms *cmd, void *config,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose char *arg)
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose{
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose isapi_server_conf *sconf = ap_get_module_config(cmd->server->module_config,
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose &isapi_module);
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose if (strcasecmp(arg, "on") == 0) {
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose sconf->AppendLogToErrors = -1;
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose }
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose else if (strcasecmp(arg, "off") == 0) {
5ff7a765434ed0b4d37564ade26d7761d06f81c3Sumit Bose sconf->AppendLogToErrors = 0;
}
else {
return "ISAPIAppendLogToErrors must be on or off";
}
return NULL;
}
static const char *isapi_cmd_appendlogtoquery(cmd_parms *cmd, void *config,
char *arg)
{
isapi_server_conf *sconf = ap_get_module_config(cmd->server->module_config,
&isapi_module);
if (strcasecmp(arg, "on") == 0) {
sconf->AppendLogToQuery = -1;
}
else if (strcasecmp(arg, "off") == 0) {
sconf->AppendLogToQuery = 0;
}
else {
return "ISAPIAppendLogToQuery must be on or off";
}
return NULL;
}
static const char *isapi_cmd_cachefile(cmd_parms *cmd, void *dummy,
const char *filename)
{
isapi_server_conf *sconf = ap_get_module_config(cmd->server->module_config,
&isapi_module);
isapi_loaded *isa, **newisa;
apr_finfo_t tmp;
apr_status_t rv;
char *fspec;
fspec = ap_server_root_relative(cmd->pool, filename);
if ((rv = apr_stat(&tmp, fspec,
APR_FINFO_TYPE, cmd->temp_pool)) != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_WARNING, rv, cmd->server,
"ISAPI: unable to stat(%s), skipping", filename);
return NULL;
}
if (tmp.filetype != APR_REG) {
ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, cmd->server,
"ISAPI: %s isn't a regular file, skipping", filename);
return NULL;
}
/* Load the extention as cached (passing sconf) */
rv = isapi_load(cmd->pool, sconf, NULL, fspec, &isa);
if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_WARNING, rv, cmd->server,
"ISAPI: unable to cache %s, skipping", filename);
return NULL;
}
/* Add to cached list of loaded modules */
newisa = apr_array_push(sconf->loaded);
*newisa = isa;
return NULL;
}
static void isapi_hooks(apr_pool_t *cont)
{
ap_hook_post_config(isapi_post_config, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_handler(isapi_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
static const command_rec isapi_cmds[] = {
AP_INIT_TAKE1("ISAPIReadAheadBuffer", isapi_cmd_readaheadbuffer, NULL, RSRC_CONF,
"Maximum bytes to initially pass to the ISAPI handler"),
AP_INIT_TAKE1("ISAPILogNotSupported", isapi_cmd_lognotsupported, NULL, RSRC_CONF,
"Log requests not supported by the ISAPI server"),
AP_INIT_TAKE1("ISAPIAppendLogToErrors", isapi_cmd_appendlogtoerrors, NULL, RSRC_CONF,
"Send all Append Log requests to the error log"),
AP_INIT_TAKE1("ISAPIAppendLogToQuery", isapi_cmd_appendlogtoquery, NULL, RSRC_CONF,
"Append Log requests are concatinated to the query args"),
AP_INIT_ITERATE("ISAPICacheFile", isapi_cmd_cachefile, NULL, RSRC_CONF,
"Cache the specified ISAPI extension in-process"),
{ NULL }
};
module isapi_module = {
STANDARD20_MODULE_STUFF,
NULL, /* create per-dir config */
NULL, /* merge per-dir config */
create_isapi_server_config, /* server config */
NULL, /* merge server config */
isapi_cmds, /* command apr_table_t */
isapi_hooks /* register hooks */
};