From 065b9bc6d8c291ac6ce4b3e5661536ea77bb3ba1 Mon Sep 17 00:00:00 2001 From: tastytea Date: Sat, 17 Feb 2018 20:01:51 +0100 Subject: [PATCH] Return new URL on HTTP 301 and 308 --- CMakeLists.txt | 2 +- README.md | 4 +- src/examples/example1_dump_json.cpp | 6 +++ src/examples/example2_parse_account.cpp | 6 +++ src/examples/example3_mastocron.cpp | 6 +++ src/examples/example4_update_credentials.cpp | 6 +++ src/examples/example5_follow_unfollow.cpp | 6 +++ src/examples/example6_toot_delete-toot.cpp | 6 +++ src/examples/example7_register_app.cpp | 6 +++ src/http_sync.cpp | 5 +- src/mastodon-cpp.cpp | 5 ++ src/mastodon-cpp.hpp | 49 +++++++++++++------- 12 files changed, 85 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 976f898..ce8cf2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.7) include(GNUInstallDirs) project (mastodon-cpp - VERSION 0.2.14 + VERSION 0.2.15 LANGUAGES CXX ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") diff --git a/README.md b/README.md index 2d211ed..d7b453a 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ After you did a `make install`, a project consisting of one file can be compiled | 0 | No error | | 1 | Invalid call | | 2 | Not implemented | +| 3 | URL changed (HTTP 301 or 308) | | 100 - 999 | HTTP status codes | | 65535 | Unknown error | @@ -99,13 +100,14 @@ If you use a debug build, you get more verbose error messages. * [x] Implement all PUT calls * [x] Implement all DELETE calls * Version 0.3.0 - * [ ] Handle HTTP statuses 301 & 302 + * [x] Handle HTTP statuses 301, 302, 307 and 308 * [x] Support registering as an application * Version 0.4.0 * [ ] Handle X-RateLimit header * [ ] Streaming API * Later * [ ] Asynchronous I/O + * [ ] Improve error reporting ## Status of implementation diff --git a/src/examples/example1_dump_json.cpp b/src/examples/example1_dump_json.cpp index 61436dd..5454a9d 100644 --- a/src/examples/example1_dump_json.cpp +++ b/src/examples/example1_dump_json.cpp @@ -68,6 +68,12 @@ int main(int argc, char *argv[]) return ret; } } + else if (ret == 3) + { + std::cerr << "The URL has permanently changed.\n" << + "New URL: " << answer << '\n'; + return ret; + } else { std::cerr << "Error code: " << ret << '\n'; diff --git a/src/examples/example2_parse_account.cpp b/src/examples/example2_parse_account.cpp index 035d071..893ac5f 100644 --- a/src/examples/example2_parse_account.cpp +++ b/src/examples/example2_parse_account.cpp @@ -56,6 +56,12 @@ int main(int argc, char *argv[]) } } } + else if (ret == 3) + { + std::cerr << "The URL has permanently changed.\n" << + "New URL: " << answer << '\n'; + return ret; + } else { std::cerr << "Error code: " << ret << '\n'; diff --git a/src/examples/example3_mastocron.cpp b/src/examples/example3_mastocron.cpp index 6d5c9a7..04073b3 100644 --- a/src/examples/example3_mastocron.cpp +++ b/src/examples/example3_mastocron.cpp @@ -104,6 +104,12 @@ int main(int argc, char *argv[]) pt::write_json(filename, config); } } + else if (ret == 3) + { + std::cerr << "The URL has permanently changed.\n" << + "New URL: " << answer << '\n'; + return ret; + } else { std::cerr << "Error code: " << ret << '\n'; diff --git a/src/examples/example4_update_credentials.cpp b/src/examples/example4_update_credentials.cpp index 1e8446f..f19174f 100644 --- a/src/examples/example4_update_credentials.cpp +++ b/src/examples/example4_update_credentials.cpp @@ -62,6 +62,12 @@ int main(int argc, char *argv[]) { std::cout << answer << '\n'; } + else if (ret == 3) + { + std::cerr << "The URL has permanently changed.\n" << + "New URL: " << answer << '\n'; + return ret; + } else { std::cerr << "Error code: " << ret << '\n'; diff --git a/src/examples/example5_follow_unfollow.cpp b/src/examples/example5_follow_unfollow.cpp index 3031c38..cad3cc9 100644 --- a/src/examples/example5_follow_unfollow.cpp +++ b/src/examples/example5_follow_unfollow.cpp @@ -36,6 +36,12 @@ int main(int argc, char *argv[]) { // std::cout << answer << '\n'; } + else if (ret == 3) + { + std::cerr << "The URL has permanently changed.\n" << + "New URL: " << answer << '\n'; + return ret; + } else { std::cerr << "Error code: " << ret << '\n'; diff --git a/src/examples/example6_toot_delete-toot.cpp b/src/examples/example6_toot_delete-toot.cpp index 9dcec1b..7dff7de 100644 --- a/src/examples/example6_toot_delete-toot.cpp +++ b/src/examples/example6_toot_delete-toot.cpp @@ -53,6 +53,12 @@ int main(int argc, char *argv[]) return ret; } } + else if (ret == 3) + { + std::cerr << "The URL has permanently changed.\n" << + "New URL: " << answer << '\n'; + return ret; + } else { std::cerr << "Error code: " << ret << '\n'; diff --git a/src/examples/example7_register_app.cpp b/src/examples/example7_register_app.cpp index 0497b3b..cc23c4e 100644 --- a/src/examples/example7_register_app.cpp +++ b/src/examples/example7_register_app.cpp @@ -71,6 +71,12 @@ int main(int argc, char *argv[]) return ret; } } + else if (ret == 3) + { + std::cerr << "The URL has permanently changed.\n" << + "New URL: " << url << '\n'; + return ret; + } else { std::cerr << "Error code: " << ret << '\n'; diff --git a/src/http_sync.cpp b/src/http_sync.cpp index e51151e..cd98d98 100644 --- a/src/http_sync.cpp +++ b/src/http_sync.cpp @@ -99,8 +99,9 @@ const std::uint16_t API::http::request_sync(const method &meth, } else if (ret == 301 || ret == 308) { // Moved Permanently or Permanent Redirect - // FIXME: The new URL should be passed back somehow - answer = oss.str(); + // return new URL + answer = curlpp::infos::EffectiveUrl::get(request); + return 3; } else { diff --git a/src/mastodon-cpp.cpp b/src/mastodon-cpp.cpp index 8cdd662..5f3c206 100644 --- a/src/mastodon-cpp.cpp +++ b/src/mastodon-cpp.cpp @@ -192,6 +192,11 @@ const std::uint16_t API::register_app1(const string &instance, return 0; } + else if (ret == 3) + { + url = answer; + return ret; + } else { std::cerr << "Error code: " << ret << '\n'; diff --git a/src/mastodon-cpp.hpp b/src/mastodon-cpp.hpp index 9c853b1..1b237ea 100644 --- a/src/mastodon-cpp.hpp +++ b/src/mastodon-cpp.hpp @@ -44,9 +44,7 @@ namespace Mastodon * | 0 | No error | * | 1 | Invalid call | * | 2 | Not implemented | - * | 16 | Connection failed | - * | 17 | TLS error | - * | 18 | Invalid response from server | + * | 3 | URL changed (HTTP 301 or 308) | * | 100 - 999 | HTTP status codes | * | 65535 | Unknown exception | */ @@ -184,7 +182,8 @@ public: * @param client_secret Returned * @param url Returned, used to generate code for register_app2 * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and url is set to the new URL. */ const std::uint16_t register_app1(const std::string &instance, const std::string &client_name, @@ -235,7 +234,8 @@ public: * @param answer The answer from the server. Usually JSON. On error an * empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t get(const Mastodon::API::v1 &call, const std::string &argument, @@ -250,7 +250,8 @@ public: * @param answer The answer from the server. Usually JSON. On error * an empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t get(const Mastodon::API::v1 &call, const parametermap ¶meters, @@ -265,7 +266,8 @@ public: * @param answer The answer from the server. Usually JSON. On error * an empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t get(const Mastodon::API::v1 &call, const std::string &argument, @@ -279,7 +281,8 @@ public: * @param answer The answer from the server. Usually JSON. On error an * empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t get(const std::string &call, std::string &answer); @@ -294,7 +297,8 @@ public: * @param answer The answer from the server. Usually JSON. On error * an empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t patch(const Mastodon::API::v1 &call, const parametermap ¶meters, @@ -307,7 +311,8 @@ public: * @param answer The answer from the server. Usually JSON. On error an * empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t post(const Mastodon::API::v1 &call, std::string &answer); @@ -320,7 +325,8 @@ public: * @param answer The answer from the server. Usually JSON. On error an * empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t post(const Mastodon::API::v1 &call, const std::string &argument, @@ -337,7 +343,8 @@ public: * @param answer The answer from the server. Usually JSON. On error * an empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t post(const Mastodon::API::v1 &call, const parametermap ¶meters, @@ -354,7 +361,8 @@ public: * @param answer The answer from the server. Usually JSON. On error * an empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t post(const Mastodon::API::v1 &call, const std::string &argument, @@ -371,7 +379,8 @@ public: * @param answer The answer from the server. Usually JSON. On error * an empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t post(const std::string &call, const parametermap ¶meters, @@ -387,7 +396,8 @@ public: * @param answer The answer from the server. Usually JSON. On error * an empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t put(const Mastodon::API::v1 &call, const std::string &argument, @@ -403,7 +413,8 @@ public: * @param answer The answer from the server. Usually JSON. On error * an empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t put(const std::string &call, const parametermap ¶meters, @@ -454,7 +465,8 @@ public: * @param answer The answer from the server. Usually JSON. On error * an empty string. * - * @return @ref error "Error code". + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t del(const std::string &call, const parametermap ¶meters, @@ -511,7 +523,8 @@ private: * @param formdata The form data for PATCH and POST request. * @param answer The answer from the server * - * @return Error code. See README.md for details. + * @return @ref error "Error code". If the URL has permanently changed, 3 + * is returned and answer is set to the new URL. */ const std::uint16_t request_sync(const method &meth, const std::string &path,