Skip to content
sws.c 28.5 KiB
Newer Older
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
Yang Tse's avatar
Yang Tse committed
 * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
 * 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.
 * 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.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id$
 ***************************************************************************/
   This code was originally graciously donated to the project by Juergen
#include "setup.h" /* portability help from the lib directory */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <ctype.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef _XOPEN_SOURCE_EXTENDED
/* This define is "almost" required to build on HPUX 11 */
#include <arpa/inet.h>
#ifdef HAVE_NETDB_H
#include <netdb.h>
#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 */
#include "curlx.h" /* from the private lib dir */
#include "getpart.h"
/* include memdebug.h last */
#include "memdebug.h"

#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...
 */
#define REQBUFSIZ 150000
#define REQBUFSIZ_TXT "149999"

long prevtestno=-1; /* previous test number we served */
long prevpartno=-1; /* previous part number we served */
Yang Tse's avatar
Yang Tse committed
bool prevbounce=FALSE; /* 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 */

struct httprequest {
  char reqbuf[REQBUFSIZ]; /* buffer area for the incoming request */
  int checkindex; /* where to start checking of the request */
  int offset;     /* size of the incoming request */
  long testno;     /* test number found in the request */
  long partno;     /* part number found in the request */
Yang Tse's avatar
Yang Tse committed
  bool 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 */
  int prot_version; /* HTTP version * 10 */
  bool pipelining; /* true if request is pipelined */
};

int ProcessRequest(struct httprequest *req);
void storerequest(char *reqbuf, ssize_t totalsize);

#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"
/* 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"

  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";
static volatile int sigpipe;  /* Why? It's not used */
#endif
static void sigpipe_handler(int sig)
{
  (void)sig; /* prevent warning */
  sigpipe = 1;
#endif
int ProcessRequest(struct httprequest *req)
{
  char *line=&req->reqbuf[req->checkindex];
Yang Tse's avatar
Yang Tse committed
  bool chunked = FALSE;
  static char request[REQUEST_KEYWORD_SIZE];
Loading
Loading full blame…