File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / tests / libtest / libntlmconnect.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:16 2020 UTC (5 years ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    1: /***************************************************************************
    2:  *                                  _   _ ____  _
    3:  *  Project                     ___| | | |  _ \| |
    4:  *                             / __| | | | |_) | |
    5:  *                            | (__| |_| |  _ <| |___
    6:  *                             \___|\___/|_| \_\_____|
    7:  *
    8:  * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
    9:  *
   10:  * This software is licensed as described in the file COPYING, which
   11:  * you should have received as part of this distribution. The terms
   12:  * are also available at https://curl.haxx.se/docs/copyright.html.
   13:  *
   14:  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
   15:  * copies of the Software, and permit persons to whom the Software is
   16:  * furnished to do so, under the terms of the COPYING file.
   17:  *
   18:  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
   19:  * KIND, either express or implied.
   20:  *
   21:  ***************************************************************************/
   22: #include "test.h"
   23: 
   24: #include <limits.h>
   25: #include <assert.h>
   26: 
   27: #include "testutil.h"
   28: #include "warnless.h"
   29: #include "memdebug.h"
   30: 
   31: #define TEST_HANG_TIMEOUT 5 * 1000
   32: #define MAX_EASY_HANDLES 3
   33: 
   34: static int counter[MAX_EASY_HANDLES];
   35: static CURL *easy[MAX_EASY_HANDLES];
   36: static curl_socket_t sockets[MAX_EASY_HANDLES];
   37: static int res = 0;
   38: 
   39: static size_t callback(char *ptr, size_t size, size_t nmemb, void *data)
   40: {
   41:   ssize_t idx = ((CURL **) data) - easy;
   42:   curl_socket_t sock;
   43:   long longdata;
   44:   CURLcode code;
   45:   const size_t failure = (size && nmemb) ? 0 : 1;
   46:   (void)ptr;
   47: 
   48:   counter[idx] += (int)(size * nmemb);
   49: 
   50:   /* Get socket being used for this easy handle, otherwise CURL_SOCKET_BAD */
   51:   code = curl_easy_getinfo(easy[idx], CURLINFO_LASTSOCKET, &longdata);
   52:   if(CURLE_OK != code) {
   53:     fprintf(stderr, "%s:%d curl_easy_getinfo() failed, "
   54:             "with code %d (%s)\n",
   55:             __FILE__, __LINE__, (int)code, curl_easy_strerror(code));
   56:     res = TEST_ERR_MAJOR_BAD;
   57:     return failure;
   58:   }
   59:   if(longdata == -1L)
   60:     sock = CURL_SOCKET_BAD;
   61:   else
   62:     sock = (curl_socket_t)longdata;
   63: 
   64:   if(sock != CURL_SOCKET_BAD) {
   65:     /* Track relationship between this easy handle and the socket. */
   66:     if(sockets[idx] == CURL_SOCKET_BAD) {
   67:       /* An easy handle without previous socket, record the socket. */
   68:       sockets[idx] = sock;
   69:     }
   70:     else if(sock != sockets[idx]) {
   71:       /* An easy handle with a socket different to previously
   72:          tracked one, log and fail right away. Known bug #37. */
   73:       fprintf(stderr, "Handle %d started on socket %d and moved to %d\n",
   74:               curlx_sztosi(idx), (int)sockets[idx], (int)sock);
   75:       res = TEST_ERR_MAJOR_BAD;
   76:       return failure;
   77:     }
   78:   }
   79:   return size * nmemb;
   80: }
   81: 
   82: enum HandleState {
   83:   ReadyForNewHandle,
   84:   NeedSocketForNewHandle,
   85:   NoMoreHandles
   86: };
   87: 
   88: int test(char *url)
   89: {
   90:   CURLM *multi = NULL;
   91:   int running;
   92:   int i;
   93:   int num_handles = 0;
   94:   enum HandleState state = ReadyForNewHandle;
   95:   size_t urllen = strlen(url) + 4 + 1;
   96:   char *full_url = malloc(urllen);
   97: 
   98:   start_test_timing();
   99: 
  100:   if(!full_url) {
  101:     fprintf(stderr, "Not enough memory for full url\n");
  102:     return TEST_ERR_MAJOR_BAD;
  103:   }
  104: 
  105:   for(i = 0; i < MAX_EASY_HANDLES; ++i) {
  106:     easy[i] = NULL;
  107:     sockets[i] = CURL_SOCKET_BAD;
  108:   }
  109: 
  110:   res_global_init(CURL_GLOBAL_ALL);
  111:   if(res) {
  112:     free(full_url);
  113:     return res;
  114:   }
  115: 
  116:   multi_init(multi);
  117: 
  118: #ifdef USE_PIPELINING
  119:   multi_setopt(multi, CURLMOPT_PIPELINING, 1L);
  120:   multi_setopt(multi, CURLMOPT_MAX_HOST_CONNECTIONS, 5L);
  121:   multi_setopt(multi, CURLMOPT_MAX_TOTAL_CONNECTIONS, 10L);
  122: #endif
  123: 
  124:   for(;;) {
  125:     struct timeval interval;
  126:     fd_set fdread;
  127:     fd_set fdwrite;
  128:     fd_set fdexcep;
  129:     long timeout = -99;
  130:     int maxfd = -99;
  131:     bool found_new_socket = FALSE;
  132: 
  133:     /* Start a new handle if we aren't at the max */
  134:     if(state == ReadyForNewHandle) {
  135:       easy_init(easy[num_handles]);
  136: 
  137:       if(num_handles % 3 == 2) {
  138:         msnprintf(full_url, urllen, "%s0200", url);
  139:         easy_setopt(easy[num_handles], CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
  140:       }
  141:       else {
  142:         msnprintf(full_url, urllen, "%s0100", url);
  143:         easy_setopt(easy[num_handles], CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
  144:       }
  145:       easy_setopt(easy[num_handles], CURLOPT_FRESH_CONNECT, 1L);
  146:       easy_setopt(easy[num_handles], CURLOPT_URL, full_url);
  147:       easy_setopt(easy[num_handles], CURLOPT_VERBOSE, 1L);
  148:       easy_setopt(easy[num_handles], CURLOPT_HTTPGET, 1L);
  149:       easy_setopt(easy[num_handles], CURLOPT_USERPWD, "testuser:testpass");
  150:       easy_setopt(easy[num_handles], CURLOPT_WRITEFUNCTION, callback);
  151:       easy_setopt(easy[num_handles], CURLOPT_WRITEDATA, easy + num_handles);
  152:       easy_setopt(easy[num_handles], CURLOPT_HEADER, 1L);
  153: 
  154:       multi_add_handle(multi, easy[num_handles]);
  155:       num_handles += 1;
  156:       state = NeedSocketForNewHandle;
  157:     }
  158: 
  159:     multi_perform(multi, &running);
  160: 
  161:     fprintf(stderr, "%s:%d running %d state %d\n",
  162:             __FILE__, __LINE__, running, state);
  163: 
  164:     abort_on_test_timeout();
  165: 
  166:     if(!running && state == NoMoreHandles)
  167:       break; /* done */
  168: 
  169:     FD_ZERO(&fdread);
  170:     FD_ZERO(&fdwrite);
  171:     FD_ZERO(&fdexcep);
  172: 
  173:     multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
  174: 
  175:     /* At this point, maxfd is guaranteed to be greater or equal than -1. */
  176: 
  177:     if(state == NeedSocketForNewHandle) {
  178:       if(maxfd != -1 && !found_new_socket) {
  179:         fprintf(stderr, "Warning: socket did not open immediately for new "
  180:                 "handle (trying again)\n");
  181:         continue;
  182:       }
  183:       state = num_handles < MAX_EASY_HANDLES ? ReadyForNewHandle
  184:                                              : NoMoreHandles;
  185:       fprintf(stderr, "%s:%d new state %d\n",
  186:               __FILE__, __LINE__, state);
  187:     }
  188: 
  189:     multi_timeout(multi, &timeout);
  190: 
  191:     /* At this point, timeout is guaranteed to be greater or equal than -1. */
  192: 
  193:     fprintf(stderr, "%s:%d num_handles %d timeout %ld running %d\n",
  194:             __FILE__, __LINE__, num_handles, timeout, running);
  195: 
  196:     if(timeout != -1L) {
  197:       int itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
  198:       interval.tv_sec = itimeout/1000;
  199:       interval.tv_usec = (itimeout%1000)*1000;
  200:     }
  201:     else {
  202:       interval.tv_sec = 0;
  203:       interval.tv_usec = 5000;
  204: 
  205:       /* if there's no timeout and we get here on the last handle, we may
  206:          already have read the last part of the stream so waiting makes no
  207:          sense */
  208:       if(!running && num_handles == MAX_EASY_HANDLES) {
  209:         break;
  210:       }
  211:     }
  212: 
  213:     select_test(maxfd + 1, &fdread, &fdwrite, &fdexcep, &interval);
  214: 
  215:     abort_on_test_timeout();
  216:   }
  217: 
  218: test_cleanup:
  219: 
  220:   /* proper cleanup sequence - type PB */
  221: 
  222:   for(i = 0; i < MAX_EASY_HANDLES; i++) {
  223:     printf("Data connection %d: %d\n", i, counter[i]);
  224:     curl_multi_remove_handle(multi, easy[i]);
  225:     curl_easy_cleanup(easy[i]);
  226:   }
  227: 
  228:   curl_multi_cleanup(multi);
  229:   curl_global_cleanup();
  230: 
  231:   free(full_url);
  232: 
  233:   return res;
  234: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>