ApResolve.cpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include "ApResolve.h"
  2. #include <memory>
  3. #include <vector>
  4. #include <string>
  5. #include <iostream>
  6. #include <ctype.h>
  7. #include <cstring>
  8. #include <stdlib.h>
  9. #include <sys/types.h>
  10. #include <sys/socket.h>
  11. #include <netdb.h>
  12. #include <netinet/in.h>
  13. #include <unistd.h>
  14. #include <sstream>
  15. #include <fstream>
  16. #include "Logger.h"
  17. #include <cJSON.h>
  18. ApResolve::ApResolve() {}
  19. std::string ApResolve::getApList()
  20. {
  21. // hostname lookup
  22. struct hostent *host = gethostbyname("apresolve.spotify.com");
  23. struct sockaddr_in client;
  24. if ((host == NULL) || (host->h_addr == NULL))
  25. {
  26. CSPOT_LOG(error, "apresolve: DNS lookup error");
  27. throw std::runtime_error("Resolve failed");
  28. }
  29. // Prepare socket
  30. bzero(&client, sizeof(client));
  31. client.sin_family = AF_INET;
  32. client.sin_port = htons(80);
  33. memcpy(&client.sin_addr, host->h_addr, host->h_length);
  34. int sockFd = socket(AF_INET, SOCK_STREAM, 0);
  35. // Connect to spotify's server
  36. if (connect(sockFd, (struct sockaddr *)&client, sizeof(client)) < 0)
  37. {
  38. close(sockFd);
  39. CSPOT_LOG(error, "Could not connect to apresolve");
  40. throw std::runtime_error("Resolve failed");
  41. }
  42. // Prepare HTTP get header
  43. std::stringstream ss;
  44. ss << "GET / HTTP/1.1\r\n"
  45. << "Host: apresolve.spotify.com\r\n"
  46. << "Accept: application/json\r\n"
  47. << "Connection: close\r\n"
  48. << "\r\n\r\n";
  49. std::string request = ss.str();
  50. // Send the request
  51. if (send(sockFd, request.c_str(), request.length(), 0) != (int)request.length())
  52. {
  53. CSPOT_LOG(error, "apresolve: can't send request");
  54. throw std::runtime_error("Resolve failed");
  55. }
  56. char cur;
  57. // skip read till json data
  58. while (read(sockFd, &cur, 1) > 0 && cur != '{');
  59. auto jsonData = std::string("{");
  60. // Read json structure
  61. while (read(sockFd, &cur, 1) > 0)
  62. {
  63. jsonData += cur;
  64. }
  65. return jsonData;
  66. }
  67. std::string ApResolve::fetchFirstApAddress()
  68. {
  69. // Fetch json body
  70. auto jsonData = getApList();
  71. // Use cJSON to get first ap address
  72. auto root = cJSON_Parse(jsonData.c_str());
  73. auto apList = cJSON_GetObjectItemCaseSensitive(root, "ap_list");
  74. auto firstAp = cJSON_GetArrayItem(apList, 0);
  75. auto data = std::string(firstAp->valuestring);
  76. // release cjson memory
  77. cJSON_Delete(root);
  78. return data;
  79. }