Skip to content

Instantly share code, notes, and snippets.

@harieamjari
Created June 15, 2021 15:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harieamjari/608ceec348fda06022524b96327b1594 to your computer and use it in GitHub Desktop.
Save harieamjari/608ceec348fda06022524b96327b1594 to your computer and use it in GitHub Desktop.
GET request for a file; download a file using an HTTP request. OpenSSL
/*
* Copyright 2013-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <string.h>
int main(int argc, char **argv) {
BIO *sbio = NULL, *out = NULL;
int len;
char tmpbuf[1024];
SSL_CTX *ctx;
SSL_CONF_CTX *cctx;
SSL *ssl;
char **args = argv + 1;
const char *connect_str = "juventudedesporto.cplp.org:443";
int nargs = argc - 1;
ctx = SSL_CTX_new(TLS_client_method());
cctx = SSL_CONF_CTX_new();
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
while (*args && **args == '-') {
int rv;
/* Parse standard arguments */
rv = SSL_CONF_cmd_argv(cctx, &nargs, &args);
if (rv == -3) {
fprintf(stderr, "Missing argument for %s\n", *args);
goto end;
}
if (rv < 0) {
fprintf(stderr, "Error in command %s\n", *args);
ERR_print_errors_fp(stderr);
goto end;
}
/* If rv > 0 we processed something so proceed to next arg */
if (rv > 0)
continue;
/* Otherwise application specific argument processing */
if (strcmp(*args, "-connect") == 0) {
connect_str = args[1];
if (connect_str == NULL) {
fprintf(stderr, "Missing -connect argument\n");
goto end;
}
args += 2;
nargs -= 2;
continue;
} else {
fprintf(stderr, "Unknown argument %s\n", *args);
goto end;
}
}
if (!SSL_CONF_CTX_finish(cctx)) {
fprintf(stderr, "Finish error\n");
ERR_print_errors_fp(stderr);
goto end;
}
/*
* We'd normally set some stuff like the verify paths and * mode here
* because as things stand this will connect to * any server whose
* certificate is signed by any CA.
*/
sbio = BIO_new_ssl_connect(ctx);
BIO_get_ssl(sbio, &ssl);
if (!ssl) {
fprintf(stderr, "Can't locate SSL pointer\n");
goto end;
}
/* We might want to do other things with ssl here */
BIO_set_conn_hostname(sbio, connect_str);
FILE *fp = fopen("f.pdf", "wb");
out = BIO_new_fp(fp, BIO_NOCLOSE);
if (BIO_do_connect(sbio) <= 0) {
fprintf(stderr, "Error connecting to server\n");
ERR_print_errors_fp(stderr);
goto end;
}
/* Could examine ssl here to get connection info */
BIO_puts(
sbio,
"GET /files/sample-pdf_9359.pdf HTTP/1.1\r\n"
"Host: juventudedesporto.cplp.org\r\n"
"Accept: "
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"User-Agent: Mozilla/5.0 (X11; CrOS x86_64 8172.45.0) AppleWebKit/537.36 "
"User-Agent: Mozilla/5.0 (X11; CrOS x86_64 8172.45.0) AppleWebKit/537.36 "
"(KHTML, "
"like Gecko) Chrome/51.0.2704.64 Safari/537.36\r\n"
"Accept-Language: en-US,en;q=0.5\r\n"
"Connection: keep-alive\r\n\r\n");
int total = 0;
for (;;) {
len = BIO_read(sbio, tmpbuf, 1024);
printf("\rread %-4d bytes, total %-7d", len, total += len);
fflush(stdout);
for (int i = 0; i < len - 3; i++) {
if (tmpbuf[i] == '\r' && tmpbuf[i + 1] == '\n' && tmpbuf[i + 2] == '\r' &&
tmpbuf[i + 3] == '\n') {
/* skip response header */
BIO_write(out, tmpbuf + i + 4, (len - i) - 4);
for (;;) {
len = BIO_read(sbio, tmpbuf, 1024);
printf("\rread %-4d bytes, total %-7d", len, total += len);
fflush(stdout);
if (len <= 0)
goto end;
BIO_write(out, tmpbuf, len);
}
}
}
if (len <= 0)
break;
}
end:
putchar('\n');
SSL_CONF_CTX_free(cctx);
BIO_free_all(sbio);
BIO_free(out);
fclose(fp);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment