Last active
July 24, 2020 15:32
-
-
Save sagebind/24f5824f44cd1f81e9a475951f888025 to your computer and use it in GitHub Desktop.
Example C program for curl issue #5717
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <curl/curl.h> | |
#include <errno.h> | |
#include <netinet/in.h> | |
#include <pthread.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/socket.h> | |
#include <unistd.h> | |
#define EXPECT(expr) \ | |
{ \ | |
if (expr != 0) \ | |
{ \ | |
fprintf(stderr, "%s\n", strerror(errno)); \ | |
exit(1); \ | |
} \ | |
} | |
#define CURL_EXPECT(expr) \ | |
{ \ | |
CURLcode result; \ | |
if ((result = expr) != CURLE_OK) \ | |
{ \ | |
fprintf(stderr, "%s\n", curl_easy_strerror(result)); \ | |
exit(1); \ | |
} \ | |
} | |
static void *server_main(void *arg) | |
{ | |
int server_socket = (int)arg; | |
int client_socket, len; | |
struct sockaddr_in client_addr; | |
socklen_t addr_len = sizeof(client_addr); | |
if ((client_socket = accept(server_socket, &client_addr, &addr_len)) < 0) | |
{ | |
fprintf(stderr, "Accept failed\n"); | |
exit(1); | |
} | |
char buf[8192]; | |
recv(client_socket, buf, 65535, 0); | |
FILE *fd = fdopen(client_socket, "w"); | |
fprintf(fd, "HTTP/1.1 200 OK\r\n"); | |
fprintf(fd, "Content-Length: 0\r\n\r\n"); | |
fflush(fd); | |
EXPECT(close(client_socket)); | |
EXPECT(close(server_socket)); | |
return NULL; | |
} | |
int main(int argc, char **argv) | |
{ | |
CURLcode result; | |
int server_socket, len; | |
pthread_t server_thread; | |
CURL_EXPECT(curl_global_init(CURL_GLOBAL_ALL)); | |
// Create a server socket. | |
if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) | |
{ | |
fprintf(stderr, "Socket creation failed\n"); | |
exit(1); | |
} | |
struct sockaddr_in server_addr; | |
server_addr.sin_family = AF_INET; | |
server_addr.sin_port = htons(0); | |
server_addr.sin_addr.s_addr = INADDR_ANY; | |
len = sizeof(server_addr); | |
EXPECT(bind(server_socket, &server_addr, len)); | |
EXPECT(listen(server_socket, 10000)); | |
getsockname(server_socket, &server_addr, &len); | |
char url[64]; | |
sprintf(url, "http://127.0.0.1:%d", ntohs(server_addr.sin_port)); | |
// Spawn TCP server thread. | |
pthread_create(&server_thread, NULL, server_main, (void *)server_socket); | |
CURL *curl = curl_easy_init(); | |
FILE *infile = fopen("main.c", "rb"); | |
fseek(infile, 0L, SEEK_END); | |
long infile_size = ftell(infile); | |
fseek(infile, 0L, SEEK_SET); | |
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); | |
curl_easy_setopt(curl, CURLOPT_URL, &url); | |
curl_easy_setopt(curl, CURLOPT_READDATA, infile); | |
curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread); | |
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); | |
curl_easy_setopt(curl, CURLOPT_NOBODY, 1); | |
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "HEAD"); | |
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, infile_size); | |
CURL_EXPECT(curl_easy_perform(curl)); | |
curl_easy_cleanup(curl); | |
fclose(infile); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.PHONY: run-old | |
run-old: out/old | |
$< | |
.PHONY: run-new | |
run-new: out/new | |
$< | |
.PHONY: clean | |
clean: | |
rm -r out | |
out/old: main.c | |
mkdir -p $(@D) | |
gcc -o $@ $< -lcurl -lpthread | |
out/new: main.c | |
mkdir -p $(@D) | |
gcc -o $@ $< /usr/local/lib/libcurl.a -lpthread -lssl -lcrypto |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
My C is a little rusty so this is probably not the most well-written program, but it gets the job done.