
#include <stdlib.h>
#include <curl/curl.h>

#define HOST "curl.haxx.se"
#define PROXY "host:port"
#define PROXYUSERPWD ":"

#define URL "http://"HOST

static void init(CURLM *cm, const char* url,const char* userpwd)
{
  CURL *eh = curl_easy_init();
  struct curl_slist* headers = 0;

  curl_easy_setopt(eh, CURLOPT_URL, url);
  curl_easy_setopt(eh, CURLOPT_PROXY, PROXY);
  curl_easy_setopt(eh, CURLOPT_PROXYUSERPWD, userpwd);
  curl_easy_setopt(eh, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
  headers = curl_slist_append(headers,"HOST: " HOST);
  curl_easy_setopt(eh, CURLOPT_HTTPHEADER,headers);

  curl_multi_add_handle(cm, eh);
}

int loop(CURLM *cm,const char* url,const char* userpwd)
{
  CURLMsg *msg;
  long L;
  int M, Q, U = -1;
  fd_set R, W, E;
  int repeat = 2;
  struct timeval T;

  init(cm, url,userpwd);

  while (U) {
    while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(cm, &U));

    if (U) {
      FD_ZERO(&R);
      FD_ZERO(&W);
      FD_ZERO(&E);

      if (curl_multi_fdset(cm, &R, &W, &E, &M)) {
        fprintf(stderr, "E: curl_multi_fdset\n");
        return EXIT_FAILURE;
      }

      /* In a real-world program you OF COURSE check the return that maxfd is
         bigger than -1 so that the call to select() below makes sense! */

      if (curl_multi_timeout(cm, &L)) {
        fprintf(stderr, "E: curl_multi_timeout\n");
        return EXIT_FAILURE;
      }

      T.tv_sec = L/1000;
      T.tv_usec = (L%1000)*1000;

      if (0 > select(M+1, &R, &W, &E, &T)) {
        fprintf(stderr, "E: select\n");
        return EXIT_FAILURE;
      }
    }

    while ((msg = curl_multi_info_read(cm, &Q))) {
      if (msg->msg == CURLMSG_DONE) {
        char *url;
        CURL *e = msg->easy_handle;
        curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
        fprintf(stderr, "R: %d - %s <%s>\n",
                msg->data.result, curl_easy_strerror(msg->data.result), url);
        curl_multi_remove_handle(cm, e);
        curl_easy_cleanup(e);
      }
      else {
        fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
      }
    }
  }

  return 1;
}

int main(int argc,char** argv)
{
  CURLM *cm;

  curl_global_init(CURL_GLOBAL_ALL);

  cm = curl_multi_init();
  loop(cm,URL,PROXYUSERPWD);
  loop(cm,URL,PROXYUSERPWD);

  curl_multi_cleanup(cm);

  curl_global_cleanup();

  return EXIT_SUCCESS;
}
