/****************************************************************************
 *                                                                          *
 * The contents of this file are subject to the WebStone Public License     *
 * Version 1.0 (the "License"); you may not use this file except in         *
 * compliance with the License. You may obtain a copy of the License        *
 * at http://www.mindcraft.com/webstone/license10.html                      *
 *                                                                          *
 * Software distributed under the License is distributed on an "AS IS"      *
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See      *
 * the License for the specific language governing rights and limitations   *
 * under the License.                                                       *
 *                                                                          *
 * The Original Code is WebStone 2.5.                                       *
 *                                                                          *
 * The Initial Developer of the Original Code is Silicon Graphics, Inc.     *
 * and Mindcraft, Inc.. Portions created by Silicon Graphics. and           *
 * Mindcraft. are Copyright (C) 1995-1998 Silicon Graphics, Inc. and        *
 * Mindcraft, Inc. All Rights Reserved.                                     *
 *                                                                          *
 * Contributor(s): ______________________________________.                  *
 *                                                                          *
 ***************************************************************************/

/*
 * ws25_ns.c 1.3
 *
 * NAME
 *	ws_nsapi_25.c
 *
 * PURPOSE
 *  A module for use with the WebStone test suite to measure performance
 *	of a Netscape Server using NSAPI.  This module will send back the
 *  contents of a given file.
 *
 * USAGE:
 *     Once this service function is installed, any URL accessing a file with 
 *     the extension "dyn-send" will be serviced with this function.  The 
 *     argument to the URL is the file name.  For example:
 *
 *         /file.dyn-send?file=/wwwroot/file500.html
 *         /file.dyn-send?file=D:\wwwroot\file500.html
 *
 *     To install the service routine, compile it as per the makefile.
 *     Then add the following lines to your netscape server configuration:
 *
 *     In obj.conf (Netscape 3.5 or later):
 *
 *	       Init fn="load-modules" funcs="ws-nsapi-send"
 *              shlib="<the path to the DLL file>" NativeThread="no"
 *
 *         Service method="(GET|HEAD)" type="magnus-internal/dyn-send" fn="ws-nsapi-send"
 *
 *     In mime.types:
 *
 *         type=magnus-internal/dyn-send        exts=dyn-send
 *
 *
 *     NOTE: The function name is "ws_nsapi_send()" but it must be specified 
 *           in the conf files as "ws-nsapi-send" (dashes rather than 
 *           underscores).  That is just how the Netscape configuration works.
 */
#include <stdio.h>
#include <stdlib.h>

#ifdef WIN32
#include <windows.h>
#define FILE_STDIO 1
#endif

#include "base/pblock.h"
#include "base/session.h"
#include "frame/protocol.h"
#include "base/util.h"
#include "frame/http.h"
#include "frame/req.h"
#include "frame/log.h"

#define BUFSIZE	1024


#ifdef WIN32
__declspec(dllexport) 
#endif
int 
ws_nsapi_send(pblock *pb, Session *sn, Request *rq)
{
	char	*query;
	char	*filename;
	FILE	*fp;
	char	buf[BUFSIZE];
	size_t	nread;

	/* 
	 * Get the file name argument.  This must be present.
	 */
	query = pblock_findval("query", rq->reqpb);
	if ( (query == NULL) || (*query == '\0') || strncmp(query, "file=", 5) )
	{
		protocol_status(sn, rq, PROTOCOL_BAD_REQUEST, NULL);
		log_error(LOG_FAILURE, "ws_nsapi_send", sn, rq,
                      "Missing or invalid query string");
		return REQ_ABORTED;
	}
	if (*(filename = &(query[5])) == '\0')
	{
		protocol_status(sn, rq, PROTOCOL_BAD_REQUEST, 
			"No file name specified.");
		log_error(LOG_FAILURE, "ws_nsapi_send", sn, rq,
                      "No file name specified");
		return REQ_ABORTED;
	}

	/*
 	 * Open the file.  Send back an error message if this fails.
 	 */
	if ((fp = fopen(filename, "r")) == NULL)
	{
		protocol_status(sn, rq, PROTOCOL_SERVER_ERROR, 
			"Unable to open file.");
		log_error(LOG_FAILURE, "ws_nsapi_send", sn, rq,
                      "Unable to open file '%s'.", filename);
		return REQ_ABORTED;
	}

	/* 
	 * So far so good, we're ready to start sending the file back.
	 * Set content-type and begin a "success" response. 
	 */
	if (rq->srvhdrs == NULL)
		rq->srvhdrs = pblock_create(1);

	pblock_nvinsert("content-type", "text/plain", rq->srvhdrs);
	protocol_status(sn, rq, PROTOCOL_OK, NULL);
	if (protocol_start_response(sn, rq) == REQ_NOACTION) 
	{
		fclose(fp);
		return REQ_PROCEED;   /* wasn't a valid GET request */
	}

	/*
	 * Now send back the contents of the file.
	 */
	while (nread = fread(buf, sizeof(char), BUFSIZE, fp))
	{
		if (net_write(sn->csd, buf, nread) == IO_ERROR) 
		{
			protocol_status(sn, rq, PROTOCOL_SERVER_ERROR, NULL);
			log_error(LOG_FAILURE, "ws_nsapi_send", sn, rq,
			      "Uknown error while sending file contents.");
			fclose(fp);
			return REQ_ABORTED;
		}
	}
	if (ferror(fp))
	{
		protocol_status(sn, rq, PROTOCOL_SERVER_ERROR, NULL);
		log_error(LOG_FAILURE, "ws_nsapi_send", sn, rq,
                      "Error reading file '%s'.", filename);
		(void) fclose(fp);
		return REQ_ABORTED;
	}

	/*
	 * Success!
	 */
	(void) fclose(fp);
	return REQ_EXIT;
}
