1
0

HttpResponseWriter.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include "HttpResponseWriter.h"
  2. namespace hv {
  3. int HttpResponseWriter::EndHeaders(const char* key /* = NULL */, const char* value /* = NULL */) {
  4. if (state != SEND_BEGIN) return -1;
  5. if (key && value) {
  6. response->SetHeader(key, value);
  7. }
  8. std::string headers = response->Dump(true, false);
  9. state = SEND_HEADER;
  10. return write(headers);
  11. }
  12. int HttpResponseWriter::WriteChunked(const char* buf, int len /* = -1 */) {
  13. int ret = 0;
  14. if (len == -1) len = strlen(buf);
  15. if (state == SEND_BEGIN) {
  16. EndHeaders("Transfer-Encoding", "chunked");
  17. }
  18. char chunked_header[64];
  19. int chunked_header_len = snprintf(chunked_header, sizeof(chunked_header), "%x\r\n", len);
  20. write(chunked_header, chunked_header_len);
  21. if (buf && len) {
  22. state = SEND_CHUNKED;
  23. ret = write(buf, len);
  24. } else {
  25. state = SEND_CHUNKED_END;
  26. }
  27. write("\r\n", 2);
  28. return ret;
  29. }
  30. int HttpResponseWriter::WriteBody(const char* buf, int len /* = -1 */) {
  31. if (response->IsChunked()) {
  32. return WriteChunked(buf, len);
  33. }
  34. if (len == -1) len = strlen(buf);
  35. if (state == SEND_BEGIN) {
  36. response->body.append(buf, len);
  37. return len;
  38. } else {
  39. state = SEND_BODY;
  40. return write(buf, len);
  41. }
  42. }
  43. int HttpResponseWriter::WriteResponse(HttpResponse* resp) {
  44. if (resp == NULL) {
  45. response->status_code = HTTP_STATUS_INTERNAL_SERVER_ERROR;
  46. return 0;
  47. }
  48. bool is_dump_headers = state == SEND_BEGIN ? true : false;
  49. std::string msg = resp->Dump(is_dump_headers, true);
  50. state = SEND_BODY;
  51. return write(msg);
  52. }
  53. int HttpResponseWriter::SSEvent(const std::string& data, const char* event /* = "message" */) {
  54. if (state == SEND_BEGIN) {
  55. EndHeaders("Content-Type", "text/event-stream");
  56. }
  57. std::string msg;
  58. msg = "event: "; msg += event; msg += "\n";
  59. msg += "data: "; msg += data; msg += "\n\n";
  60. state = SEND_BODY;
  61. return write(msg);
  62. }
  63. int HttpResponseWriter::End(const char* buf /* = NULL */, int len /* = -1 */) {
  64. if (end == SEND_END) return 0;
  65. end = SEND_END;
  66. if (!isConnected()) {
  67. return -1;
  68. }
  69. int ret = 0;
  70. bool keepAlive = response->IsKeepAlive();
  71. if (state == SEND_CHUNKED) {
  72. if (buf) {
  73. ret = WriteChunked(buf, len);
  74. }
  75. if (state == SEND_CHUNKED) {
  76. EndChunked();
  77. }
  78. } else {
  79. if (buf) {
  80. ret = WriteBody(buf, len);
  81. }
  82. bool is_dump_headers = true;
  83. bool is_dump_body = true;
  84. if (state == SEND_HEADER) {
  85. is_dump_headers = false;
  86. } else if (state == SEND_BODY) {
  87. is_dump_headers = false;
  88. is_dump_body = false;
  89. }
  90. if (is_dump_body) {
  91. std::string msg = response->Dump(is_dump_headers, is_dump_body);
  92. state = SEND_BODY;
  93. ret = write(msg);
  94. }
  95. }
  96. if (!keepAlive) {
  97. close(true);
  98. }
  99. return ret;
  100. }
  101. }