Beispiel #1
0
int main(int argc, char* argv[]) {
  // Parse any command-line options.
  namespace po = boost::program_options;
  po::options_description desc("Allowed options");
  desc.add_options()
    ("help", "show help")
    ("debug-httpd", po::value<bool>(&mp3d_debug_httpd), "show httpd debug output")
    ("root", po::value<std::string>(&mp3d_music_root), "root of file system mp3 tree")
    ("port", po::value<int>(&mp3d_port), "httpd port number")
  ;
  po::variables_map args;
  po::store(po::parse_command_line(argc, argv, desc), args);
  po::notify(args);
  if (args.count("help")) {
    std::cout << desc << std::endl;
    return 1;
  }

  // Index all the mp3s.
  Paths paths;
  find_mp3_files(mp3d_music_root, paths);
  std::cerr << ".mp3 files found: " << paths.size() << std::endl;

  int old_percentage = -1;
  size_t id = 0;
  for (Paths::const_iterator it = paths.begin(); it != paths.end(); ++it) {
    Mp3Info mp3;
    mp3.filename = (*it).string();

    const ID3_Tag tag(mp3.filename.c_str());

    ID3_Tag::ConstIterator* it = tag.CreateIterator();
    for (size_t i = 0; i < tag.NumFrames(); ++i) {
      const ID3_Frame* frame = it->GetNext();
      if (frame != 0) {
        std::string* dst;
        switch (frame->GetID()) {
        case ID3FID_ALBUM: dst = &mp3.album; break;
        case ID3FID_LEADARTIST: dst = &mp3.artist; break;
        case ID3FID_TITLE: dst = &mp3.title; break;
        default: continue;
        }
        char* text = ID3_GetString(frame, ID3FN_TEXT);
        dst->assign(text);
        ID3_FreeString(text);
      }
    }
    
    // FIXME: maybe a hash, to enable bookmarks?
    mp3.id = id++;
    
    all_mp3s.push_back(mp3);
    
    // Show progress. Not really useful when we're not debugging.
    // FIXME: start the web server straight away, and say "Indexing..." there.
    const int new_percentage = (100*all_mp3s.size())/paths.size();
    if (new_percentage != old_percentage) {
      std::cout << "\rScanned: " << new_percentage << "%" << std::flush;
      old_percentage = new_percentage;
    }
  }
  std::cout << "\r.mp3 files scanned: " << all_mp3s.size() << std::endl;

  // Set up the static files we need to serve.
  read_static_file("/static/add.png",
                   "/usr/share/icons/gnome/16x16/actions/gtk-add.png");
  read_static_file("/static/play.png",
                   "/usr/share/icons/gnome/16x16/actions/gtk-media-play-ltr.png");
  read_static_file("/static/remove.png",
                   "/usr/share/icons/gnome/16x16/actions/gtk-remove.png");
  static_file_map["/static/site.css"] = make_css();
  
  // Start the mp3 player thread.
  boost::thread mp3_player_thread(mp3_play_loop);
  
  // Start the HTTP server.
  std::cerr << "Starting HTTP server on port " << mp3d_port << "..." << std::endl;
  const int mhd_flags = MHD_USE_SELECT_INTERNALLY;
  MHD_Daemon* daemon = MHD_start_daemon(mhd_flags, mp3d_port, 0, 0, &handle_request, 0, MHD_OPTION_END);
  if (daemon == 0) {
    fail("MHD_start_daemon failed!");
  }
  
  getchar(); // Wait for the user to hit enter.
  
  MHD_stop_daemon(daemon);
  //mp3_player_thread.join();
  return 0;
}
Beispiel #2
0
static int
testExternalGet ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket maxsock;
#ifdef MHD_WINSOCK_SOCKETS
  int maxposixs; /* Max socket number unused on W32 */
#else  /* MHD_POSIX_SOCKETS */
#define maxposixs maxsock
#endif /* MHD_POSIX_SOCKETS */
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  int i;
  MHD_socket fd;

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_DEBUG,
                        11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
  if (d == NULL)
    return 256;
  c = setupCURL(&cbc);

  multi = curl_multi_init ();
  if (multi == NULL)
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 512;
    }
  mret = curl_multi_add_handle (multi, c);
  if (mret != CURLM_OK)
    {
      curl_multi_cleanup (multi);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 1024;
    }

  for (i = 0; i < 2; i++) {
    start = time (NULL);
    while ((time (NULL) - start < 5) && (multi != NULL))
      {
        maxsock = MHD_INVALID_SOCKET;
        maxposixs = -1;
        FD_ZERO (&rs);
        FD_ZERO (&ws);
        FD_ZERO (&es);
        curl_multi_perform (multi, &running);
        mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
        if (mret != CURLM_OK)
          {
            curl_multi_remove_handle (multi, c);
            curl_multi_cleanup (multi);
            curl_easy_cleanup (c);
            MHD_stop_daemon (d);
            return 2048;
          }
        if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
          {
            curl_multi_remove_handle (multi, c);
            curl_multi_cleanup (multi);
            curl_easy_cleanup (c);
            MHD_stop_daemon (d);
            return 4096;
          }
        tv.tv_sec = 0;
        tv.tv_usec = 1000;
        select (maxposixs + 1, &rs, &ws, &es, &tv);
        curl_multi_perform (multi, &running);
        if (running == 0)
          {
            msg = curl_multi_info_read (multi, &running);
            if (msg == NULL)
              break;
            if (msg->msg == CURLMSG_DONE)
              {
                if (i == 0 && msg->data.result != CURLE_OK)
                  printf ("%s failed at %s:%d: `%s'\n",
                          "curl_multi_perform",
                          __FILE__,
                          __LINE__, curl_easy_strerror (msg->data.result));
                else if (i == 1 && msg->data.result == CURLE_OK)
                  printf ("%s should have failed at %s:%d\n",
                          "curl_multi_perform",
                          __FILE__,
                          __LINE__);
                curl_multi_remove_handle (multi, c);
                curl_multi_cleanup (multi);
                curl_easy_cleanup (c);
                c = NULL;
                multi = NULL;
              }
          }
        MHD_run (d);
      }

      if (i == 0) {
        /* quiesce the daemon on the 1st iteration, so the 2nd should fail */
        fd = MHD_quiesce_daemon(d);
        if (MHD_INVALID_SOCKET == fd)
          {
            fprintf (stderr,
                     "MHD_quiesce_daemon failed.\n");
            curl_multi_remove_handle (multi, c);
            curl_multi_cleanup (multi);
            curl_easy_cleanup (c);
            MHD_stop_daemon (d);
            return 2;
          }
        c = setupCURL (&cbc);
        multi = curl_multi_init ();
        mret = curl_multi_add_handle (multi, c);
        if (mret != CURLM_OK)
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 32768;
        }
      }
    }
  if (multi != NULL)
    {
      curl_multi_remove_handle (multi, c);
      curl_easy_cleanup (c);
      curl_multi_cleanup (multi);
    }
  MHD_stop_daemon (d);
  MHD_socket_close_ (fd);
  if (cbc.pos != strlen ("/hello_world"))
    return 8192;
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 16384;
  return 0;
}
Beispiel #3
0
static int
testExternalPut ()
{
  struct MHD_Daemon *d;
  CURL *c;
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket maxsock;
#ifdef MHD_WINSOCK_SOCKETS
  int maxposixs; /* Max socket number unused on W32 */
#else  /* MHD_POSIX_SOCKETS */
#define maxposixs maxsock
#endif /* MHD_POSIX_SOCKETS */
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  unsigned int pos = 0;
  int done_flag = 0;
  char buf[2048];

  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  multi = NULL;
  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
                        1082,
                        NULL, NULL, &ahc_echo, &done_flag,
                        MHD_OPTION_CONNECTION_MEMORY_LIMIT,
                        (size_t) (PUT_SIZE * 4), MHD_OPTION_END);
  if (d == NULL)
    return 256;
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
  curl_easy_setopt (c, CURLOPT_READDATA, &pos);
  curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
  curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  if (oneone)
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  else
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
  // NOTE: use of CONNECTTIMEOUT without also
  //   setting NOSIGNAL results in really weird
  //   crashes on my system!
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);


  multi = curl_multi_init ();
  if (multi == NULL)
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 512;
    }
  mret = curl_multi_add_handle (multi, c);
  if (mret != CURLM_OK)
    {
      curl_multi_cleanup (multi);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 1024;
    }
  start = time (NULL);
  while ((time (NULL) - start < 5) && (multi != NULL))
    {
      maxsock = MHD_INVALID_SOCKET;
      maxposixs = -1;
      FD_ZERO (&rs);
      FD_ZERO (&ws);
      FD_ZERO (&es);
      curl_multi_perform (multi, &running);
      mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
      if (mret != CURLM_OK)
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 2048;
        }
      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 4096;
        }
      tv.tv_sec = 0;
      tv.tv_usec = 1000;
      if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
        {
          if (EINTR != errno)
            abort ();
        }
      curl_multi_perform (multi, &running);
      if (running == 0)
        {
          msg = curl_multi_info_read (multi, &running);
          if (msg == NULL)
            break;
          if (msg->msg == CURLMSG_DONE)
            {
              if (msg->data.result != CURLE_OK)
                printf ("%s failed at %s:%d: `%s'\n",
                        "curl_multi_perform",
                        __FILE__,
                        __LINE__, curl_easy_strerror (msg->data.result));
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              c = NULL;
              multi = NULL;
            }
        }
      MHD_run (d);
    }
  if (multi != NULL)
    {
      curl_multi_remove_handle (multi, c);
      curl_easy_cleanup (c);
      curl_multi_cleanup (multi);
    }
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello_world"))
    {
      fprintf (stderr, "Got invalid response `%.*s'\n", (int)cbc.pos, cbc.buf);
      return 8192;
    }
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 16384;
  return 0;
}
static int
testExternalGet ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  int max;
  int running;
  time_t start;
  struct timeval tv;
  int i;

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_DEBUG */ ,
                        11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
  if (d == NULL)
    return 256;
  multi = curl_multi_init ();
  if (multi == NULL)
    {
      MHD_stop_daemon (d);
      return 512;
    }
  zzuf_socat_start ();
  for (i = 0; i < LOOP_COUNT; i++)
    {
      fprintf (stderr, ".");
      c = curl_easy_init ();
      curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11081/hello_world");
      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
      curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
      curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
      curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
      curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
      curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
      // NOTE: use of CONNECTTIMEOUT without also
      //   setting NOSIGNAL results in really weird
      //   crashes on my system!
      curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
      mret = curl_multi_add_handle (multi, c);
      if (mret != CURLM_OK)
        {
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          zzuf_socat_stop ();
          MHD_stop_daemon (d);
          return 1024;
        }
      start = time (NULL);
      while ((time (NULL) - start < 5) && (c != NULL))
        {
          max = 0;
          FD_ZERO (&rs);
          FD_ZERO (&ws);
          FD_ZERO (&es);
          curl_multi_perform (multi, &running);
          mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
          if (mret != CURLM_OK)
            {
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              zzuf_socat_stop ();
              MHD_stop_daemon (d);
              return 2048;
            }
          if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
            {
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              zzuf_socat_stop ();
              MHD_stop_daemon (d);
              return 4096;
            }
          tv.tv_sec = 0;
          tv.tv_usec = 1000;
          select (max + 1, &rs, &ws, &es, &tv);
          curl_multi_perform (multi, &running);
          if (running == 0)
            {
              curl_multi_info_read (multi, &running);
              curl_multi_remove_handle (multi, c);
              curl_easy_cleanup (c);
              c = NULL;
            }
          MHD_run (d);
        }
      if (c != NULL)
        {
          curl_multi_remove_handle (multi, c);
          curl_easy_cleanup (c);
        }
    }
  fprintf (stderr, "\n");
  curl_multi_cleanup (multi);
  zzuf_socat_stop ();
  MHD_stop_daemon (d);
  return 0;
}
static int
testLongUrlGet ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  char *url;
  long code;

  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */ ,
                        1080,
                        &apc_all,
                        NULL,
                        &ahc_echo,
                        "GET",
                        MHD_OPTION_CONNECTION_MEMORY_LIMIT,
                        VERY_LONG / 2, MHD_OPTION_END);
  if (d == NULL)
    return 1;
  c = curl_easy_init ();
  url = malloc (VERY_LONG);
  memset (url, 'a', VERY_LONG);
  url[VERY_LONG - 1] = '\0';
  memcpy (url, "http://localhost:1080/", strlen ("http://localhost:1080/"));
  curl_easy_setopt (c, CURLOPT_URL, url);
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
  if (oneone)
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  else
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  // NOTE: use of CONNECTTIMEOUT without also
  //   setting NOSIGNAL results in really weird
  //   crashes on my system!
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
  if (CURLE_OK == curl_easy_perform (c))
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      free (url);
      return 2;
    }
  if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code))
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      free (url);
      return 4;
    }
  curl_easy_cleanup (c);
  MHD_stop_daemon (d);
  free (url);
  if (code != MHD_HTTP_REQUEST_URI_TOO_LONG)
    return 8;
  return 0;
}
Beispiel #6
0
/* ****************************************************************************
*
* restStart - 
*/
static int restStart(IpVersion ipVersion, const char* httpsKey = NULL, const char* httpsCertificate = NULL)
{
  if (port == 0)
     LM_RE(1, ("Please call restInit before starting the REST service"));

  if ((ipVersion == IPV4) || (ipVersion == IPDUAL)) 
  { 
    memset(&sad, 0, sizeof(sad));
    if (inet_pton(AF_INET, bindIp, &(sad.sin_addr.s_addr)) != 1)
      LM_RE(2, ("V4 inet_pton fail for %s", bindIp));

    sad.sin_family = AF_INET;
    sad.sin_port   = htons(port);

    if ((httpsKey != NULL) && (httpsCertificate != NULL))
    {
      mhdDaemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL, // MHD_USE_SELECT_INTERNALLY
                                   htons(port),
                                   NULL,
                                   NULL,
                                   connectionTreat,                     NULL,
                                   MHD_OPTION_HTTPS_MEM_KEY,            httpsKey,
                                   MHD_OPTION_HTTPS_MEM_CERT,           httpsCertificate,
                                   MHD_OPTION_NOTIFY_COMPLETED,         requestCompleted, NULL,
                                   MHD_OPTION_CONNECTION_MEMORY_LIMIT,  2 * PAYLOAD_SIZE,
                                   MHD_OPTION_SOCK_ADDR,                (struct sockaddr*) &sad,
                                   MHD_OPTION_END);
    }
    else
    {
      LM_V(("Starting HTTP daemon on IPv4 %s port %d", bindIp, port));
      mhdDaemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, // MHD_USE_SELECT_INTERNALLY
                                   htons(port),
                                   NULL,
                                   NULL,
                                   connectionTreat,                     NULL,
                                   MHD_OPTION_NOTIFY_COMPLETED,         requestCompleted, NULL,
                                   MHD_OPTION_CONNECTION_MEMORY_LIMIT,  2 * PAYLOAD_SIZE,
                                   MHD_OPTION_SOCK_ADDR,                (struct sockaddr*) &sad,
                                   MHD_OPTION_END);
    }

    if (mhdDaemon == NULL)
      LM_RE(3, ("MHD_start_daemon failed"));
  }  

  if ((ipVersion == IPV6) || (ipVersion == IPDUAL))
  { 
    memset(&sad_v6, 0, sizeof(sad_v6));
    if (inet_pton(AF_INET6, bindIPv6, &(sad_v6.sin6_addr.s6_addr)) != 1)
      LM_RE(1, ("V6 inet_pton fail for %s", bindIPv6));

    sad_v6.sin6_family = AF_INET6;
    sad_v6.sin6_port = htons(port);

    if ((httpsKey != NULL) && (httpsCertificate != NULL))
    {
      LM_V(("Starting HTTPS daemon on IPv6 %s port %d", bindIPv6, port));
      mhdDaemon_v6 = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_IPv6 | MHD_USE_SSL,
                                      htons(port),
                                      NULL,
                                      NULL,
                                      connectionTreat,                     NULL,
                                      MHD_OPTION_HTTPS_MEM_KEY,            httpsKey,
                                      MHD_OPTION_HTTPS_MEM_CERT,           httpsCertificate,
                                      MHD_OPTION_NOTIFY_COMPLETED,         requestCompleted, NULL,
                                      MHD_OPTION_CONNECTION_MEMORY_LIMIT,  2 * PAYLOAD_SIZE,
                                      MHD_OPTION_SOCK_ADDR,                (struct sockaddr*) &sad_v6,
                                      MHD_OPTION_END);
    }
    else
    {
      LM_V(("Starting HTTP daemon on IPv6 %s port %d", bindIPv6, port));
      mhdDaemon_v6 = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_IPv6,
                                      htons(port),
                                      NULL,
                                      NULL,
                                      connectionTreat,                     NULL,
                                      MHD_OPTION_NOTIFY_COMPLETED,         requestCompleted, NULL,
                                      MHD_OPTION_CONNECTION_MEMORY_LIMIT,  2 * PAYLOAD_SIZE,
                                      MHD_OPTION_SOCK_ADDR,                (struct sockaddr*) &sad_v6,
                                      MHD_OPTION_END);
    }

    if (mhdDaemon_v6 == NULL)
      LM_RE(1, ("MHD_start_daemon_v6 failed"));
  }

  return 0;
}
static int
testExternalPut ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  int max;
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  unsigned int pos = 0;
  int done_flag = 0;

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_DEBUG,
                        11082,
                        NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
  if (d == NULL)
    return 256;
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11082/hello_world");
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
  curl_easy_setopt (c, CURLOPT_READDATA, &pos);
  curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
  /*
     // by not giving the file size, we force chunking!
     curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
   */
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
  // NOTE: use of CONNECTTIMEOUT without also
  //   setting NOSIGNAL results in really weird
  //   crashes on my system!
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);


  multi = curl_multi_init ();
  if (multi == NULL)
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 512;
    }
  mret = curl_multi_add_handle (multi, c);
  if (mret != CURLM_OK)
    {
      curl_multi_cleanup (multi);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 1024;
    }
  start = time (NULL);
  while ((time (NULL) - start < 5) && (multi != NULL))
    {
      max = 0;
      FD_ZERO (&rs);
      FD_ZERO (&ws);
      FD_ZERO (&es);
      curl_multi_perform (multi, &running);
      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
      if (mret != CURLM_OK)
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 2048;
        }
      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 4096;
        }
      tv.tv_sec = 0;
      tv.tv_usec = 1000;
      select (max + 1, &rs, &ws, &es, &tv);
      curl_multi_perform (multi, &running);
      if (running == 0)
        {
          msg = curl_multi_info_read (multi, &running);
          if (msg == NULL)
            break;
          if (msg->msg == CURLMSG_DONE)
            {
              if (msg->data.result != CURLE_OK)
                printf ("%s failed at %s:%d: `%s'\n",
                        "curl_multi_perform",
                        __FILE__,
                        __LINE__, curl_easy_strerror (msg->data.result));
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              c = NULL;
              multi = NULL;
            }
        }
      MHD_run (d);
    }
  if (multi != NULL)
    {
      curl_multi_remove_handle (multi, c);
      curl_easy_cleanup (c);
      curl_multi_cleanup (multi);
    }
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello_world"))
    return 8192;
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 16384;
  return 0;
}
Beispiel #8
0
/**@internal
 * Main execution loop
 */
static void
main_loop(void)
{
	int result = 0;
	pthread_t tid;
	s_config *config;

	config = config_get_config();

	/* Set the time when nodogsplash started */
	if (!started_time) {
		debug(LOG_INFO, "Setting started_time");
		started_time = time(NULL);
	} else if (started_time < MINIMUM_STARTED_TIME) {
		debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time");
		started_time = time(NULL);
	}

	/* If we don't have the Gateway IP address, get it. Exit on failure. */
	if (!config->gw_address) {
		debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface);
		if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) {
			debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface);
			exit(1);
		}
	}
	if ((config->gw_mac = get_iface_mac(config->gw_interface)) == NULL) {
		debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->gw_interface);
		exit(1);
	}
	debug(LOG_NOTICE, "Detected gateway %s at %s (%s)", config->gw_interface, config->gw_address, config->gw_mac);

	/* Initializes the web server */
	if ((webserver = MHD_start_daemon(
						MHD_USE_EPOLL_INTERNALLY,
						config->gw_port,
						NULL, NULL,
						libmicrohttpd_cb, NULL,
						MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
						MHD_OPTION_LISTENING_ADDRESS_REUSE, 1,
						MHD_OPTION_END)) == NULL) {
		debug(LOG_ERR, "Could not create web server: %s", strerror(errno));
		exit(1);
	}
	/* TODO: set listening socket */
	debug(LOG_NOTICE, "Created web server on %s:%d", config->gw_address, config->gw_port);
	/*
		httpdAddCContent(webserver, "/", "", 0, NULL, http_nodogsplash_callback_index);
		httpdAddCWildcardContent(webserver, config->authdir, NULL, http_nodogsplash_callback_auth);
		httpdAddCWildcardContent(webserver, config->denydir, NULL, http_nodogsplash_callback_deny);
		httpdAddC404Content(webserver, http_nodogsplash_callback_404);
	*/
	/* Reset the firewall (cleans it, in case we are restarting after nodogsplash crash) */

	fw_destroy();
	/* Then initialize it */
	debug(LOG_NOTICE, "Initializing firewall rules");
	if (fw_init() != 0) {
		debug(LOG_ERR, "Error initializing firewall rules! Cleaning up");
		fw_destroy();
		debug(LOG_ERR, "Exiting because of error initializing firewall rules");
		exit(1);
	}

	/* Start client statistics and timeout clean-up thread */
	result = pthread_create(&tid_client_check, NULL, thread_client_timeout_check, NULL);
	if (result != 0) {
		debug(LOG_ERR, "FATAL: Failed to create thread_client_timeout_check - exiting");
		termination_handler(0);
	}
	pthread_detach(tid_client_check);

	/* Start control thread */
	result = pthread_create(&tid, NULL, thread_ndsctl, (void *)(config->ndsctl_sock));
	if (result != 0) {
		debug(LOG_ERR, "FATAL: Failed to create thread_ndsctl - exiting");
		termination_handler(1);
	}

	result = pthread_join(tid, NULL);
	if (result) {
		debug(LOG_INFO, "Failed to wait for nodogsplash thread.");
	}
	MHD_stop_daemon(webserver);
	termination_handler(result);
}
Beispiel #9
0
/* ****************************************************************************
*
* restStart - 
*/
static int restStart(IpVersion ipVersion, const char* httpsKey = NULL, const char* httpsCertificate = NULL)
{
  bool   mhdStartError = true;
  size_t memoryLimit   = 2 * PAYLOAD_SIZE;

  if (port == 0)
  {
    LM_X(1, ("Fatal Error (please call restInit before starting the REST service)"));
  }

  if ((ipVersion == IPV4) || (ipVersion == IPDUAL))
  { 
    memset(&sad, 0, sizeof(sad));
    if (inet_pton(AF_INET, bindIp, &(sad.sin_addr.s_addr)) != 1)
    {
      LM_X(2, ("Fatal Error (V4 inet_pton fail for %s)", bindIp));
    }

    sad.sin_family = AF_INET;
    sad.sin_port   = htons(port);

    if ((httpsKey != NULL) && (httpsCertificate != NULL))
    {
      LM_T(LmtMhd, ("Starting HTTPS daemon on IPv4 %s port %d", bindIp, port));
      mhdDaemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL, // MHD_USE_SELECT_INTERNALLY
                                   htons(port),
                                   NULL,
                                   NULL,
                                   connectionTreat,                     NULL,
                                   MHD_OPTION_HTTPS_MEM_KEY,            httpsKey,
                                   MHD_OPTION_HTTPS_MEM_CERT,           httpsCertificate,
                                   MHD_OPTION_CONNECTION_MEMORY_LIMIT,  memoryLimit,
                                   MHD_OPTION_SOCK_ADDR,                (struct sockaddr*) &sad,
                                   MHD_OPTION_NOTIFY_COMPLETED,         requestCompleted, NULL,
                                   MHD_OPTION_END);

    }
    else
    {
      LM_T(LmtMhd, ("Starting HTTP daemon on IPv4 %s port %d", bindIp, port));
      mhdDaemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, // MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG
                                   htons(port),
                                   NULL,
                                   NULL,
                                   connectionTreat,                     NULL,
                                   MHD_OPTION_CONNECTION_MEMORY_LIMIT,  memoryLimit,
                                   MHD_OPTION_SOCK_ADDR,                (struct sockaddr*) &sad,
                                   MHD_OPTION_NOTIFY_COMPLETED,         requestCompleted, NULL,
                                   MHD_OPTION_END);

    }

    if (mhdDaemon != NULL)
    {
      mhdStartError = false;
    }
  }  

  if ((ipVersion == IPV6) || (ipVersion == IPDUAL))
  { 
    memset(&sad_v6, 0, sizeof(sad_v6));
    if (inet_pton(AF_INET6, bindIPv6, &(sad_v6.sin6_addr.s6_addr)) != 1)
    {
      LM_X(4, ("Fatal Error (V6 inet_pton fail for %s)", bindIPv6));
    }

    sad_v6.sin6_family = AF_INET6;
    sad_v6.sin6_port = htons(port);

    if ((httpsKey != NULL) && (httpsCertificate != NULL))
    {
      LM_T(LmtMhd, ("Starting HTTPS daemon on IPv6 %s port %d", bindIPv6, port));
      mhdDaemon_v6 = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_IPv6 | MHD_USE_SSL,
                                      htons(port),
                                      NULL,
                                      NULL,
                                      connectionTreat,                     NULL,
                                      MHD_OPTION_HTTPS_MEM_KEY,            httpsKey,
                                      MHD_OPTION_HTTPS_MEM_CERT,           httpsCertificate,
                                      MHD_OPTION_CONNECTION_MEMORY_LIMIT,  memoryLimit,
                                      MHD_OPTION_SOCK_ADDR,                (struct sockaddr*) &sad_v6,
                                      MHD_OPTION_NOTIFY_COMPLETED,         requestCompleted, NULL,
                                      MHD_OPTION_END);
    }
    else
    {
      LM_T(LmtMhd, ("Starting HTTP daemon on IPv6 %s port %d", bindIPv6, port));
      mhdDaemon_v6 = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_IPv6,
                                      htons(port),
                                      NULL,
                                      NULL,
                                      connectionTreat,                     NULL,
                                      MHD_OPTION_CONNECTION_MEMORY_LIMIT,  memoryLimit,
                                      MHD_OPTION_SOCK_ADDR,                (struct sockaddr*) &sad_v6,
                                      MHD_OPTION_NOTIFY_COMPLETED,         requestCompleted, NULL,
                                      MHD_OPTION_END);
    }

    if (mhdDaemon_v6 != NULL)
    {
      mhdStartError = false;
    }
  }


  if (mhdStartError == true)
  {
    LM_X(5, ("Fatal Error (error starting REST interface)"));
  }

  return 0;
}
static int
testMultithreadedPoolPost ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLcode errornum;
  int i;
  char url[1024];
  int port;

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    {
      port = 1352;
      if (oneone)
        port += 10;
    }

  cbc.buf = buf;
  cbc.size = 2048;
  d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
                        port, NULL, NULL, &ahc_echo, NULL,
                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
  if (d == NULL)
    return 16;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }
  for (i = 0; i < LOOPCOUNT; i++)
    {
      if (99 == i % 100)
        fprintf (stderr, ".");
      c = curl_easy_init ();
      cbc.pos = 0;
      buf[0] = '\0';
      snprintf (url,
                sizeof (url),
                "http://127.0.0.1:%d/hw%d",
                port,
                i);
      curl_easy_setopt (c, CURLOPT_URL, url);
      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
      curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
      curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
      curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
      curl_easy_setopt (c, CURLOPT_POST, 1L);
      curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
      curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
      if (oneone)
        curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
      else
        curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
      curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
      /* NOTE: use of CONNECTTIMEOUT without also
       *   setting NOSIGNAL results in really weird
       *   crashes on my system! */
      curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
      if (CURLE_OK != (errornum = curl_easy_perform (c)))
        {
          fprintf (stderr,
                   "curl_easy_perform failed: `%s'\n",
                   curl_easy_strerror (errornum));
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 32;
        }
      curl_easy_cleanup (c);
      if ((buf[0] != 'O') || (buf[1] != 'K'))
        {
          MHD_stop_daemon (d);
          return 64;
        }
    }
  MHD_stop_daemon (d);
  if (LOOPCOUNT >= 99)
    fprintf (stderr, "\n");
  return 0;
}
static int
testExternalPost ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket maxsock;
#ifdef MHD_WINSOCK_SOCKETS
  int maxposixs; /* Max socket number unused on W32 */
#else  /* MHD_POSIX_SOCKETS */
#define maxposixs maxsock
#endif /* MHD_POSIX_SOCKETS */
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  int i;
  unsigned long long timeout;
  long ctimeout;
  char url[1024];
  int port;

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    {
      port = 1353;
      if (oneone)
        port += 10;
    }

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
                        port, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
  if (d == NULL)
    return 256;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }
  multi = curl_multi_init ();
  if (multi == NULL)
    {
      MHD_stop_daemon (d);
      return 512;
    }
  for (i = 0; i < LOOPCOUNT; i++)
    {
      if (99 == i % 100)
	fprintf (stderr, ".");
      c = curl_easy_init ();
      cbc.pos = 0;
      buf[0] = '\0';
      snprintf (url,
                sizeof (url),
                "http://127.0.0.1:%d/hw%d",
                port,
                i);
      curl_easy_setopt (c, CURLOPT_URL, url);
      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
      curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
      curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
      curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
      curl_easy_setopt (c, CURLOPT_POST, 1L);
      curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
      curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
      if (oneone)
        curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
      else
        curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
      curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
      /* NOTE: use of CONNECTTIMEOUT without also
       *   setting NOSIGNAL results in really weird
       *   crashes on my system! */
      curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
      mret = curl_multi_add_handle (multi, c);
      if (mret != CURLM_OK)
        {
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 1024;
        }
      start = time (NULL);
      while ((time (NULL) - start < 5) && (multi != NULL))
        {
          maxsock = MHD_INVALID_SOCKET;
          maxposixs = -1;
          FD_ZERO (&rs);
          FD_ZERO (&ws);
          FD_ZERO (&es);
          while (CURLM_CALL_MULTI_PERFORM ==
                 curl_multi_perform (multi, &running));
          mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
          if (mret != CURLM_OK)
            {
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              MHD_stop_daemon (d);
              return 2048;
            }
          if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
            {
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              MHD_stop_daemon (d);
              return 4096;
            }
          if (MHD_NO == MHD_get_timeout (d, &timeout))
            timeout = 100;      /* 100ms == INFTY -- CURL bug... */
          if ((CURLM_OK == curl_multi_timeout (multi, &ctimeout)) &&
              (ctimeout < (long long)timeout) && (ctimeout >= 0))
            timeout = ctimeout;
	  if ( (c == NULL) || (running == 0) )
	    timeout = 0; /* terminate quickly... */
          tv.tv_sec = timeout / 1000;
          tv.tv_usec = (timeout % 1000) * 1000;
          if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
	    {
	      if (EINTR == errno)
		continue;
	      fprintf (stderr,
		       "select failed: %s\n",
		       strerror (errno));
	      break;
	    }
          while (CURLM_CALL_MULTI_PERFORM ==
                 curl_multi_perform (multi, &running));
          if (running == 0)
            {
              msg = curl_multi_info_read (multi, &running);
              if (msg == NULL)
                break;
              if (msg->msg == CURLMSG_DONE)
                {
                  if (msg->data.result != CURLE_OK)
                    printf ("%s failed at %s:%d: `%s'\n",
                            "curl_multi_perform",
                            __FILE__,
                            __LINE__, curl_easy_strerror (msg->data.result));
                  curl_multi_remove_handle (multi, c);
                  curl_easy_cleanup (c);
                  c = NULL;
                }
            }
          MHD_run (d);
        }
      if (c != NULL)
        {
          curl_multi_remove_handle (multi, c);
          curl_easy_cleanup (c);
        }
      if ((buf[0] != 'O') || (buf[1] != 'K'))
        {
          curl_multi_cleanup (multi);
          MHD_stop_daemon (d);
          return 8192;
        }
    }
  curl_multi_cleanup (multi);
  MHD_stop_daemon (d);
  if (LOOPCOUNT >= 99)
    fprintf (stderr, "\n");
  return 0;
}
Beispiel #12
0
/**
 * Main function
 * @param argc : number of arguments given on the command line.
 * @param argv : an array of strings that contains command line arguments.
 * @returns always 0
 */
int main(int argc, char **argv)
{
    server_struct_t *server_struct = NULL;  /** main structure for 'server' program.           */
    guint id_int = 0;
    guint id_term = 0;

    #if !GLIB_CHECK_VERSION(2, 36, 0)
        g_type_init();  /** g_type_init() is deprecated since glib 2.36 */
    #endif

    ignore_sigpipe(); /** into order to get libmicrohttpd portable */

    init_international_languages();

    server_struct = init_server_main_structure(argc, argv);

    if (server_struct != NULL && server_struct->opt != NULL && server_struct->backend != NULL)
        {
            server_struct->loop = g_main_loop_new(g_main_context_default(), FALSE);
            id_int = g_unix_signal_add(SIGINT, int_signal_handler, server_struct);
            id_term = g_unix_signal_add(SIGTERM, int_signal_handler, server_struct);

            if (id_int <= 0 || id_term <= 0)
                {
                    print_error(__FILE__, __LINE__, _("Unable to add signal handler\n"));
                }

            /* Initializing the choosen backend by calling it's function */
            if (server_struct->backend->init_backend != NULL)
                {
                   server_struct->backend->init_backend(server_struct);
                }

            /* Before starting anything else, start the threads */
            server_struct->meta_thread = g_thread_new("meta-data", meta_data_thread, server_struct);
            server_struct->data_thread = g_thread_new("data", data_thread, server_struct);

            /* Starting the libmicrohttpd daemon */
            server_struct->d = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, server_struct->opt->port, NULL, NULL, &ahc, server_struct, MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) 131070 , MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120, MHD_OPTION_END);

            if (server_struct->d == NULL)
                {
                    print_error(__FILE__, __LINE__, _("Error while spawning libmicrohttpd daemon\n"));
                    return 1;
                }

            /* Unless on error we will never join the threads as they
             * contain a while (TRUE) loop !
             */
            g_main_loop_run(server_struct->loop);

            /* g_thread_join(server_struct->meta_thread); */
            /* g_thread_join(server_struct->data_thread); */


        }
    else
        {
            print_error(__FILE__, __LINE__, _("Error: initialization failed.\n"));
        }

    return 0;
}
Beispiel #13
0
static int
testExternalGet (int port)
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket max;
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  unsigned int i;
  char url[64];

  sprintf(url, "http://127.0.0.1:%d/hello_world", port);

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  d = MHD_start_daemon (MHD_USE_DEBUG,
                        port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
  if (d == NULL)
    return 256;
  start_timer ();
  multi = curl_multi_init ();
  if (multi == NULL)
    {
      MHD_stop_daemon (d);
      return 512;
    }
  for (i=0;i<ROUNDS;i++)
    {
      cbc.pos = 0;
      c = curl_easy_init ();
      curl_easy_setopt (c, CURLOPT_URL, url);
      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
      curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
      curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
      if (oneone)
	curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
      else
	curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
      curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
      curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
      /* NOTE: use of CONNECTTIMEOUT without also
	 setting NOSIGNAL results in really weird
	 crashes on my system! */
      curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
      mret = curl_multi_add_handle (multi, c);
      if (mret != CURLM_OK)
	{
	  curl_multi_cleanup (multi);
	  curl_easy_cleanup (c);
	  MHD_stop_daemon (d);
	  return 1024;
	}
      start = time (NULL);
      while ((time (NULL) - start < 5) && (c != NULL))
	{
	  max = 0;
	  FD_ZERO (&rs);
	  FD_ZERO (&ws);
	  FD_ZERO (&es);
	  curl_multi_perform (multi, &running);
	  mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
	  if (mret != CURLM_OK)
	    {
	      curl_multi_remove_handle (multi, c);
	      curl_multi_cleanup (multi);
	      curl_easy_cleanup (c);
	      MHD_stop_daemon (d);
	      return 2048;
	    }
	  if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
	    {
	      curl_multi_remove_handle (multi, c);
	      curl_multi_cleanup (multi);
	      curl_easy_cleanup (c);
	      MHD_stop_daemon (d);
	      return 4096;
	    }
	  tv.tv_sec = 0;
	  tv.tv_usec = 1000;
	  select (max + 1, &rs, &ws, &es, &tv);
	  curl_multi_perform (multi, &running);
	  if (running == 0)
	    {
	      msg = curl_multi_info_read (multi, &running);
	      if (msg == NULL)
		break;
	      if (msg->msg == CURLMSG_DONE)
		{
		  if (msg->data.result != CURLE_OK)
		    printf ("%s failed at %s:%d: `%s'\n",
			    "curl_multi_perform",
			    __FILE__,
			    __LINE__, curl_easy_strerror (msg->data.result));
		  curl_multi_remove_handle (multi, c);
		  curl_easy_cleanup (c);
		  c = NULL;
		}
	    }
	  /* two possibilities here; as select sets are
	     tiny, this makes virtually no difference
	     in actual runtime right now, even though the
	     number of select calls is virtually cut in half
	     (and 'select' is the most expensive of our system
	     calls according to 'strace') */
	  if (0)
	    MHD_run (d);
	  else
	    MHD_run_from_select (d, &rs, &ws, &es);
	}
      if (NULL != c)
	{
	  curl_multi_remove_handle (multi, c);
	  curl_easy_cleanup (c);
	  fprintf (stderr, "Timeout!?\n");
	}
    }
  stop ("external select");
  if (multi != NULL)
    {
      curl_multi_cleanup (multi);
    }
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello_world"))
    return 8192;
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 16384;
  return 0;
}
Beispiel #14
0
static int
testInternalSelectGet ()
{
    struct MHD_Daemon *d;
    CURL *c;
    char buf[2048];
    struct CBC cbc;
    CURLM *multi;
    CURLMcode mret;
    fd_set rs;
    fd_set ws;
    fd_set es;
    MHD_socket max;
    int running;
    struct CURLMsg *msg;
    time_t start;
    struct timeval tv;

    multi = NULL;
    cbc.buf = buf;
    cbc.size = 2048;
    cbc.pos = 0;
    d = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL | MHD_USE_SELECT_INTERNALLY,
                          1082, NULL, NULL, &ahc_echo, "GET",
                          MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
                          MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
                          MHD_OPTION_END);
    if (d == NULL)
        return 256;

    char *aes256_sha = "AES256-SHA";
    if (curl_uses_nss_ssl() == 0)
    {
        aes256_sha = "rsa_aes_256_sha";
    }

    c = curl_easy_init ();
    curl_easy_setopt (c, CURLOPT_URL, "https://127.0.0.1:1082/hello_world");
    curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
    curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
    /* TLS options */
    curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
    curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, aes256_sha);
    curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
    curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
    curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
    if (oneone)
        curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    else
        curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
    curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
    curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
    /* NOTE: use of CONNECTTIMEOUT without also
       setting NOSIGNAL results in really weird
       crashes on my system! */
    curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);


    multi = curl_multi_init ();
    if (multi == NULL)
    {
        curl_easy_cleanup (c);
        MHD_stop_daemon (d);
        return 512;
    }
    mret = curl_multi_add_handle (multi, c);
    if (mret != CURLM_OK)
    {
        curl_multi_cleanup (multi);
        curl_easy_cleanup (c);
        MHD_stop_daemon (d);
        return 1024;
    }
    start = time (NULL);
    while ((time (NULL) - start < 5) && (multi != NULL))
    {
        max = 0;
        FD_ZERO (&rs);
        FD_ZERO (&ws);
        FD_ZERO (&es);
        mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
        if (mret != CURLM_OK)
        {
            curl_multi_remove_handle (multi, c);
            curl_multi_cleanup (multi);
            curl_easy_cleanup (c);
            MHD_stop_daemon (d);
            return 2048;
        }
        tv.tv_sec = 0;
        tv.tv_usec = 1000;
        select (max + 1, &rs, &ws, &es, &tv);
        curl_multi_perform (multi, &running);
        if (running == 0)
        {
            msg = curl_multi_info_read (multi, &running);
            if (msg == NULL)
                break;
            if (msg->msg == CURLMSG_DONE)
            {
                if (msg->data.result != CURLE_OK)
                    printf ("%s failed at %s:%d: `%s'\n",
                            "curl_multi_perform",
                            __FILE__,
                            __LINE__, curl_easy_strerror (msg->data.result));
                curl_multi_remove_handle (multi, c);
                curl_multi_cleanup (multi);
                curl_easy_cleanup (c);
                c = NULL;
                multi = NULL;
            }
        }
    }
    if (multi != NULL)
    {
        curl_multi_remove_handle (multi, c);
        curl_easy_cleanup (c);
        curl_multi_cleanup (multi);
    }
    MHD_stop_daemon (d);
    if (cbc.pos != 0)
        return 8192;
    return 0;
}
Beispiel #15
0
static int
testLongHeaderGet ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  char *url;
  long code;
  struct curl_slist *header = NULL;

  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */ ,
                        1080,
                        &apc_all,
                        NULL,
                        &ahc_echo,
                        "GET",
                        MHD_OPTION_CONNECTION_MEMORY_LIMIT,
                        (size_t) (VERY_LONG / 2), MHD_OPTION_END);
  if (d == NULL)
    return 16;
  c = curl_easy_init ();
  url = malloc (VERY_LONG);
  if (url == NULL)
     {
	MHD_stop_daemon (d);
	return 16;
     }
  memset (url, 'a', VERY_LONG);
  url[VERY_LONG - 1] = '\0';
  url[VERY_LONG / 2] = ':';
  url[VERY_LONG / 2 + 1] = ' ';
  header = curl_slist_append (header, url);

  curl_easy_setopt (c, CURLOPT_HTTPHEADER, header);
  curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1080/hello_world");
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
  if (oneone)
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  else
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  /* NOTE: use of CONNECTTIMEOUT without also
     setting NOSIGNAL results in really weird
     crashes on my system! */
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
  if (CURLE_OK == curl_easy_perform (c))
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      curl_slist_free_all (header);
      free (url);
      return 32;
    }
  if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code))
    {
      curl_slist_free_all (header);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      free (url);
      return 64;
    }
  curl_slist_free_all (header);
  curl_easy_cleanup (c);
  MHD_stop_daemon (d);
  free (url);
  if (code != MHD_HTTP_REQUEST_ENTITY_TOO_LARGE)
    return 128;
  return 0;
}
static int
testMultithreadedPoolPost ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLcode errornum;
  int i;
  char url[1024];

  cbc.buf = buf;
  cbc.size = 2048;
  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
                        1081, NULL, NULL, &ahc_echo, NULL,
                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
  if (d == NULL)
    return 16;
  for (i = 0; i < LOOPCOUNT; i++)
    {
      if (99 == i % 100)
        fprintf (stderr, ".");
      c = curl_easy_init ();
      cbc.pos = 0;
      buf[0] = '\0';
      sprintf (url, "http://127.0.0.1:1081/hw%d", i);
      curl_easy_setopt (c, CURLOPT_URL, url);
      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
      curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
      curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
      curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
      curl_easy_setopt (c, CURLOPT_POST, 1L);
      curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
      curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
      if (oneone)
        curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
      else
        curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
      curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
      // NOTE: use of CONNECTTIMEOUT without also
      //   setting NOSIGNAL results in really weird
      //   crashes on my system!
      curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
      if (CURLE_OK != (errornum = curl_easy_perform (c)))
        {
          fprintf (stderr,
                   "curl_easy_perform failed: `%s'\n",
                   curl_easy_strerror (errornum));
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 32;
        }
      curl_easy_cleanup (c);
      if ((buf[0] != 'O') || (buf[1] != 'K'))
        {
          MHD_stop_daemon (d);
          return 64;
        }
    }
  MHD_stop_daemon (d);
  if (LOOPCOUNT >= 99)
    fprintf (stderr, "\n");
  return 0;
}
Beispiel #17
0
int main(int argc,char *argv[])
{
	extern char *optarg;
	extern int optind;
	int ch;

	struct option long_options[] = {
		{"help", no_argument, 0, 'h'},
		{"version", no_argument, 0, 'V'},
		{"debug", no_argument, 0, 'd'},
		{"quiet", no_argument, 0, 'q'},
		{"log", required_argument, 0, 'l'},
		{"command", required_argument, 0, 'c'},
#ifdef HAVE_LIBMICROHTTPD
		{"port", required_argument, 0, 'p'},
#endif
		{0, 0, 0, 0}
	};

	int contest_offset;

	char *tmp;
	char buf[BUF_SIZE];
	int ttylog,lu,i,q;
	struct winsize ws;

#ifdef HAVE_LIBMICROHTTPD
	unsigned int port = 0;
#endif

	regmatch_t pmatch[2];

	char defcmd[] = "dnetc", logfile[128] = "stdout";
	int pos_cpu[MAX_CPU];
	char p[] = "a";
	int log_fd;

	/* check arguments */
#ifdef HAVE_LIBMICROHTTPD
	while ((ch = getopt_long(argc, argv, "hdVql:c:p:", long_options, NULL)) != -1)
#else
	while ((ch = getopt_long(argc, argv, "hdVql:c:", long_options, NULL)) != -1)
#endif
	{
		switch(ch)
		{
			case 'd':
				dflag = 1;
				break;
			case 'V':
				printf("%s\n",GKRELLDNET_VERSION);
				exit(0);
				break;
#ifdef HAVE_LIBMICROHTTPD
			case 'p':
				port = atoi(optarg);
				break;
#endif
			case 'q':
				qflag = 1;
				break;
			case 'c':
				nargc = get_arg(&nargv,optarg);
				break;
			case 'l':
				strcpy(logfile,optarg);
				break;
			case 'h':
			default:
				usage(argv[0]);
		}
	}
	if(argc - optind != 0)
		usage(argv[0]);

	/* continue in background if in quiet mode */
	if(qflag == 1 && ((new_pid = fork()) != 0))
	{
		if(new_pid < 0)
			clean_and_exit("forking daemon",1);
		else
			exit(0);
	}

	/* default command line */
	if(nargv == NULL)
		nargc = get_arg(&nargv,defcmd);

	/* change output to logfile */
	if(strcmp(logfile,"stdout") != 0)
	{
		if((log_fd = open(logfile, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
			clean_and_exit("opening logfile",1);
		if(dup2(log_fd,1) == -1)
			clean_and_exit("dup2",1);
	}
	ttylog = isatty(1);

	/* creat shared memory segment */
	if((shmid = my_shmcreate(sizeof(struct dnetc_values),IPC_CREAT|IPC_EXCL|0644)) == -1)
		clean_and_exit("shmget",1);
	if((int) (shmem = shmat(shmid,0,0)) == -1)
		clean_and_exit("shmat",1);

	/* init shared memory content */
	shmem->running = TRUE;
	strcpy(shmem->contest,"???");
	shmem->cmode = CRUNCH_RELATIVE;
	shmem->wu_in = shmem->wu_out = 0;
	shmem->n_cpu = 1;
	for(i=0;i<MAX_CPU;i++)
		shmem->val_cpu[i] = 0;
	
	/* precompile regex */
	if(regcomp(&preg_in,"[0-9]+.packets?.+remains?.in",REG_EXTENDED) != 0)
		clean_and_exit(NULL,1);
	if(regcomp(&preg_out,"[0-9]+.packets?(.+in.buff-out|.\\(.+stats?.units?\\).(are|is).in)",REG_EXTENDED) != 0)
		clean_and_exit(NULL,1);
	if(regcomp(&preg_contest,"[A-Z0-9-]{3,6}(.#[a-z])?:.Loaded",REG_EXTENDED) != 0)
		clean_and_exit(NULL,1);
	if(regcomp(&preg_proxy,"((Retrieved|Sent).+(stat..unit|packet)|Attempting.to.resolve|Connect(ing|ed).to)",REG_EXTENDED) !=0)
		clean_and_exit(NULL,1);

	contest_offset = 0;

	if(regcomp(&preg_absolute,"(#[0-9]+: [A-Z0-9-]{3,6}|[A-Z0-9-]{3,6}(.#[a-z])?):.+\\[[,0-9]+\\]",REG_EXTENDED) != 0)
		clean_and_exit(NULL,1);
	if(regcomp(&preg_cruncher,"[0-9]+.cruncher.*started",REG_EXTENDED) != 0)
		clean_and_exit(NULL,1);
	regex_flag = 1;

	/* obtain a pseudo-terminal */
	ws.ws_col = 132; ws.ws_row = 10;
	ws.ws_xpixel = ws.ws_ypixel = 0;
	if((openpty(&fd,&tty_fd,NULL,NULL,&ws)) == -1)
		clean_and_exit("openpty",1);

	/* start dnet client and start reading tty */
	if((fils = fork()) == -1)
		clean_and_exit("fork",1);

	if(fils == 0)
	{
		/* change to dnetc directory */
		change_dir();
		/* start dnet client */
		if(dup2(tty_fd,1) == -1)
			clean_and_exit("dup2",1);
		if(execvp(nargv[0],nargv) == -1)
			clean_and_exit("execvp",1);
	}

#ifdef HAVE_LIBMICROHTTPD
	/* start http server */
	if(port > 0)
	{
		struct sockaddr_in so;
			
		so.sin_family = AF_INET;
		so.sin_port = htons(port);
		so.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	
	    http_daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, port, NULL, NULL, &answer_to_connection, shmem,
					MHD_OPTION_SOCK_ADDR, &so, MHD_OPTION_END);
	    if(http_daemon == NULL)
	        clean_and_exit("MHD_start_daemon",1);
	}
#endif

	/* set signal handler */
	if(signal(SIGHUP,got_signal) == SIG_ERR
	   || signal(SIGINT,got_signal) == SIG_ERR
	   || signal(SIGQUIT,got_signal) == SIG_ERR
	   || signal(SIGCHLD,got_signal) == SIG_ERR
	   || signal(SIGTERM,got_signal) == SIG_ERR)
		clean_and_exit("signal",1);

	/* some more init */
	for(i=0;i<MAX_CPU;i++)
		shmem->val_cpu[i] = 0;

	/* main loop */
	while((lu = mygets(fd,buf,BUF_SIZE)) > 0)
	{
		if(dflag)
			fprintf(stderr,"buf[0] = %x\n<--\n%s\n-->\n",buf[0],buf);

		if(buf[1] == '.' || buf[lu-1] != '\n')
		{
			if(dflag)
				fprintf(stderr,"lu: %02d, ",lu);

			/* fix line with two 0x0d char */
			if((tmp = strchr(&buf[1],0x0d)) != NULL)
				lu = tmp-buf;

			/* skip line with proxy comm. */
			q = regexec(&preg_proxy,buf,1,pmatch,0);
			if(q != 0)
			{
				/* check if line match absolute crunch-o-meter */
				if(regexec(&preg_absolute,buf,1,pmatch,0) == 0)
				{
					/* set crunch-o-meter mode */
					shmem->cmode = CRUNCH_ABSOLUTE;
					/* read CPU num */
					tmp = strchr(&buf[pmatch[0].rm_so],'#');
					if(tmp != NULL)
					{
						if(isdigit(tmp[1]))
							i = strtol(&buf[pmatch[0].rm_so+1],(char **) NULL,10) - 1;
						else if(islower(tmp[1]))
							i = tmp[1] - 'a';
						/* avoid core dump */
						i %= MAX_CPU;
					}
					else
						i = 0;
					/* read k(keys|nodes) */
					shmem->val_cpu[i] = extract_val(&buf[pmatch[0].rm_so]);
					
					if(dflag)
					{
						fprintf(stderr,"\ncpu = %d, %llu nodes|keys\n",i,shmem->val_cpu[i]);
						fprintf(stderr,"found: %s\n",&buf[pmatch[0].rm_so]);
					}
				}
				else
				{
					/* set crunch-o-meter mode */
					shmem->cmode = CRUNCH_RELATIVE;

					for(i=0;i<shmem->n_cpu;i++)
					{
						if(shmem->n_cpu != 1)
						{
							p[0] = 'a' + i;
							if((tmp = strstr(buf,p)) != NULL)
								pos_cpu[i] = tmp - buf;
						}
						else
							pos_cpu[i] = lu - 1;
						
						shmem->val_cpu[i] = (pos_cpu[i] - (pos_cpu[i]/8)*3) * 2;
						if(shmem->val_cpu[i] > 100)
							shmem->val_cpu[i] = 100;
						
						if(dflag)
							fprintf(stderr,"cpu%d: %llu,",i,shmem->val_cpu[i]);
					}
					if(dflag)
						fprintf(stderr,"\n");
				}
			}

			if(!qflag && (ttylog || q == 0))
			{
				printf("%s",buf); fflush(stdout);
			}
		}
		else
		{
			if(regexec(&preg_in,buf,1,pmatch,0) == 0)
				shmem->wu_in = strtol(&buf[pmatch[0].rm_so],NULL,10);
			if(regexec(&preg_out,buf,1,pmatch,0) == 0)
				shmem->wu_out = strtol(&buf[pmatch[0].rm_so],NULL,10);
			if(regexec(&preg_contest,buf,1,pmatch,0) == 0)
				strncpy(shmem->contest,&buf[pmatch[0].rm_so+contest_offset],3);
			if(regexec(&preg_cruncher,buf,1,pmatch,0) == 0)
			{
				shmem->n_cpu = strtol(&buf[pmatch[0].rm_so],NULL,10);
				/* too many crunchers */
				if(shmem->n_cpu > MAX_CPU)
				{
					fprintf(stderr,"dnetw: too many crunchers\n");
					clean_and_exit(NULL,1);
				}
			}

			if(dflag)
				fprintf(stderr,"contest = %s, in = %d, out = %d, n_cpu = %d\n",shmem->contest, shmem->wu_in, shmem->wu_out, shmem->n_cpu);

			if(!qflag)
			{
				printf("%s",buf); fflush(stdout);
			}
		}

	}

	clean_and_exit(NULL,0);

	return 0;
}
static int
testExternalPost ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket max;
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  int i;
  unsigned long long timeout;
  long ctimeout;
  char url[1024];

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_DEBUG,
                        1082, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
  if (d == NULL)
    return 256;
  multi = curl_multi_init ();
  if (multi == NULL)
    {
      MHD_stop_daemon (d);
      return 512;
    }
  for (i = 0; i < LOOPCOUNT; i++)
    {
      if (99 == i % 100)
	fprintf (stderr, ".");
      c = curl_easy_init ();
      cbc.pos = 0;
      buf[0] = '\0';
      sprintf (url, "http://127.0.0.1:1082/hw%d", i);
      curl_easy_setopt (c, CURLOPT_URL, url);
      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
      curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
      curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
      curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
      curl_easy_setopt (c, CURLOPT_POST, 1L);
      curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
      curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
      if (oneone)
        curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
      else
        curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
      curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
      // NOTE: use of CONNECTTIMEOUT without also
      //   setting NOSIGNAL results in really weird
      //   crashes on my system!
      curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
      mret = curl_multi_add_handle (multi, c);
      if (mret != CURLM_OK)
        {
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 1024;
        }
      start = time (NULL);
      while ((time (NULL) - start < 5) && (multi != NULL))
        {
          max = 0;
          FD_ZERO (&rs);
          FD_ZERO (&ws);
          FD_ZERO (&es);
          while (CURLM_CALL_MULTI_PERFORM ==
                 curl_multi_perform (multi, &running));
          mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
          if (mret != CURLM_OK)
            {
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              MHD_stop_daemon (d);
              return 2048;
            }
          if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
            {
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              MHD_stop_daemon (d);
              return 4096;
            }
          if (MHD_NO == MHD_get_timeout (d, &timeout))
            timeout = 100;      /* 100ms == INFTY -- CURL bug... */
          if ((CURLM_OK == curl_multi_timeout (multi, &ctimeout)) &&
              (ctimeout < timeout) && (ctimeout >= 0))
            timeout = ctimeout;
	  if ( (c == NULL) || (running == 0) )
	    timeout = 0; /* terminate quickly... */
          tv.tv_sec = timeout / 1000;
          tv.tv_usec = (timeout % 1000) * 1000;
          if (-1 == select (max + 1, &rs, &ws, &es, &tv))
	    {
	      if (EINTR == errno)
		continue;
	      fprintf (stderr,
		       "select failed: %s\n",
		       strerror (errno));
	      break;	      
	    }
          while (CURLM_CALL_MULTI_PERFORM ==
                 curl_multi_perform (multi, &running));
          if (running == 0)
            {
              msg = curl_multi_info_read (multi, &running);
              if (msg == NULL)
                break;
              if (msg->msg == CURLMSG_DONE)
                {
                  if (msg->data.result != CURLE_OK)
                    printf ("%s failed at %s:%d: `%s'\n",
                            "curl_multi_perform",
                            __FILE__,
                            __LINE__, curl_easy_strerror (msg->data.result));
                  curl_multi_remove_handle (multi, c);
                  curl_easy_cleanup (c);
                  c = NULL;
                }
            }
          MHD_run (d);
        }
      if (c != NULL)
        {
          curl_multi_remove_handle (multi, c);
          curl_easy_cleanup (c);
        }
      if ((buf[0] != 'O') || (buf[1] != 'K'))
        {
          curl_multi_cleanup (multi);
          MHD_stop_daemon (d);
          return 8192;
        }
    }
  curl_multi_cleanup (multi);
  MHD_stop_daemon (d);
  if (LOOPCOUNT >= 99)
    fprintf (stderr, "\n");
  return 0;
}
Beispiel #19
0
/**
 * Test upgrading a connection.
 *
 * @param flags which event loop style should be tested
 * @param pool size of the thread pool, 0 to disable
 */
static int
test_upgrade (int flags,
              unsigned int pool)
{
  struct MHD_Daemon *d = NULL;
  wr_socket sock;
  struct sockaddr_in sa;
#if defined(HTTPS_SUPPORT) && defined(HAVE_FORK) && defined(HAVE_WAITPID)
  pid_t pid = -1;
#endif /* HTTPS_SUPPORT && HAVE_FORK && HAVE_WAITPID */

  done = 0;

  if (!test_tls)
    d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE,
                        1080,
                        NULL, NULL,
                        &ahc_upgrade, NULL,
                        MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
                        MHD_OPTION_NOTIFY_COMPLETED, &notify_completed_cb, NULL,
                        MHD_OPTION_NOTIFY_CONNECTION, &notify_connection_cb, NULL,
                        MHD_OPTION_THREAD_POOL_SIZE, pool,
                        MHD_OPTION_END);
#ifdef HTTPS_SUPPORT
  else
    d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE | MHD_USE_TLS,
                          1080,
                          NULL, NULL,
                          &ahc_upgrade, NULL,
                          MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
                          MHD_OPTION_NOTIFY_COMPLETED, &notify_completed_cb, NULL,
                          MHD_OPTION_NOTIFY_CONNECTION, &notify_connection_cb, NULL,
                          MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
                          MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
                          MHD_OPTION_THREAD_POOL_SIZE, pool,
                          MHD_OPTION_END);
#endif /* HTTPS_SUPPORT */
  if (NULL == d)
    return 2;
  if (!test_tls || TLS_LIB_GNUTLS == use_tls_tool)
    {
      sock = test_tls ? wr_create_tls_sckt () : wr_create_plain_sckt ();
      if (WR_BAD == sock)
        abort ();
      sa.sin_family = AF_INET;
      sa.sin_port = htons (1080);
      sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
      if (0 != wr_connect (sock,
                        (struct sockaddr *) &sa,
                        sizeof (sa)))
        abort ();
    }
  else
    {
#if defined(HTTPS_SUPPORT) && defined(HAVE_FORK) && defined(HAVE_WAITPID)
      MHD_socket tls_fork_sock;
      if (-1 == (pid = gnutlscli_connect (&tls_fork_sock, 1080)))
        {
          MHD_stop_daemon (d);
          return 4;
        }
      sock =  wr_create_from_plain_sckt (tls_fork_sock);
      if (WR_BAD == sock)
        abort ();
#else  /* !HTTPS_SUPPORT || !HAVE_FORK || !HAVE_WAITPID */
      abort ();
#endif /* !HTTPS_SUPPORT || !HAVE_FORK || !HAVE_WAITPID */
    }

  if (0 != pthread_create (&pt_client,
                           NULL,
                           &run_usock_client,
                           &sock))
    abort ();
  if (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD) )
    run_mhd_loop (d, flags);
  pthread_join (pt_client,
                NULL);
  pthread_join (pt,
                NULL);
#if defined(HTTPS_SUPPORT) && defined(HAVE_FORK) && defined(HAVE_WAITPID)
  if (test_tls && TLS_LIB_GNUTLS != use_tls_tool)
    waitpid (pid, NULL, 0);
#endif /* HTTPS_SUPPORT && HAVE_FORK && HAVE_WAITPID */
  MHD_stop_daemon (d);
  return 0;
}
Beispiel #20
0
/**
 * Entry point to demo.  Note: this HTTP server will make all
 * files in the current directory and its subdirectories available
 * to anyone.  Press ENTER to stop the server once it has started.
 *
 * @param argc number of arguments in argv
 * @param argv first and only argument should be the port number
 * @return 0 on success
 */
int
main (int argc, char *const *argv)
{
  struct MHD_Daemon *d;
  unsigned int port;

  if ( (argc != 2) ||
       (1 != sscanf (argv[1], "%u", &port)) ||
       (UINT16_MAX < port) )
    {
      fprintf (stderr,
	       "%s PORT\n", argv[0]);
      return 1;
    }
  #ifndef MINGW
  ignore_sigpipe ();
  #endif
  magic = magic_open (MAGIC_MIME_TYPE);
  (void) magic_load (magic, NULL);

  (void) pthread_mutex_init (&mutex, NULL);
  file_not_found_response = MHD_create_response_from_buffer (strlen (FILE_NOT_FOUND_PAGE),
							     (void *) FILE_NOT_FOUND_PAGE,
							     MHD_RESPMEM_PERSISTENT);
  mark_as_html (file_not_found_response);
  request_refused_response = MHD_create_response_from_buffer (strlen (REQUEST_REFUSED_PAGE),
							     (void *) REQUEST_REFUSED_PAGE,
							     MHD_RESPMEM_PERSISTENT);
  mark_as_html (request_refused_response);
  internal_error_response = MHD_create_response_from_buffer (strlen (INTERNAL_ERROR_PAGE),
							     (void *) INTERNAL_ERROR_PAGE,
							     MHD_RESPMEM_PERSISTENT);
  mark_as_html (internal_error_response);
  update_directory ();
  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG
#if EPOLL_SUPPORT
			| MHD_USE_EPOLL_LINUX_ONLY
#endif
			,
                        port,
                        NULL, NULL,
			&generate_page, NULL,
			MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (256 * 1024),
#if PRODUCTION
			MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) (64),
#endif
			MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) (120 /* seconds */),
			MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) NUMBER_OF_THREADS,
			MHD_OPTION_NOTIFY_COMPLETED, &response_completed_callback, NULL,
			MHD_OPTION_END);
  if (NULL == d)
    return 1;
  fprintf (stderr, "HTTP server running. Press ENTER to stop the server\n");
  (void) getc (stdin);
  MHD_stop_daemon (d);
  MHD_destroy_response (file_not_found_response);
  MHD_destroy_response (request_refused_response);
  MHD_destroy_response (internal_error_response);
  update_cached_response (NULL);
  (void) pthread_mutex_destroy (&mutex);
  magic_close (magic);
  return 0;
}
int
main (int argc, char *const *argv)
{
  int errorCount = 0;;
  struct MHD_Daemon *d;
  gnutls_session_t session;
  gnutls_datum_t key;
  gnutls_datum_t cert;
  gnutls_certificate_credentials_t xcred;
  int port;
  (void)argc;   /* Unused. Silent compiler warning. */

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    port = 3070;

#ifdef MHD_HTTPS_REQUIRE_GRYPT
  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
#endif /* MHD_HTTPS_REQUIRE_GRYPT */
  gnutls_global_init ();
  gnutls_global_set_log_level (11);

  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS |
                        MHD_USE_ERROR_LOG, port,
                        NULL, NULL, &http_dummy_ahc, NULL,
                        MHD_OPTION_CONNECTION_TIMEOUT, TIME_OUT,
                        MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
                        MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
                        MHD_OPTION_END);

  if (NULL == d)
    {
      fprintf (stderr, MHD_E_SERVER_INIT);
      return -1;
    }
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return -1; }
      port = (int)dinfo->port;
    }

  if (0 != setup_session (&session, &key, &cert, &xcred))
    {
      fprintf (stderr, "failed to setup session\n");
      return 1;
    }
  errorCount += test_tls_session_time_out (session, port);
  teardown_session (session, &key, &cert, xcred);

  print_test_result (errorCount, argv[0]);

  MHD_stop_daemon (d);
  gnutls_global_deinit ();

  return errorCount != 0 ? 1 : 0;
}
Beispiel #22
0
static int
testUnknownPortGet (int poll_flag)
{
  struct MHD_Daemon *d;
  const union MHD_DaemonInfo *di;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLcode errornum;

  struct sockaddr_in addr;
  socklen_t addr_len = sizeof(addr);
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_port = 0;
  addr.sin_addr.s_addr = INADDR_ANY;

  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG  | poll_flag,
                        1, NULL, NULL, &ahc_echo, "GET",
                        MHD_OPTION_SOCK_ADDR, &addr,
                        MHD_OPTION_END);
  if (d == NULL)
    return 32768;

  di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD);
  if (di == NULL)
    return 65536;

  if (0 != getsockname(di->listen_fd, &addr, &addr_len))
    return 131072;

  if (addr.sin_family != AF_INET)
    return 26214;

  snprintf(buf, sizeof(buf), "http://localhost:%hu/hello_world",
           ntohs(addr.sin_port));

  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL, buf);
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
  if (oneone)
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  else
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  /* NOTE: use of CONNECTTIMEOUT without also
     setting NOSIGNAL results in really weird
     crashes on my system! */
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
  if (CURLE_OK != (errornum = curl_easy_perform (c)))
    {
      fprintf (stderr,
               "curl_easy_perform failed: `%s'\n",
               curl_easy_strerror (errornum));
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 524288;
    }
  curl_easy_cleanup (c);
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello_world"))
    return 1048576;
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 2097152;
  return 0;
}
static int
testDigestAuth ()
{
  int fd;
  CURL *c;
  CURLcode errornum;
  struct MHD_Daemon *d;
  struct CBC cbc;
  size_t len;
  size_t off = 0;
  char buf[2048];
  char rnd[8];

  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
#ifndef WINDOWS
  fd = open("/dev/urandom", O_RDONLY);
  if (-1 == fd)
    {
	  fprintf(stderr, "Failed to open `%s': %s\n",
	       "/dev/urandom",
		   strerror(errno));
	  return 1;
	}
  while (off < 8)
	{
	  len = read(fd, rnd, 8);
	  if (len == -1)
	    {
		  fprintf(stderr, "Failed to read `%s': %s\n",
		       "/dev/urandom",
			   strerror(errno));
		  (void) close(fd);
		  return 1;
		}
	  off += len;
	}
  (void) close(fd);
#else
  {
    HCRYPTPROV cc;
    BOOL b;
    b = CryptAcquireContext (&cc, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    if (b == 0)
    {
      fprintf (stderr, "Failed to acquire crypto provider context: %lu\n",
          GetLastError ());
      return 1;
    }
    b = CryptGenRandom (cc, 8, rnd);
    if (b == 0)
    {
      fprintf (stderr, "Failed to generate 8 random bytes: %lu\n",
          GetLastError ());
    }
    CryptReleaseContext (cc, 0);
    if (b == 0)
      return 1;
  }
#endif
  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
                        1337, NULL, NULL, &ahc_echo, PAGE,
			MHD_OPTION_DIGEST_AUTH_RANDOM, sizeof (rnd), rnd,
			MHD_OPTION_NONCE_NC_SIZE, 300,
			MHD_OPTION_END);
  if (d == NULL)
    return 1;
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1337/foo?key=value");
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
  curl_easy_setopt (c, CURLOPT_USERPWD, "testuser:testpass");
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  /* NOTE: use of CONNECTTIMEOUT without also
     setting NOSIGNAL results in really weird
     crashes on my system!*/
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
  if (CURLE_OK != (errornum = curl_easy_perform (c)))
    {
      fprintf (stderr,
               "curl_easy_perform failed: `%s'\n",
               curl_easy_strerror (errornum));
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 2;
    }
  curl_easy_cleanup (c);
  MHD_stop_daemon (d);
  if (cbc.pos != strlen (PAGE))
    return 4;
  if (0 != strncmp (PAGE, cbc.buf, strlen (PAGE)))
    return 8;
  return 0;
}
static int
testExternalGet ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket maxsock;
#ifdef MHD_WINSOCK_SOCKETS
  int maxposixs; /* Max socket number unused on W32 */
#else  /* MHD_POSIX_SOCKETS */
#define maxposixs maxsock
#endif /* MHD_POSIX_SOCKETS */
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  int port;

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    {
      port = 1410;
      if (oneone)
        port += 5;
    }

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
                        port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
  if (d == NULL)
    return 256;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL,
                    "http://127.0.0.1/hello+world?k=v+x&hash=%23foo&space=%A0bar");
  curl_easy_setopt (c, CURLOPT_PORT, (long)port);
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
  if (oneone)
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  else
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
  /* NOTE: use of CONNECTTIMEOUT without also
     setting NOSIGNAL results in really weird
     crashes on my system! */
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);


  multi = curl_multi_init ();
  if (multi == NULL)
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 512;
    }
  mret = curl_multi_add_handle (multi, c);
  if (mret != CURLM_OK)
    {
      curl_multi_cleanup (multi);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 1024;
    }
  start = time (NULL);
  while ((time (NULL) - start < 5) && (multi != NULL))
    {
      maxsock = MHD_INVALID_SOCKET;
      maxposixs = -1;
      FD_ZERO (&rs);
      FD_ZERO (&ws);
      FD_ZERO (&es);
      curl_multi_perform (multi, &running);
      mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
      if (mret != CURLM_OK)
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 2048;
        }
      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 4096;
        }
      tv.tv_sec = 0;
      tv.tv_usec = 1000;
      if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
        {
#ifdef MHD_POSIX_SOCKETS
          if (EINTR != errno)
            abort ();
#else
          if (WSAEINVAL != WSAGetLastError() || 0 != rs.fd_count || 0 != ws.fd_count || 0 != es.fd_count)
            abort ();
          Sleep (1000);
#endif
        }
      curl_multi_perform (multi, &running);
      if (running == 0)
        {
          msg = curl_multi_info_read (multi, &running);
          if (msg == NULL)
            break;
          if (msg->msg == CURLMSG_DONE)
            {
              if (msg->data.result != CURLE_OK)
                printf ("%s failed at %s:%d: `%s'\n",
                        "curl_multi_perform",
                        __FILE__,
                        __LINE__, curl_easy_strerror (msg->data.result));
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              c = NULL;
              multi = NULL;
            }
        }
      MHD_run (d);
    }
  if (multi != NULL)
    {
      curl_multi_remove_handle (multi, c);
      curl_easy_cleanup (c);
      curl_multi_cleanup (multi);
    }
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello+world"))
    return 8192;
  if (0 != strncmp ("/hello+world", cbc.buf, strlen ("/hello+world")))
    return 16384;
  return 0;
}
Beispiel #25
0
static int
testGet (int type, int pool_count, int poll_flag)
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLcode errornum;
  MHD_socket fd;
  pthread_t thrd;
  const char *thrdRet;

  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  if (pool_count > 0) {
    d = MHD_start_daemon (type | MHD_USE_DEBUG | MHD_USE_PIPE_FOR_SHUTDOWN | poll_flag,
                          11080, NULL, NULL, &ahc_echo, "GET",
                          MHD_OPTION_THREAD_POOL_SIZE, pool_count, MHD_OPTION_END);

  } else {
    d = MHD_start_daemon (type | MHD_USE_DEBUG | MHD_USE_PIPE_FOR_SHUTDOWN | poll_flag,
                          11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
  }
  if (d == NULL)
    return 1;

  c = setupCURL(&cbc);

  if (CURLE_OK != (errornum = curl_easy_perform (c)))
    {
      fprintf (stderr,
               "curl_easy_perform failed: `%s'\n",
               curl_easy_strerror (errornum));
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 2;
    }

  if (cbc.pos != strlen ("/hello_world")) {
    curl_easy_cleanup (c);
    MHD_stop_daemon (d);
    return 4;
  }
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) {
    curl_easy_cleanup (c);
    MHD_stop_daemon (d);
    return 8;
  }

  fd = MHD_quiesce_daemon (d);
  if (MHD_INVALID_SOCKET == fd)
    {
      fprintf (stderr,
               "MHD_quiesce_daemon failed.\n");
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 2;
    }
  if (0 != pthread_create(&thrd, NULL, &ServeOneRequest, (void*)(intptr_t) fd))
    {
      fprintf (stderr, "pthread_create failed\n");
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 16;
    }

  cbc.pos = 0;
  if (CURLE_OK != (errornum = curl_easy_perform (c)))
    {
      fprintf (stderr,
               "curl_easy_perform failed: `%s'\n",
               curl_easy_strerror (errornum));
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 2;
    }

  if (0 != pthread_join(thrd, (void**)&thrdRet))
    {
      fprintf (stderr, "pthread_join failed\n");
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 16;
    }
  if (NULL != thrdRet)
    {
      fprintf (stderr, "ServeOneRequest() error: %s\n", thrdRet);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 16;
    }

  if (cbc.pos != strlen ("/hello_world"))
    {
      fprintf(stderr, "%s\n", cbc.buf);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      MHD_socket_close_(fd);
      return 4;
    }
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    {
      fprintf(stderr, "%s\n", cbc.buf);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      MHD_socket_close_(fd);
      return 8;
    }

  /* at this point, the forked server quit, and the new
   * server has quiesced, so new requests should fail
   */
  if (CURLE_OK == (errornum = curl_easy_perform (c)))
    {
      fprintf (stderr, "curl_easy_perform should fail\n");
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      MHD_socket_close_(fd);
      return 2;
    }
  curl_easy_cleanup (c);
  MHD_stop_daemon (d);
  MHD_socket_close_(fd);

  return 0;
}
int main(int argc, char *const *argv)
{
    struct MHD_Daemon *d;

    if (argc != 4) {
        printf("%s PORT DHT-PEER-NAME DHT-PEER-PORT\n", argv[0]);
        return 1;
    }

    printf("Setting up server...\n");

    printf("\n\n[[[ API ]]]\n  GET: /dht/:key\n  POST: /dht with data url-encoded in body\n  DELETE: /dht/:key\n\n");

    // SET UP DHT PEER
    //Resolv hostname to IP Address
    if ((he = gethostbyname(argv[2])) == NULL) {  // get the host info
        herror("gethostbyname");
        printf("Fatal: Couldn't resolve host.");
        exit(1);
    }

    their_addr.sin_family = AF_INET;
    server_port = htons(atoi(argv[3]));
    their_addr.sin_port = server_port;
    their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);
    addrlen = sizeof(their_addr);
    printf("init port with %d\n", their_addr.sin_port);


    // straight from the docs:
  /**
   * Start a webserver on the given port.  Variadic version of
   * #MHD_start_daemon_va.
   *
   * @param flags combination of `enum MHD_FLAG` values
   * @param port port to bind to
   * @param apc callback to call to check which clients
   *        will be allowed to connect; you can pass NULL
   *        in which case connections from any IP will be
   *        accepted
   * @param apc_cls extra argument to apc
   * @param dh handler called for all requests (repeatedly)
   * @param dh_cls extra argument to @a dh
   * @return NULL on error, handle to daemon on success
   * @ingroup event
   */
    port = atoi(argv[1]);
    d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, port, NULL, NULL,
                         &answer_to_connection, NULL, MHD_OPTION_NOTIFY_COMPLETED, request_completed, NULL, MHD_OPTION_END);

    if (d == NULL) {
        return 1;
    }
    printf("DHT REST API started.\nHit any key to shut down...\n\n");

    // wait for input and exit
    getc(stdin);

    printf("Shutdown signal recieved.\n");

    MHD_stop_daemon(d);

    printf("Server shut down.\n\n");
    return 0;
}
Beispiel #27
0
static int
testMultithreadedPoolPut ()
{
  struct MHD_Daemon *d;
  CURL *c;
  struct CBC cbc;
  unsigned int pos = 0;
  int done_flag = 0;
  CURLcode errornum;
  char buf[2048];

  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
                        1081,
                        NULL, NULL, &ahc_echo, &done_flag,
                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT,
			MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (1024*1024),
			MHD_OPTION_END);
  if (d == NULL)
    return 16;
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
  curl_easy_setopt (c, CURLOPT_READDATA, &pos);
  curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
  curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  if (oneone)
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  else
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
  // NOTE: use of CONNECTTIMEOUT without also
  //   setting NOSIGNAL results in really weird
  //   crashes on my system!
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
  if (CURLE_OK != (errornum = curl_easy_perform (c)))
    {
      fprintf (stderr,
               "curl_easy_perform failed: `%s'\n",
               curl_easy_strerror (errornum));
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 32;
    }
  curl_easy_cleanup (c);
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello_world"))
    {
      fprintf (stderr, "Got invalid response `%.*s'\n", (int)cbc.pos, cbc.buf);
      return 64;
    }
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 128;
  return 0;
}
Beispiel #28
0
static int
testExternalGet ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket max;
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_DEBUG,
                        21080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
  if (d == NULL)
    return 256;
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:21080/hello_world");
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  if (oneone)
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  else
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
  /* NOTE: use of CONNECTTIMEOUT without also
     setting NOSIGNAL results in really weird
     crashes on my system! */
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);


  multi = curl_multi_init ();
  if (multi == NULL)
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 512;
    }
  mret = curl_multi_add_handle (multi, c);
  if (mret != CURLM_OK)
    {
      curl_multi_cleanup (multi);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 1024;
    }
  start = time (NULL);
  while ((time (NULL) - start < 5) && (multi != NULL))
    {
      max = 0;
      FD_ZERO (&rs);
      FD_ZERO (&ws);
      FD_ZERO (&es);
      curl_multi_perform (multi, &running);
      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
      if (mret != CURLM_OK)
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 2048;
        }
      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 4096;
        }
      tv.tv_sec = 0;
      tv.tv_usec = 1000;
      select (max + 1, &rs, &ws, &es, &tv);
      curl_multi_perform (multi, &running);
      if (running == 0)
        {
          msg = curl_multi_info_read (multi, &running);
          if (msg == NULL)
            break;
          if (msg->msg == CURLMSG_DONE)
            {
              if (msg->data.result != CURLE_OK)
                printf ("%s failed at %s:%d: `%s'\n",
                        "curl_multi_perform",
                        __FILE__,
                        __LINE__, curl_easy_strerror (msg->data.result));
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              c = NULL;
              multi = NULL;
            }
        }
      MHD_run (d);
    }
  if (multi != NULL)
    {
      curl_multi_remove_handle (multi, c);
      curl_easy_cleanup (c);
      curl_multi_cleanup (multi);
    }
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello_world"))
    return 8192;
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 16384;
  return 0;
}
Beispiel #29
0
void httpd_proc(int rank)
{
#ifdef LIBMICROHTTPD
	int status;
	fd_set rs;
	fd_set ws;
	fd_set es;
	int max;
#endif
	struct httpd_cb *cb = httpd_cb_list;

	/*child's initial settings*/
	if (init_mi_child()!=0) {
		LM_ERR("failed to init the mi child process\n");
		return;
	}

	/* Allocating http response buffer */
	buffer.s = (char*)pkg_malloc(sizeof(char)*buffer.len);
	if (buffer.s==NULL) {
		LM_ERR("oom\n");
		return;
	}

	while(cb) {
		if (cb->init_proc_callback)
			cb->init_proc_callback();
		cb = cb->next;
	}

#ifdef LIBMICROHTTPD
	struct timeval tv;
	struct sockaddr_in saddr_in;

	memset(&saddr_in, 0, sizeof(saddr_in));
	if (ip.s)
		saddr_in.sin_addr.s_addr = inet_addr(ip.s);
	else
		saddr_in.sin_addr.s_addr = INADDR_ANY;
	saddr_in.sin_family = AF_INET;
	saddr_in.sin_port = htons(port);

	LM_DBG("init_child [%d] - [%d] HTTP Server init [%s:%d]\n",
		rank, getpid(), (ip.s?ip.s:"INADDR_ANY"), port);
	set_proc_attrs("HTTPD %s:%d", (ip.s?ip.s:"INADDR_ANY"), port);
	dmn = MHD_start_daemon(MHD_NO_FLAG|MHD_USE_DEBUG, port, NULL, NULL,
			&(answer_to_connection), NULL,
			MHD_OPTION_SOCK_ADDR, &saddr_in,
			MHD_OPTION_END);

	if (NULL == dmn) {
		LM_ERR("unable to start http daemon\n");
		return;
	}

	while(1) {
		max = 0;
		FD_ZERO (&rs);
		FD_ZERO (&ws);
		FD_ZERO (&es);
		if (MHD_YES != MHD_get_fdset (dmn, &rs, &ws, &es, &max)) {
			LM_ERR("unable to get file descriptors\n");
			return;
		}
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		//LM_DBG("select(%d,%p,%p,%p,%p)\n",max+1, &rs, &ws, &es, &tv);
		status = select(max+1, &rs, &ws, &es, &tv);
		switch(status){
		case EBADF:
			LM_ERR("error returned by select: EBADF [%d] "
				"(Bad file descriptor)\n", status);
			return;
			break;
		case EINTR:
			LM_WARN("error returned by select: EINTR [%d] "
				"(Non blocked signal caught)\n", status);
			break;
		case EINVAL:
			LM_ERR("error returned by select: EINVAL [%d] "
				"(Invalid # of fd [%d] or timeout)\n",
				status, max+1);
			return;
			break;
		case ENOMEM:
			LM_ERR("error returned by select: ENOMEM [%d] "
				"(No more memory)\n", status);
			return;
			break;
		default:
			if(status<0){
				switch(errno){
				case EINTR:
					LM_WARN("error returned by select:"
						" [%d] [%d][%s]\n",
						status, errno, strerror(errno));
					break;
				default:
					LM_WARN("error returned by select:"
						" [%d] [%d][%s]\n",
						status, errno, strerror(errno));
					return;
				}
			}
		}
		//LM_DBG("select returned %d\n", status);
		status = MHD_run(dmn);
		if (status == MHD_NO) {
			LM_ERR("unable to run http daemon\n");
			return;
		}
	}
#endif
	LM_DBG("HTTP Server stopped!\n");
}
Beispiel #30
0
static int
testMultithreadedPostCancelPart(int flags)
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLcode errornum;
  struct curl_slist *headers = NULL;
  long response_code;
  CURLcode cc;
  int result = 0;
  struct CRBC crbc;

  /* Don't test features that aren't available with HTTP/1.0 in
   * HTTP/1.0 mode. */
  if (!oneone && (flags & (FLAG_EXPECT_CONTINUE | FLAG_CHUNKED)))
    return 0;

  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
                        1081, NULL, NULL, &ahc_cancel, NULL, 
			MHD_OPTION_END);
  if (d == NULL)
    return 32768;

  crbc.buffer = "Test content";
  crbc.size = strlen(crbc.buffer);
  crbc.pos = 0;
  
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_READFUNCTION, (flags & FLAG_SLOW_READ) ? &slowReadBuffer : &readBuffer);
  curl_easy_setopt (c, CURLOPT_READDATA, &crbc);
  curl_easy_setopt (c, CURLOPT_POSTFIELDS, NULL);
  curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, crbc.size);
  curl_easy_setopt (c, CURLOPT_POST, 1L);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  if (oneone)
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  else
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
  // NOTE: use of CONNECTTIMEOUT without also
  //   setting NOSIGNAL results in really weird
  //   crashes on my system!
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);

  if (flags & FLAG_CHUNKED)
      headers = curl_slist_append(headers, "Transfer-Encoding: chunked");
  if (!(flags & FLAG_FORM_DATA))
  headers = curl_slist_append(headers, "Content-Type: application/octet-stream");
  if (flags & FLAG_EXPECT_CONTINUE)
      headers = curl_slist_append(headers, "Expect: 100-Continue");
  curl_easy_setopt(c, CURLOPT_HTTPHEADER, headers);
  
  if (CURLE_HTTP_RETURNED_ERROR != (errornum = curl_easy_perform (c)))
    {
      fprintf (stderr,
               "flibbet curl_easy_perform didn't fail as expected: `%s' %d\n",
               curl_easy_strerror (errornum), errornum);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      curl_slist_free_all(headers);
      return 65536;
    }
  
  if (CURLE_OK != (cc = curl_easy_getinfo(c, CURLINFO_RESPONSE_CODE, &response_code)))
    {
      fprintf(stderr, "curl_easy_getinfo failed: '%s'\n", curl_easy_strerror(errornum));
      result = 65536;
    }
  
  if (!result && (response_code != 500))
    {
      fprintf(stderr, "Unexpected response code: %ld\n", response_code);
      result = 131072;
    }
  
  if (!result && (cbc.pos != 0))
    result = 262144;

  curl_easy_cleanup (c);
  MHD_stop_daemon (d);
  curl_slist_free_all(headers);
  return result;
}