BinaryResponseData.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. //
  2. // Created by xcbosa on 2023/1/28.
  3. //
  4. #include "BinaryResponseData.h"
  5. #include "../webuiconf.h"
  6. namespace xc {
  7. namespace utils {
  8. BinaryResponseData::BinaryResponseData(int statusCode, uint8_t *body, int bodySize, string contentType): headers() {
  9. this->statusCode = statusCode;
  10. this->body = body;
  11. this->bodySize = bodySize;
  12. this->headers["Server"] = "XCHttpServer";
  13. this->headers["Transfer-Encoding"] = "chunked";
  14. this->headers["Content-Type"] = contentType;
  15. this->filePath = nullptr;
  16. }
  17. BinaryResponseData::BinaryResponseData(int statusCode, string filePath, string contentType): headers() {
  18. this->statusCode = statusCode;
  19. this->body = nullptr;
  20. this->bodySize = 0;
  21. this->headers["Server"] = "XCHttpServer";
  22. this->headers["Transfer-Encoding"] = "chunked";
  23. this->headers["Content-Type"] = contentType;
  24. this->filePath = filePath;
  25. }
  26. void BinaryResponseData::setHeader(string headerName, string value) {
  27. this->headers[headerName] = value;
  28. }
  29. void BinaryResponseData::writeTo(::FILE *fp) const {
  30. ::fprintf(fp, "HTTP/1.0 %d FRPCWebUI\r\n", this->statusCode);
  31. for (auto item : this->headers) {
  32. ::fprintf(fp, "%s: %s\r\n", item.first.c_str(), item.second.c_str());
  33. }
  34. ::fputs("\r\n", fp);
  35. int mtu = conf::mtu;
  36. if (this->isWriteFromMemory()) {
  37. int writeTimes = this->bodySize / mtu;
  38. if (this->bodySize % mtu) {
  39. writeTimes++;
  40. }
  41. ::uint8_t *cursor = this->body;
  42. ::uint8_t *endNextCursor = this->body + this->bodySize;
  43. for (int i = 0; i < writeTimes; i++) {
  44. long writeSize = min((long)mtu, endNextCursor - cursor);
  45. ::fwrite(cursor, writeSize, mtu, fp);
  46. cursor += writeSize;
  47. }
  48. }
  49. if (this->isWriteFromFile()) {
  50. string filePath = this->filePath;
  51. ::FILE *inputFile = ::fopen(filePath.c_str(), "rb");
  52. if (inputFile) {
  53. ::uint8_t buff[mtu];
  54. long readPerPack = 0;
  55. while ((readPerPack = ::fread(buff, 1, mtu, inputFile)) == mtu) {
  56. ::fwrite(buff, 1, readPerPack, fp);
  57. }
  58. } else {
  59. cerr << "[FileIOError]: " << ::strerror(errno) << endl;
  60. }
  61. }
  62. ::fflush(fp);
  63. }
  64. bool BinaryResponseData::isWriteFromFile() const {
  65. return !this->isWriteFromMemory();
  66. }
  67. bool BinaryResponseData::isWriteFromMemory() const {
  68. return this->bodySize > 0;
  69. }
  70. } // xc
  71. } // utils