Jack
Jack

Reputation: 16724

Make an https request using sockets on linux

How do I make an http request using sockets on linux? currently, I'm getting

HTTP/1.1 301 Moved Permanently
//etc
Location: https://server.com

here's relevant part of code(the function is too big to post here):

 /* Socket file descriptor. */
        int sock;
    struct sockaddr_in sockaddr;
    struct hostent *host; /* Host information. */
    sock = socket(AF_INET, /* IPV4 protocol. */
              SOCK_STREAM, /* TCP socket. */
              0); /* O for socket() function choose the correct protocol based on the socket type. */

    if(sock == INVALID_SOCKET) return SOCK_GENERROR;

    if((host = gethostbyname(server)) == NULL) {
        close(sock);
        return SOCK_HOSTNFOUND;
    }

    /* zero buffer */
    memset(&sockaddr, 0, sizeof(sockaddr));
    sockaddr.sin_family = AF_INET;
    memcpy(&sockaddr.sin_addr,
           host -> h_addr,
           host -> h_length );
    sockaddr.sin_port = htons(port);

    if(connect(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) == INVALID_SOCKET) {
        close(sock);
        return SOCK_FERRCONN;
    }

    if(send(sock, sendbuf, bufsize, 0) == INVALID_SOCKET) {
        close(sock);
        return SOCK_FERRWRITE;
    }


       if((readed = recv(sock, recvbuffer, sizeof(recvbuffer), 0)) <= 0)
    break;

in the call, server="server.com"; and port=80;

I tried to remove as possible my onw routines and type from this code to make more clean for you.

Upvotes: 16

Views: 20595

Answers (2)

user4815162342
user4815162342

Reputation: 155376

https requests look just like http requests, but with transparent encryption of the actual communication between the client and the server, and on a different default port. The good news is that transparent encryption allows you to program just like you're writing a regular HTTP client. The bad news is that the encryption is complex enough that you need a specialized library to implement it for you.

One such library is OpenSSL. Using OpenSSL, the minimal code for a client would look like this:

#include <openssl/ssl.h>

// first connect to the remote as usual, but use the port 443 instead of 80

// initialize OpenSSL - do this once and stash ssl_ctx in a global var
SSL_load_error_strings ();
SSL_library_init ();
SSL_CTX *ssl_ctx = SSL_CTX_new (SSLv23_client_method ());

// create an SSL connection and attach it to the socket
SSL *conn = SSL_new(ssl_ctx);
SSL_set_fd(conn, sock);

// perform the SSL/TLS handshake with the server - when on the
// server side, this would use SSL_accept()
int err = SSL_connect(conn);
if (err != 1)
   abort(); // handle error

// now proceed with HTTP traffic, using SSL_read instead of recv() and
// SSL_write instead of send(), and SSL_shutdown/SSL_free before close()

Upvotes: 28

Havenard
Havenard

Reputation: 27914

HTTPS is just like HTTP, but its encapsulated in a cryptographic SSL layer. You will need to use a lib like OpenSSL to make those HTTPS connections.

OpenSSL will provide functions that replace the socket.h ones, to connect, read and write regular HTTP (or whatever other protocol you want to use) through a SSL channel, making the handling of the SSL part transparent to you.

Upvotes: 7

Related Questions