GithubDownloader.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include <GithubDownloader.h>
  2. #include <FS.h>
  3. Stream& GithubDownloader::streamFile(const String& path) {
  4. if (!client.connect(GITHUB_RAW_DOMAIN, 443)) {
  5. Serial.println("Failed to connect to github over HTTPS.");
  6. }
  7. if (!client.verify(GITHUB_SSL_FINGERPRINT, GITHUB_RAW_DOMAIN)) {
  8. Serial.println("Failed to verify github certificate");
  9. }
  10. client.print(String("GET ") + path + " HTTP/1.1\r\n" +
  11. "Host: " + GITHUB_RAW_DOMAIN + "\r\n" +
  12. "Connection: close\r\n\r\n");
  13. return client;
  14. }
  15. Stream& GithubDownloader::streamFile(const String& username, const String& repo, const String& path) {
  16. return streamFile(buildPath(username, repo, path));
  17. }
  18. bool GithubDownloader::downloadFile(const String& path, Stream& dest) {
  19. Stream& client = streamFile(path);
  20. if (client.available()) {
  21. if (!client.find("\r\n\r\n")) {
  22. Serial.println("Error seeking to body");
  23. return false;
  24. }
  25. } else {
  26. Serial.println("Failed to open stream to Github");
  27. return false;
  28. }
  29. printf("Downloading...\n");
  30. size_t bytes = 0;
  31. size_t nextCheckpoint = 4096;
  32. while (client.available()) {
  33. size_t l = client.readBytes(buffer, GITHUB_DOWNLOADER_BUFFER_SIZE);
  34. size_t w = dest.write(buffer, l);
  35. dest.flush();
  36. if (w != l) {
  37. printf("Error writing to stream. Expected to write %d bytes, but only wrote %d\n", l, w);
  38. return false;
  39. }
  40. bytes += w;
  41. printf(".");
  42. if (bytes >= nextCheckpoint) {
  43. printf(" [%d KB]\n", bytes/1024);
  44. nextCheckpoint += 4096;
  45. }
  46. yield();
  47. }
  48. printf("\n");
  49. return true;
  50. }
  51. bool GithubDownloader::downloadFile(const String& username, const String& repo, const String& repoPath, Stream& dest) {
  52. return downloadFile(buildPath(username, repo, repoPath), dest);
  53. }
  54. bool GithubDownloader::downloadFile(const String& username, const String& repo, const String& repoPath, const String& fsPath) {
  55. String tmpFile = fsPath + ".download_tmp";
  56. File f = SPIFFS.open(tmpFile.c_str(), "w");
  57. if (!f) {
  58. Serial.print("ERROR - could not open file for downloading: ");
  59. Serial.println(fsPath);
  60. return false;
  61. }
  62. if (!downloadFile(buildPath(username, repo, repoPath), f)) {
  63. f.close();
  64. return false;
  65. }
  66. f.flush();
  67. f.close();
  68. SPIFFS.remove(fsPath);
  69. SPIFFS.rename(tmpFile, fsPath);
  70. printf("Finished downloading file: %s\n", fsPath.c_str());
  71. return true;
  72. }
  73. String GithubDownloader::buildPath(const String& username, const String& repo, const String& repoPath) {
  74. String path = String("/") + username + "/" + repo + "/master/" + repoPath;
  75. return path;
  76. }