Skip to content

A command-line HTTP client written in C++ that interacts with a RESTful API using raw TCP sockets, handling JSON parsing, session cookies, and JWT authentication.

Notifications You must be signed in to change notification settings

mihneapopesq/HTTP-Movie-Web-Server

Repository files navigation

Popescu Mihnea-Gabriel 321CAa

Web Client - Rest API Communication

Notes

  • Development Time: This project used 2 sleep days
  • Laboratory Code: Builds upon code from Communication Protocols Lab 9 for socket utilities.

Overview

This is a command-line HTTP client written in C++ that interacts with a RESTful movie library server over raw TCP sockets. It supports two roles:

  • Admin: manage normal user accounts (login, create, list, delete, logout)
  • User: authenticate via admin, obtain JWT access, and perform operations on movies and collections

The client loops reading textual commands, constructs HTTP requests (GET/POST/PUT/DELETE) using helper functions, sends them to the server, parses responses, and prints clear SUCCESS: or ERROR: messages. This project used nlohmann/json (json.hpp) for JSON handling

Available commands:

  • Admin: login_admin, add_user, get_users, delete_user, logout_admin
  • User: login, get_access, logout
  • Movies: get_movies, get_movie, add_movie, update_movie, delete_movie
  • Collections: get_collections, get_collection, add_collection, delete_collection, add_movie_to_collection, delete_movie_from_collection
  • exit

For commands requiring parameters, you will be prompted:

username=...
password=...
id=...
title=...

Flow & Features

  1. Interactive loop (in main()):

    • Opens a new socket to 63.32.125.183:8081 per command
    • Reads a command string from stdin
    • Calls the corresponding handler function
    • Cleans up any cookies or tokens on logout or exit
  2. HTTP communication:

    • Socket helpers in helpers.hpp/cpp:

      • open_connection(), close_connection(), send_to_server(), receive_from_server()
      • compute_message() assembles raw HTTP headers
      • basic_extract_json_response() pulls JSON body out of raw response
    • Request builders in requests.hpp/cpp:

      • compute_get_request(), compute_post_request(), compute_put_request(), compute_delete_request()
      • Automatically set required headers: Host, Content-Type, Content-Length, Cookie, Authorization: Bearer <token>
  3. Session & Authentication:

    • Admin:

      • login_admin: POST /api/v1/tema/admin/login with JSON credentials; on success, store Set-Cookie: headers in admin_cookies
      • logout_admin: GET /api/v1/tema/admin/logout; clears stored admin cookies
    • User:

      • login: POST /api/v1/tema/user/login with { admin_username, username, password }; stores session cookie(s) in user_cookies
      • get_access: GET /api/v1/tema/library/access; parses JWT token from JSON body; saved as token
      • logout: GET /api/v1/tema/user/logout; clears user_cookies and token
  4. Cookie & JWT handling:

    • Helper functions in main.cpp:

      • extract_cookie(), extract_cookies() parse Set-Cookie: headers
      • handle_response_and_store_cookies() checks 2xx codes, stores cookies in a vector
    • JWT passed in Authorization: Bearer <token> header for library endpoints

  5. Commands implementation:

    • User management (admin-only):

      • add_user, get_users, delete_user
    • Movies (requires JWT):

      • get_movies, get_movie, add_movie, update_movie, delete_movie
    • Collections (requires JWT + ownership checks):

      • get_collections, get_collection, add_collection, delete_collection, add_movie_to_collection, delete_movie_from_collection
    • Each handler:

      • Validates input (e.g., numeric IDs, non-empty strings)
      • Builds the HTTP request via compute_*_request
      • Sends, receives, parses status code
      • On success: optionally parse JSON and print concise info
      • On error: print meaningful ERROR: message
  6. Logging & Validation:

    • All operations log either SUCCESS: ... or ERROR: ...
    • Input validators ensure correct formats (no spaces in usernames, valid numbers)

File Structure

├── nlohmann/
│   └── json.hpp           # nlohmann/json single-header
├── helpers.hpp           # socket and HTTP helper declarations
├── helpers.cpp           # implementations of connection, parsing
├── requests.hpp          # HTTP request builder declarations
├── requests.cpp          # implementations of GET/POST/PUT/DELETE builders
├── client.cpp            # `main()`, command dispatch, handlers
├── buffer.hpp/cpp        # dynamic buffer for socket reads and substring search
└── README.md             # this file

buffer.hpp/cpp

  • Implements a resizable Buffer struct for accumulating socket data
  • Provides methods to locate headers, CRLF delimiters, and manage allocations

helpers.hpp/cpp

  • Connection: open/close, send, receive raw bytes
  • HTTP parsing: split headers/body, basic JSON extraction
  • Utility: is_success() to classify 2xx codes (concept sourced from MDN HTTP status reference)

requests.hpp/cpp

  • Encapsulates construction of HTTP methods:

    • Computes Content-Length, serializes JSON bodies, attaches cookies/JWT
    • Terminates headers with \r\n sequences

client.cpp

  • Contains main() loop with while(true) reading commands

  • One handler function per command name

  • Common patterns:

    • Prompt for fields
    • Input validation (numeric IDs via strtol, no-spaces checks)
    • Build request, send/receive, parse response code
    • Print output and manage session state

Error Handling

  • All HTTP responses are checked: 2xx codes → success; others → error with code or context
  • JSON parsing uses nlohmann::json::parse(..., false) to detect malformed bodies
  • User inputs are pre-validated before sending any request

Customization

  • Modify hostIp and PORT macros in client.cpp to point to a different server
  • Swap out JSON library by updating includes and parsing code
  • Extend command list by adding new handler and request path

Buffer Module Details

The project uses a custom buffer implementation (buffer.hpp/buffer.cpp) to efficiently read from sockets and assemble full HTTP responses:

  • buffer_init / buffer_destroy: allocate and free the dynamic data buffer.
  • buffer_add: append raw bytes to the buffer, resizing as needed.
  • buffer_find / buffer_find_insensitive: search for byte sequences (e.g., header terminators) in a case-sensitive or insensitive manner.
  • Response reader in helpers.cpp repeatedly reads into the buffer until it detects the `"

"header terminator, parses theContent-Length` header, and then continues reading the body.

About

A command-line HTTP client written in C++ that interacts with a RESTful API using raw TCP sockets, handling JSON parsing, session cookies, and JWT authentication.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published