You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by tr...@locus.apache.org on 2000/06/26 22:14:37 UTC

cvs commit: apache-2.0/src/lib/apr/test testsf.c Makefile.in

trawick     00/06/26 13:14:35

  Modified:    src/lib/apr/test Makefile.in
  Added:       src/lib/apr/test testsf.c
  Log:
  Add a test driver for ap_sendfile().
  
  Revision  Changes    Path
  1.24      +5 -0      apache-2.0/src/lib/apr/test/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/test/Makefile.in,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- Makefile.in	2000/06/03 15:17:45	1.23
  +++ Makefile.in	2000/06/26 20:14:34	1.24
  @@ -17,6 +17,7 @@
   	testfile@EXEEXT@ \
   	testproc@EXEEXT@ \
   	testsock@EXEEXT@ \
  +	testsf@EXEEXT@ \
   	testthread@EXEEXT@ \
   	testtime@EXEEXT@ \
   	testargs@EXEEXT@ \
  @@ -33,6 +34,7 @@
   	testfile.o \
   	testproc.o \
   	testsock.o \
  +	testsf.o \
   	testthread.o \
   	testtime.o \
           testargs.o \
  @@ -82,6 +84,9 @@
   	$(CC) $(CFLAGS) -o testsock@EXEEXT@ testsock.o $(LDFLAGS)
   	$(CC) $(CFLAGS) -o server@EXEEXT@ server.o $(LDFLAGS) 
   	$(CC) $(CFLAGS) -o client@EXEEXT@ client.o $(LDFLAGS)
  +
  +testsf@EXEEXT@: testsf.o
  +	$(CC) $(CFLAGS) -o testsf@EXEEXT@ testsf.o $(LDFLAGS)
   
   testtime@EXEEXT@: testtime.o
   	$(CC) $(CFLAGS) -o testtime@EXEEXT@ testtime.o $(LDFLAGS)
  
  
  
  1.1                  apache-2.0/src/lib/apr/test/testsf.c
  
  Index: testsf.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  #include <assert.h>
  #include <errno.h>
  #include <signal.h>
  #include <stdlib.h>
  #include "apr_network_io.h"
  #include "apr_errno.h"
  #include "apr_general.h"
  
  #if !APR_HAS_SENDFILE
  int main(void)
  {
      fprintf(stderr, 
              "This program won't work on this platform because there is no "
              "support for sendfile().\n");
      return 0;
  }
  #else /* !APR_HAS_SENDFILE */
  
  #define FILE_LENGTH    100000
  
  #define HDR1           "First header\n"
  #define HDR2           "Last header\n"
  #define TRL1           "First trailer\n"
  #define TRL2           "Last trailer\n"
  
  #define TESTSF_PORT    8021
  
  #define TESTFILE       "testsf.dat"
  
  static void apr_setup(ap_pool_t **p, ap_socket_t **sock)
  {
      char buf[120];
      ap_status_t rv;
  
      rv = ap_initialize();
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_initialize()->%d/%s\n",
                  rv,
                  ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      atexit(ap_terminate);
  
      rv = ap_create_pool(p, NULL);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_create_pool()->%d/%s\n",
                  rv,
                  ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      *sock = NULL;
      rv = ap_create_tcp_socket(sock, *p);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_create_tcp_socket()->%d/%s\n",
                  rv,
                  ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  }
  
  static void create_testfile(ap_pool_t *p, const char *fname)
  {
      ap_file_t *f = NULL;
      ap_status_t rv;
      char buf[120];
      int i;
      ap_ssize_t nbytes;
  
      rv = ap_open(&f, fname, APR_CREATE | APR_WRITE | APR_TRUNCATE, APR_UREAD | APR_UWRITE, p);
      if (rv) {
          fprintf(stderr, "ap_open()->%d/%s\n",
                  rv, ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
      
      for (i = 0; i < FILE_LENGTH; i++) {
          nbytes = 1;
          rv = ap_write(f, "0", &nbytes);
          if (rv) {
              fprintf(stderr, "ap_write()->%d/%s\n",
                      rv, ap_strerror(rv, buf, sizeof buf));
              exit(1);
          }
      }
  
      rv = ap_close(f);
      if (rv) {
          fprintf(stderr, "ap_close()->%d/%s\n",
                  rv, ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  }
  
  static int client(int blocking)
  {
      ap_status_t rv;
      ap_socket_t *sock;
      ap_pool_t *p;
      char buf[120];
      ap_file_t *f = NULL;
      ap_size_t len;
      ap_off_t offset;
      ap_hdtr_t hdtr;
      struct iovec headers[2];
      struct iovec trailers[2];
      ap_ssize_t bytes_read;
  
      apr_setup(&p, &sock);
      create_testfile(p, TESTFILE);
  
      rv = ap_open(&f, TESTFILE, APR_READ, 0, p);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_open()->%d/%s\n",
                  rv,
                  ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      rv = ap_set_remote_port(sock, TESTSF_PORT);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_set_remote_port()->%d/%s\n",
                  rv,
                  ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      rv = ap_connect(sock, "127.0.0.1");
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_connect()->%d/%s\n", 
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      if (!blocking) {
          rv = ap_setsocketopt(sock, APR_SO_NONBLOCK, 1);
          if (rv != APR_SUCCESS) {
              fprintf(stderr, "ap_setsocketopt(APR_SO_NONBLOCK)->%d/%s\n", 
                      rv,
                      ap_strerror(rv, buf, sizeof buf));
              exit(1);
          }
      }
  
      hdtr.headers = headers;
      hdtr.numheaders = 2;
      hdtr.headers[0].iov_base = HDR1;
      hdtr.headers[0].iov_len  = strlen(hdtr.headers[0].iov_base);
      hdtr.headers[1].iov_base = HDR2;
      hdtr.headers[1].iov_len  = strlen(hdtr.headers[1].iov_base);
  
      hdtr.trailers = trailers;
      hdtr.numtrailers = 2;
      hdtr.trailers[0].iov_base = TRL1;
      hdtr.trailers[0].iov_len  = strlen(hdtr.trailers[0].iov_base);
      hdtr.trailers[1].iov_base = TRL2;
      hdtr.trailers[1].iov_len  = strlen(hdtr.trailers[1].iov_base);
  
      offset = 0;
      len = FILE_LENGTH;
      rv = ap_sendfile(sock, f, &hdtr, &offset, &len, 0);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_sendfile()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      printf("ap_sendfile() updated len with %ld\n",
             (long int)len);
  
      rv = ap_shutdown(sock, APR_SHUTDOWN_WRITE);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_shutdown()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      bytes_read = 1;
      rv = ap_recv(sock, buf, &bytes_read);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_recv()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
      if (bytes_read != 0) {
          fprintf(stderr, "We expected the EOF condition on the connected\n"
                  "socket but instead we read %ld bytes.\n",
                  (long int)bytes_read);
          exit(1);
      }
  
      printf("client: ap_sendfile() worked as expected!\n");
  
      rv = ap_remove_file(TESTFILE, p);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_remove_file()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      return 0;
  }
  
  static int server(void)
  {
      ap_status_t rv;
      ap_socket_t *sock;
      ap_pool_t *p;
      char buf[120];
      int i;
      ap_socket_t *newsock = NULL;
      ap_ssize_t bytes_read;
  
      apr_setup(&p, &sock);
  
      rv = ap_set_local_port(sock, TESTSF_PORT);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_set_local_port()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      rv = ap_setsocketopt(sock, APR_SO_REUSEADDR, 1);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_setsocketopt()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      rv = ap_bind(sock);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_bind()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      rv = ap_listen(sock, 5);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_listen()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      printf("Waiting for a client to connect...\n");
  
      rv = ap_accept(&newsock, sock, p);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_accept()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
  
      assert(sizeof buf > strlen(HDR1));
      bytes_read = strlen(HDR1);
      rv = ap_recv(newsock, buf, &bytes_read);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_recv()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
      if (bytes_read != strlen(HDR1)) {
          fprintf(stderr, "wrong data read (1)\n");
          exit(1);
      }
      if (memcmp(buf, HDR1, strlen(HDR1))) {
          fprintf(stderr, "wrong data read (2)\n");
          fprintf(stderr, "received: `%.*s'\nexpected: `%s'\n",
                  bytes_read, buf, HDR1);
          exit(1);
      }
          
      assert(sizeof buf > strlen(HDR2));
      bytes_read = strlen(HDR2);
      rv = ap_recv(newsock, buf, &bytes_read);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_recv()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
      if (bytes_read != strlen(HDR2)) {
          fprintf(stderr, "wrong data read (3)\n");
          exit(1);
      }
      if (memcmp(buf, HDR2, strlen(HDR2))) {
          fprintf(stderr, "wrong data read (4)\n");
          fprintf(stderr, "received: `%.*s'\nexpected: `%s'\n",
                  bytes_read, buf, HDR2);
          exit(1);
      }
  
      for (i = 0; i < FILE_LENGTH; i++) {
          bytes_read = 1;
          rv = ap_recv(newsock, buf, &bytes_read);
          if (rv != APR_SUCCESS) {
              fprintf(stderr, "ap_recv()->%d/%s\n",
                      rv,
                      ap_strerror(rv, buf, sizeof buf));
              exit(1);
          }
          if (bytes_read != 1) {
              fprintf(stderr, "ap_recv()->%ld bytes instead of 1\n",
                      (long int)bytes_read);
              exit(1);
          }
      }
          
      assert(sizeof buf > strlen(TRL1));
      bytes_read = strlen(TRL1);
      rv = ap_recv(newsock, buf, &bytes_read);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_recv()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
      if (bytes_read != strlen(TRL1)) {
          fprintf(stderr, "wrong data read (5)\n");
          exit(1);
      }
      if (memcmp(buf, TRL1, strlen(TRL1))) {
          fprintf(stderr, "wrong data read (6)\n");
          fprintf(stderr, "received: `%.*s'\nexpected: `%s'\n",
                  bytes_read, buf, TRL1);
          exit(1);
      }
          
      assert(sizeof buf > strlen(TRL2));
      bytes_read = strlen(TRL2);
      rv = ap_recv(newsock, buf, &bytes_read);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_recv()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
      if (bytes_read != strlen(TRL2)) {
          fprintf(stderr, "wrong data read (7)\n");
          exit(1);
      }
      if (memcmp(buf, TRL2, strlen(TRL2))) {
          fprintf(stderr, "wrong data read (8)\n");
          fprintf(stderr, "received: `%.*s'\nexpected: `%s'\n",
                  bytes_read, buf, TRL2);
          exit(1);
      }
  
      bytes_read = 1;
      rv = ap_recv(newsock, buf, &bytes_read);
      if (rv != APR_SUCCESS) {
          fprintf(stderr, "ap_recv()->%d/%s\n",
                  rv,
  		ap_strerror(rv, buf, sizeof buf));
          exit(1);
      }
      if (bytes_read != 0) {
          fprintf(stderr, "We expected the EOF condition on the connected\n"
                  "socket but instead we read %ld bytes.\n",
                  (long int)bytes_read);
          exit(1);
      }
  
      printf("server: ap_sendfile() worked as expected!\n");
  
      return 0;
  }
  
  int main(int argc, char *argv[])
  {
  #ifdef SIGPIPE
      signal(SIGPIPE, SIG_IGN);
  #endif
  
      /* Gee whiz this is goofy logic but I wanna drive sendfile right now, 
       * not dork around with the command line!
       */
      if (argc == 3 && !strcmp(argv[1], "client")) {
          if (!strcmp(argv[2], "blocking")) {
              return client(1);
          }
          else if (!strcmp(argv[2], "nonblocking")) {
              return client(0);
          }
      }
      else if (argc == 2 && !strcmp(argv[1], "server")) {
          return server();
      }
  
      fprintf(stderr, 
              "Usage: %s client {blocking|nonblocking}\n"
              "       %s server\n",
              argv[0], argv[0]);
      return -1;
  }
  
  #endif /* !APR_HAS_SENDFILE */