182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes/***************************************************************************
282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes *                                  _   _ ____  _
382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes *  Project                     ___| | | |  _ \| |
482be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes *                             / __| | | | |_) | |
582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes *                            | (__| |_| |  _ <| |___
682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes *                             \___|\___/|_| \_\_____|
782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes *
882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes *
1082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes * This software is licensed as described in the file COPYING, which
1182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes * you should have received as part of this distribution. The terms
1282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes * are also available at https://curl.haxx.se/docs/copyright.html.
1382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes *
1482be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes * You may opt to use, copy, modify, merge, publish, distribute and/or sell
1582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes * copies of the Software, and permit persons to whom the Software is
1682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes * furnished to do so, under the terms of the COPYING file.
1782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes *
1882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
1982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes * KIND, either express or implied.
2082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes *
2182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes ***************************************************************************/
2282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes#include "test.h"
2382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
2482be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes#include "testutil.h"
2582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes#include "warnless.h"
2682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes#include "memdebug.h"
2782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
2882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughesstruct transfer_status {
2982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  CURL *easy;
3082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  int halted;
3182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  int counter; /* count write callback invokes */
3282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  int please;  /* number of times xferinfo is called while halted */
3382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes};
3482be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
3582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughesstatic int please_continue(void *userp,
3682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes                           curl_off_t dltotal,
3782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes                           curl_off_t dlnow,
3882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes                           curl_off_t ultotal,
3982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes                           curl_off_t ulnow)
4082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes{
4182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  struct transfer_status *st = (struct transfer_status *)userp;
4282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  (void)dltotal;
4382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  (void)dlnow;
4482be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  (void)ultotal;
4582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  (void)ulnow;
4682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  if(st->halted) {
4782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes    st->please++;
4882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes    if(st->please == 2) {
4982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes      /* waited enough, unpause! */
5082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes      curl_easy_pause(st->easy, CURLPAUSE_CONT);
5182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes    }
5282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  }
5382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  fprintf(stderr, "xferinfo: paused %d\n", st->halted);
5482be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  return 0; /* go on */
5582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes}
5682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
5782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughesstatic size_t header_callback(void *ptr, size_t size, size_t nmemb,
5882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes                              void *userp)
5982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes{
6082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  size_t len = size * nmemb;
6182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  (void)userp;
6282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  (void)fwrite(ptr, size, nmemb, stdout);
6382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  return len;
6482be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes}
6582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
6682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughesstatic size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userp)
6782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes{
6882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  struct transfer_status *st = (struct transfer_status *)userp;
6982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  size_t len = size * nmemb;
7082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  st->counter++;
7182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  if(st->counter > 1) {
7282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes    /* the first call puts us on pause, so subsequent calls are after
7382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes       unpause */
7482be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes    fwrite(ptr, size, nmemb, stdout);
7582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes    return len;
7682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  }
7782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  printf("Got %d bytes but pausing!\n", (int)len);
7882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  st->halted = 1;
7982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  return CURL_WRITEFUNC_PAUSE;
8082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes}
8182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
8282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes#define TEST_HANG_TIMEOUT 60 * 1000
8382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
8482be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughesint test(char *URL)
8582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes{
8682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  CURL *curls = NULL;
8782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  int i = 0;
8882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  int res = 0;
8982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  struct transfer_status st;
9082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
9182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  start_test_timing();
9282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
9382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  memset(&st, 0, sizeof(st));
9482be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
9582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  global_init(CURL_GLOBAL_ALL);
9682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
9782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  easy_init(curls);
9882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  st.easy = curls; /* to allow callbacks access */
9982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
10082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  easy_setopt(curls, CURLOPT_URL, URL);
10182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  easy_setopt(curls, CURLOPT_WRITEFUNCTION, write_callback);
10282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  easy_setopt(curls, CURLOPT_WRITEDATA, &st);
10382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  easy_setopt(curls, CURLOPT_HEADERFUNCTION, header_callback);
10482be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  easy_setopt(curls, CURLOPT_HEADERDATA, &st);
10582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
10682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  easy_setopt(curls, CURLOPT_XFERINFOFUNCTION, please_continue);
10782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  easy_setopt(curls, CURLOPT_XFERINFODATA, &st);
10882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  easy_setopt(curls, CURLOPT_NOPROGRESS, 0L);
10982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
11082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  res = curl_easy_perform(curls);
11182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
11282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughestest_cleanup:
11382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
11482be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  curl_easy_cleanup(curls);
11582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  curl_global_cleanup();
11682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
11782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  if(res)
11882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes    i = res;
11982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes
12082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  return i; /* return the final return code */
12182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes}
122