// Copyright 2021,2024 Jeisson Hidalgo-Cespedes. ECCI-UCR. CC BY 4.0 #include #include #include #include #include #include #include #include "Factorization.hpp" #include "FactWebApp.hpp" #include "HttpRequest.hpp" #include "HttpResponse.hpp" #include "Util.hpp" static const char* const PREFIX1 = "/fact"; static const char* const PREFIX2 = "/fact?number="; // TODO(you): Do not duplicate code for other apps, such as GoldbachWebApp. // Move common code to a base class for Factorization and Goldbach apps bool FactWebApp::handleHttpRequest(HttpRequest& httpRequest, HttpResponse& httpResponse) { // If the request starts with "fact/" is for this web app if (httpRequest.getURI().rfind(PREFIX1, 0) == 0) { return this->serveFactorization(httpRequest, httpResponse); } // Unrecognized request return false; } void FactWebApp::addToHomepage(HttpRequest&, HttpResponse& httpResponse) { httpResponse.body() << "

" << "Prime factorization" << "

\n" << "
\n" << " \n" << " \n" << " \n" << "
\n" << "\n"; } bool FactWebApp::serveFactorization(HttpRequest& httpRequest, HttpResponse& httpResponse) { // Replace %xx hexadecimal codes by their ASCII symbols // Sanitize code that client may want to inject const std::string& uri = HttpApp::sanitizeHtml(Util::decodeURI( httpRequest.getURI())); // Build the body of the response this->serveHeader(httpResponse, "Prime factorization"); httpResponse.body() << "

request: " << uri << "

\n" << "
    \n"; this->factorizeNumbers(uri, httpResponse); httpResponse.body() << "
\n" << "
\n" << "

Back

\n" << "\n"; // Send the response to the client (user agent) return httpResponse.send(); } void FactWebApp::factorizeNumbers(const std::string& uri, HttpResponse& httpResponse) { // Numbers were asked in the form "/fact/123,45,-7899" or "/fact?number=13" // Determine the position where numbers start. Assume PREFIX1 is used size_t numbersStart = std::strlen(PREFIX1); // If URI starts with PREFIX2 instead of PREFIX1 if (uri.rfind(PREFIX2, 0) == 0) { // Numbers starts after the PREFIX2 length numbersStart = std::strlen(PREFIX2); } // TODO(you): Use arbitrary precision for numbers larger than int64_t const std::vector& texts = Util::split(uri.substr(numbersStart), ",", true); // For each asked number, provide its prime factorization for (size_t index = 0; index < texts.size(); ++index) { try { // Convert the text to a number. Provide an error message if not size_t end = 0; const int64_t number = std::stoll(texts[index], &end); if (end != texts[index].length()) { throw std::runtime_error("invalid number " + texts[index]); } // Text was converted to number, provide its prime factorization httpResponse.body() << "
  • " << Factorization(number) << std::endl; } catch (const std::exception& exception) { // Text was not a valid number, report an error to user httpResponse.body() << "
  • " << texts[index] << ": invalid number\n"; } } }