// Experiment 10: A simple HTTP client
// Builds a raw HTTP/1.0 GET request over TCP and prints the response
// Compile: gcc 10_http_client.c -o httpclient
// Run    : ./httpclient www.example.com /
//          ./httpclient www.google.com /

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define BUF 4096

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Usage: %s <host> <path>\n", argv[0]);
        printf("Example: %s www.example.com /\n", argv[0]);
        return 1;
    }

    const char *host = argv[1];
    const char *path = argv[2];

    // 1. Resolve hostname -> IP
    struct hostent *server = gethostbyname(host);
    if (!server) { fprintf(stderr, "host not found\n"); return 2; }

    // 2. Create TCP socket
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) { perror("socket"); return 3; }

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port   = htons(80);              // HTTP port
    memcpy(&addr.sin_addr.s_addr, server->h_addr, server->h_length);

    // 3. Connect to web server
    if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("connect"); return 4;
    }
    printf("Connected to %s. Sending GET %s ...\n\n", host, path);

    // 4. Build and send HTTP GET request
    char request[1024];
    snprintf(request, sizeof(request),
             "GET %s HTTP/1.0\r\n"
             "Host: %s\r\n"
             "Connection: close\r\n"
             "\r\n",
             path, host);
    send(sock, request, strlen(request), 0);

    // 5. Read response and print it
    char buffer[BUF];
    int n;
    while ((n = read(sock, buffer, BUF - 1)) > 0) {
        buffer[n] = '\0';
        printf("%s", buffer);
    }

    close(sock);
    return 0;
}
