Commit 6ed72fd7 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

sws: added basic gopher support

parent 40e16236
Loading
Loading
Loading
Loading
+63 −12
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@
#ifdef ENABLE_IPV6
static bool use_ipv6 = FALSE;
#endif
static bool use_gopher = FALSE;
static const char *ipv_inuse = "IPv4";
static int serverlogslocked = 0;

@@ -159,6 +160,7 @@ enum {
  DOCNUMBER_404     = -1
};

const char *end_of_headers = END_OF_HEADERS;

/* sent as reply to a QUIT */
static const char *docquit =
@@ -307,13 +309,22 @@ static int ProcessRequest(struct httprequest *req)
  int prot_major, prot_minor;
  char *end;
  int error;
  end = strstr(line, END_OF_HEADERS);
  end = strstr(line, end_of_headers);

  logmsg("ProcessRequest() called");

  /* try to figure out the request characteristics as soon as possible, but
     only once! */
  if((req->testno == DOCNUMBER_NOTHING) &&

  if(use_gopher &&
     (req->testno == DOCNUMBER_NOTHING) &&
     !strncmp("/verifiedserver", line, 15)) {
    logmsg("Are-we-friendly question received");
    req->testno = DOCNUMBER_WERULEZ;
    return 1; /* done */
  }

  else if((req->testno == DOCNUMBER_NOTHING) &&
     sscanf(line,
            "%" REQUEST_KEYWORD_SIZE_TXT"s %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d",
            request,
@@ -471,10 +482,40 @@ static int ProcessRequest(struct httprequest *req)
  }
  logmsg("ProcessRequest found a complete request");

  if(use_gopher) {
    /* when using gopher we cannot check the request until the entire
       thing has been received */
    char *ptr;

    /* find the last slash in the line */
    ptr = strrchr(line, '/');

    if(ptr) {
      ptr++; /* skip the slash */

      /* skip all non-numericals following the slash */
      while(*ptr && !ISDIGIT(*ptr))
        ptr++;

      req->testno = strtol(ptr, &ptr, 10);

      if(req->testno > 10000) {
        req->partno = req->testno % 10000;
        req->testno /= 10000;
      }
      else
        req->partno = 0;

      sprintf(logbuf, "Requested GOPHER test number %ld part %ld",
              req->testno, req->partno);
      logmsg("%s", logbuf);
    }
  }

  if(req->pipe)
    /* we do have a full set, advance the checkindex to after the end of the
       headers, for the pipelining case mostly */
    req->checkindex += (end - line) + strlen(END_OF_HEADERS);
    req->checkindex += (end - line) + strlen(end_of_headers);

  /* **** Persistence ****
   *
@@ -582,12 +623,12 @@ static int ProcessRequest(struct httprequest *req)
     req->open &&
     req->prot_version >= 11 &&
     end &&
     req->reqbuf + req->offset > end + strlen(END_OF_HEADERS) &&
     req->reqbuf + req->offset > end + strlen(end_of_headers) &&
     (!strncmp(req->reqbuf, "GET", strlen("GET")) ||
      !strncmp(req->reqbuf, "HEAD", strlen("HEAD")))) {
    /* If we have a persistent connection, HTTP version >= 1.1
       and GET/HEAD request, enable pipelining. */
    req->checkindex = (end - req->reqbuf) + strlen(END_OF_HEADERS);
    req->checkindex = (end - req->reqbuf) + strlen(end_of_headers);
    req->pipelining = TRUE;
  }

@@ -596,10 +637,10 @@ static int ProcessRequest(struct httprequest *req)
      return 1; /* done */
    /* scan for more header ends within this chunk */
    line = &req->reqbuf[req->checkindex];
    end = strstr(line, END_OF_HEADERS);
    end = strstr(line, end_of_headers);
    if(!end)
      break;
    req->checkindex += (end - line) + strlen(END_OF_HEADERS);
    req->checkindex += (end - line) + strlen(end_of_headers);
    req->pipe--;
  }

@@ -611,7 +652,7 @@ static int ProcessRequest(struct httprequest *req)
    return 1; /* done */

  if(req->cl > 0) {
    if(req->cl <= req->offset - (end - req->reqbuf) - strlen(END_OF_HEADERS))
    if(req->cl <= req->offset - (end - req->reqbuf) - strlen(end_of_headers))
      return 1; /* done */
    else
      return 0; /* not complete yet */
@@ -842,6 +883,9 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
      logmsg("Identifying ourselves as friends");
      sprintf(msgbuf, "WE ROOLZ: %ld\r\n", (long)getpid());
      msglen = strlen(msgbuf);
      if(use_gopher)
        sprintf(weare, "%s", msgbuf);
      else
        sprintf(weare, "HTTP/1.1 200 OK\r\nContent-Length: %zu\r\n\r\n%s",
                msglen, msgbuf);
      buffer = weare;
@@ -1050,7 +1094,7 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
  if(cmd)
    free(cmd);

  req->open = persistant;
  req->open = use_gopher?FALSE:persistant;

  prevtestno = req->testno;
  prevpartno = req->partno;
@@ -1106,6 +1150,11 @@ int main(int argc, char *argv[])
      if(argc>arg)
        serverlogfile = argv[arg++];
    }
    else if(!strcmp("--gopher", argv[arg])) {
      arg++;
      use_gopher = TRUE;
      end_of_headers = "\r\n"; /* gopher style is much simpler */
    }
    else if(!strcmp("--ipv4", argv[arg])) {
#ifdef ENABLE_IPV6
      ipv_inuse = "IPv4";
@@ -1157,6 +1206,7 @@ int main(int argc, char *argv[])
           " --ipv6\n"
           " --port [port]\n"
           " --srcdir [path]\n"
           " --gopher\n"
           " --fork");
      return 0;
    }
@@ -1221,7 +1271,8 @@ int main(int argc, char *argv[])
    goto sws_cleanup;
  }

  logmsg("Running %s version on port %d", ipv_inuse, (int)port);
  logmsg("Running %s %s version on port %d",
         use_gopher?"GOPHER":"HTTP", ipv_inuse, (int)port);

  /* start accepting connections */
  rc = listen(sock, 5);