Skip to content

Instantly share code, notes, and snippets.

@leiless
Created August 12, 2019 14:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save leiless/62d51ccb5207374d47366020b48dcfff to your computer and use it in GitHub Desktop.
Save leiless/62d51ccb5207374d47366020b48dcfff to your computer and use it in GitHub Desktop.
[Test] Simple program to POST a HTTP request to postman-echo.com
/**
* Simple program to POST a HTTP request
*
* see:
* https://docs.postman-echo.com/?version=latest
* https://aticleworld.com/http-get-and-post-methods-example-in-c/
* https://stackoverflow.com/questions/11208299/how-to-make-an-http-get-request-in-c-without-libcurl
* https://stackoverflow.com/questions/22077802/simple-c-example-of-doing-an-http-post-and-consuming-the-response
*/
#include <stdio.h> /* printf, sprintf */
#include <stdlib.h> /* exit */
#include <unistd.h> /* read, write, close */
#include <string.h> /* memcpy, memset */
#include <sys/socket.h> /* socket, connect */
#include <netinet/in.h> /* struct sockaddr_in, struct sockaddr */
#include <netdb.h> /* struct hostent, gethostbyname */
static void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
static int port = 80;
static const char *host = "postman-echo.com";
static const char *message_fmt = "POST /post?data=%s HTTP/1.0\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: %zu\r\n"
"\r\n%s";
struct hostent *server;
struct sockaddr_in serv_addr;
int fd, bytes, sent, received, total;
char message[1024], response[4096];
if (argc < 3) {
puts("Usage:\n\t<data> <body>\n");
exit(0);
}
sprintf(message, message_fmt, argv[1], strlen(argv[2]), argv[2]);
printf("Request:\n%s\n", message);
/* Create the socket */
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) error("ERROR opening socket");
/* Lookup the ip address */
server = gethostbyname(host);
if (server == NULL) error("ERROR, no such host");
/* Fill in the structure */
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
/* Connect the socket */
if (connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR connecting");
/* Send the request */
total = strlen(message);
sent = 0;
do {
bytes = write(fd, message + sent, total - sent);
if (bytes < 0)
error("ERROR writing message to socket");
if (bytes == 0) break;
sent += bytes;
} while (sent < total);
/* Receive the response */
memset(response, 0, sizeof(response));
total = sizeof(response) - 1;
received = 0;
do {
bytes = read(fd, response + received, total - received);
if (bytes < 0)
error("ERROR reading response from socket");
if (bytes == 0) break;
received += bytes;
} while (received < total);
if (received == total)
error("ERROR storing complete response from socket");
(void) close(fd);
/* process response */
printf("Response:\n%s\n", response);
return 0;
}
@leiless
Copy link
Author

leiless commented Aug 12, 2019

Sample out:

$ gcc -Wall postman-echo.c
$ ./a.out foobar "$(uptime)"
Request:
POST /post?data=foobar HTTP/1.0
Content-Type: text/plain
Content-Length: 55

22:24  up 23:55, 2 users, load averages: 1.78 1.79 1.82
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Mon, 12 Aug 2019 14:24:48 GMT
ETag: W/"132-V6wIUjboovne2bhtf5dl63F1Ozg"
Server: nginx
set-cookie: sails.sid=s%3AH0e-238rLgqzOAQuNScgLJgLAiOesV3P.oDsZz0IZnqMSykuB0gToYvUftVB9gYHCHzMkc9FoONQ; Path=/; HttpOnly
Vary: Accept-Encoding
Content-Length: 306
Connection: Close

{"args":{"data":"foobar"},"data":"22:24  up 23:55, 2 users, load averages: 1.78 1.79 1.82","files":{},"form":{},"headers":{"x-forwarded-proto":"https","host":"172.31.38.43","content-length":"55","content-type":"text/plain","x-forwarded-port":"80"},"json":null,"url":"https://172.31.38.43/post?data=foobar"}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment