title: Handling HTTP and HTTPS requests with libevent in a same socket
body: <p>Drawing on <a href="https://github.com/ppelleti/https-example" rel="nofollow">https://github.com/ppelleti/https-example</a>, I've tried to define the following code in order to handle (server side) https and http requests. Is there a more simple way to handle https AND http requests in a single listening socket? Thanks in advance</p>
  
  <pre><code>static int serve_some_http (void)
  { struct event_base *base;
    struct evhttp *https, *http;
    struct evhttp_bound_socket *https_handle, *http_handle;
  
    unsigned short port = COMMON_HTTPS_PORT;
  #ifdef _WIN32
    WSADATA WSAData;
    WSAStartup (0x101, &amp;WSAData);
  #endif
  
    base = event_base_new ();
    if (! base)
      { fprintf (stderr, "Couldn't create an event_base: exiting\n");
        return 1;
      }
  
    /* Create a new evhttp object to handle requests. */
    https = evhttp_new (base);
    http  = evhttp_new (base);
    if ((! https)||(! http))
      { fprintf (stderr, "couldn't create evhttp. Exiting.\n");
        return 1;
      }
  
    SSL_CTX *ctx = SSL_CTX_new (SSLv23_server_method ());
    SSL_CTX_set_options (ctx,
                     SSL_OP_SINGLE_DH_USE |
                     SSL_OP_SINGLE_ECDH_USE |
                     SSL_OP_NO_SSLv2);
  
    /* Cheesily pick an elliptic curve to use with elliptic curve ciphersuites.
     * We just hardcode a single curve which is reasonably decent.
     * See http://www.mail-archive.com/openssl-dev@openssl.org/msg30957.html */
    EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
    if (! ecdh)
      die_most_horribly_from_openssl_error ("EC_KEY_new_by_curve_name");
    if (1 != SSL_CTX_set_tmp_ecdh (ctx, ecdh))
      die_most_horribly_from_openssl_error ("SSL_CTX_set_tmp_ecdh");
  
    /* Find and set up our server certificate. */
    const char *certificate_chain = SERVER_CERT_PEM;
    const char *private_key = SERVER_PRIV_PEM;
    server_setup_certs (ctx, certificate_chain, private_key);
  
    /* This is the magic that lets evhttp use SSL. */
    evhttp_set_bevcb (https, bevcb, ctx);
  
    /* This is the callback that gets called when a request comes in. */
    evhttp_set_gencb (https, https_document_cb, NULL);
    evhttp_set_gencb (http, http_document_cb, NULL);
  
    /* Now we tell the evhttp what port to listen on */
    https_handle = evhttp_bind_socket_with_handle (https, "127.0.0.1", port);
    http_handle = evhttp_bind_socket_with_handle (http, "127.0.0.1", port+1);
    if ((! https_handle)||(! http_handle))
      { fprintf (stderr, "couldn't bind to port %d. Exiting.\n", (int) port);
        return 1;
      }
  
    { /* Extract and display the address we're listening on. */
      sock_hop ss, sss;
      evutil_socket_t fds,fd;
      ev_socklen_t socklen = sizeof (ss);
      ev_socklen_t s_socklen = sizeof (ss);
      char addrbuf[128];
      char s_addrbuf[128];
      void *inaddr, *s_inaddr;
      const char *addr, *s_addr;
      int got_port = -1;
      int s_got_port = -1;
  
  
      fds = evhttp_bound_socket_get_fd (https_handle);
      memset (&amp;sss, 0, sizeof(sss));
      if (getsockname (fds, &amp;sss.sa, &amp;s_socklen))
        { perror ("getsockname() failed");
      return 1;
        }
      if (sss.ss.ss_family == AF_INET)
        { s_got_port = ntohs (sss.in.sin_port);
      s_inaddr = &amp;sss.in.sin_addr;
        }
      else if (sss.ss.ss_family == AF_INET6)
        { s_got_port = ntohs (sss.i6.sin6_port);
      s_inaddr = &amp;sss.i6.sin6_addr;
        }
      else
        { fprintf (stderr, "Weird address family %d\n", sss.ss.ss_family);
      return 1;
        }
      s_addr = evutil_inet_ntop (sss.ss.ss_family, s_inaddr, s_addrbuf,
                           sizeof (s_addrbuf));
      if (s_addr)
        printf ("Listening HTTPS on %s:%d\n", s_addr, s_got_port);
      else
        { fprintf (stderr, "evutil_inet_ntop failed\n");
      return 1;
        }
  
  
  
  
  
      fd = evhttp_bound_socket_get_fd (http_handle);
      memset (&amp;ss, 0, sizeof(ss));
      if (getsockname (fd, &amp;ss.sa, &amp;socklen))
        { perror ("getsockname() failed");
      return 1;
        }
      if (ss.ss.ss_family == AF_INET)
        { got_port = ntohs (ss.in.sin_port);
      inaddr = &amp;ss.in.sin_addr;
        }
      else if (ss.ss.ss_family == AF_INET6)
        { got_port = ntohs (ss.i6.sin6_port);
      inaddr = &amp;ss.i6.sin6_addr;
        }
      else
        { fprintf (stderr, "Weird address family %d\n", ss.ss.ss_family);
      return 1;
        }
      addr = evutil_inet_ntop (ss.ss.ss_family, inaddr, addrbuf,
                           sizeof (addrbuf));
      if (addr)
        printf ("Listening HTTP on %s:%d\n", addr, got_port);
      else
        { fprintf (stderr, "evutil_inet_ntop failed\n");
      return 1;
        }
  
    }
  
    event_base_dispatch (base);
  
    /* not reached; runs forever */
  
    return 0;
  }
  </code></pre>