Newer
Older
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
Daniel Stenberg
committed
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
Daniel Stenberg
committed
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
Daniel Stenberg
committed
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
Daniel Stenberg
committed
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
Daniel Stenberg
committed
/* sws.c: simple (silly?) web server
This code was originally graciously donated to the project by Juergen
Daniel Stenberg
committed
Wilke. Thanks a bunch!
Daniel Stenberg
committed
*/
#include "setup.h" /* portability help from the lib directory */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
Daniel Stenberg
committed
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
Daniel Stenberg
committed
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
Daniel Stenberg
committed
#endif
#ifdef _XOPEN_SOURCE_EXTENDED
/* This define is "almost" required to build on HPUX 11 */
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h> /* for TCP_NODELAY */
#endif
#define ENABLE_CURLX_PRINTF
/* make the curlx header define all printf() functions to use the curlx_*
versions instead */
Daniel Stenberg
committed
#include "curlx.h" /* from the private lib dir */
#include "util.h"
/* include memdebug.h last */
#include "memdebug.h"
Daniel Stenberg
committed
#if !defined(CURL_SWS_FORK_ENABLED) && defined(HAVE_FORK)
/*
* The normal sws build for the plain standard curl test suite has no use for
* fork(), but if you feel wild and crazy and want to setup some more exotic
* tests. Define this and run...
*/
Daniel Stenberg
committed
#define CURL_SWS_FORK_ENABLED
#endif
Daniel Stenberg
committed
#define REQBUFSIZ 150000
#define REQBUFSIZ_TXT "149999"
Daniel Stenberg
committed
long prevtestno=-1; /* previous test number we served */
long prevpartno=-1; /* previous part number we served */
bool prevbounce; /* instructs the server to increase the part number for
a test in case the identical testno+partno request
shows up again */
#define RCMD_NORMALREQ 0 /* default request, use the tests file normally */
#define RCMD_IDLE 1 /* told to sit idle */
#define RCMD_STREAM 2 /* told to stream */
Daniel Stenberg
committed
struct httprequest {
char reqbuf[REQBUFSIZ]; /* buffer area for the incoming request */
int checkindex; /* where to start checking of the request */
Daniel Stenberg
committed
int offset; /* size of the incoming request */
long testno; /* test number found in the request */
Daniel Stenberg
committed
long partno; /* part number found in the request */
Daniel Stenberg
committed
int open; /* keep connection open info, as found in the request */
bool auth_req; /* authentication required, don't wait for body unless
there's an Authorization header */
bool auth; /* Authorization header present in the incoming request */
size_t cl; /* Content-Length of the incoming request */
bool digest; /* Authorization digest header found */
bool ntlm; /* Authorization ntlm header found */
int pipe; /* if non-zero, expect this many requests to do a "piped"
request/response */
int rcmd; /* doing a special command, see defines above */
Daniel Stenberg
committed
};
int ProcessRequest(struct httprequest *req);
void storerequest(char *reqbuf, ssize_t totalsize);
#define DEFAULT_PORT 8999
#ifndef DEFAULT_LOGFILE
#define DEFAULT_LOGFILE "log/sws.log"
const char *serverlogfile = DEFAULT_LOGFILE;
#define SWSVERSION "cURL test suite HTTP server/0.1"
#define REQUEST_DUMP "log/server.input"
#define RESPONSE_DUMP "log/server.response"
Daniel Stenberg
committed
/* very-big-path support */
#define MAXDOCNAMELEN 140000
#define MAXDOCNAMELEN_TXT "139999"
#define REQUEST_KEYWORD_SIZE 256
#define CMD_AUTH_REQUIRED "auth_required"
/* 'idle' means that it will accept the request fine but never respond
any data. Just keep the connection alive. */
#define CMD_IDLE "idle"
/* 'stream' means to send a never-ending stream of data */
#define CMD_STREAM "stream"
#define END_OF_HEADERS "\r\n\r\n"
Daniel Stenberg
committed
DOCNUMBER_NOTHING = -7,
DOCNUMBER_QUIT = -6,
DOCNUMBER_BADCONNECT = -5,
DOCNUMBER_INTERNAL= -4,
DOCNUMBER_CONNECT = -3,
DOCNUMBER_WERULEZ = -2,
DOCNUMBER_404 = -1
};
/* sent as reply to a QUIT */
static const char *docquit =
"HTTP/1.1 200 Goodbye" END_OF_HEADERS;
/* sent as reply to a CONNECT */
static const char *docconnect =
"HTTP/1.1 200 Mighty fine indeed" END_OF_HEADERS;
/* sent as reply to a "bad" CONNECT */
static const char *docbadconnect =
"HTTP/1.1 501 Forbidden you fool" END_OF_HEADERS;
/* send back this on 404 file not found */
static const char *doc404 = "HTTP/1.1 404 Not Found\r\n"
"Server: " SWSVERSION "\r\n"
"Connection: close\r\n"
"Content-Type: text/html"
END_OF_HEADERS
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
"<HTML><HEAD>\n"
"<TITLE>404 Not Found</TITLE>\n"
"</HEAD><BODY>\n"
"<H1>Not Found</H1>\n"
"The requested URL was not found on this server.\n"
"<P><HR><ADDRESS>" SWSVERSION "</ADDRESS>\n" "</BODY></HTML>\n";
Daniel Stenberg
committed
#ifdef SIGPIPE
static volatile int sigpipe; /* Why? It's not used */
Daniel Stenberg
committed
#ifdef SIGPIPE
static void sigpipe_handler(int sig)
{
(void)sig; /* prevent warning */
sigpipe = 1;
Daniel Stenberg
committed
int ProcessRequest(struct httprequest *req)
{
char *line=&req->reqbuf[req->checkindex];
Daniel Stenberg
committed
char chunked=FALSE;
static char request[REQUEST_KEYWORD_SIZE];
static char doc[MAXDOCNAMELEN];
char logbuf[256];
Loading
Loading full blame…