- Development Time: This project used 2 sleep days
- Laboratory Code: Builds upon code from Communication Protocols Lab 9 for socket utilities.
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=...
-
Interactive loop (in
main()):- Opens a new socket to
63.32.125.183:8081per command - Reads a command string from
stdin - Calls the corresponding handler function
- Cleans up any cookies or tokens on logout or exit
- Opens a new socket to
-
HTTP communication:
-
Socket helpers in
helpers.hpp/cpp:open_connection(),close_connection(),send_to_server(),receive_from_server()compute_message()assembles raw HTTP headersbasic_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>
-
-
Session & Authentication:
-
Admin:
login_admin: POST/api/v1/tema/admin/loginwith JSON credentials; on success, storeSet-Cookie:headers inadmin_cookieslogout_admin: GET/api/v1/tema/admin/logout; clears stored admin cookies
-
User:
login: POST/api/v1/tema/user/loginwith{ admin_username, username, password }; stores session cookie(s) inuser_cookiesget_access: GET/api/v1/tema/library/access; parses JWT token from JSON body; saved astokenlogout: GET/api/v1/tema/user/logout; clearsuser_cookiesandtoken
-
-
Cookie & JWT handling:
-
Helper functions in
main.cpp:extract_cookie(),extract_cookies()parseSet-Cookie:headershandle_response_and_store_cookies()checks 2xx codes, stores cookies in a vector
-
JWT passed in
Authorization: Bearer <token>header for library endpoints
-
-
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
-
-
Logging & Validation:
- All operations log either
SUCCESS: ...orERROR: ... - Input validators ensure correct formats (no spaces in usernames, valid numbers)
- All operations log either
├── 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
- Implements a resizable
Bufferstruct for accumulating socket data - Provides methods to locate headers, CRLF delimiters, and manage allocations
- 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)
-
Encapsulates construction of HTTP methods:
- Computes
Content-Length, serializes JSON bodies, attaches cookies/JWT - Terminates headers with
\r\nsequences
- Computes
-
Contains
main()loop withwhile(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
- All HTTP responses are checked:
2xxcodes → 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
- Modify
hostIpandPORTmacros inclient.cppto 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
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.cpprepeatedly reads into the buffer until it detects the `"
"header terminator, parses theContent-Length` header, and then continues reading the body.