Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make an https request using sockets on linux

Tags:

c

linux

sockets

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.

like image 560
Jack Avatar asked Apr 27 '13 18:04

Jack


2 Answers

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()
like image 195
user4815162342 Avatar answered Nov 10 '22 08:11

user4815162342


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.

like image 27
Havenard Avatar answered Nov 10 '22 08:11

Havenard