1 /*
2 * Copyright 2022 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Niels Sascha Reedijk, niels.reedijk@gmail.com
7 */
8
9 #include "HttpDebugLogger.h"
10
11 #include <iostream>
12
13 #include <ErrorsExt.h>
14 #include <HttpSession.h>
15 #include <NetServicesDefs.h>
16
17 using namespace BPrivate::Network;
18
19
HttpDebugLogger()20 HttpDebugLogger::HttpDebugLogger()
21 :
22 BLooper("HttpDebugLogger")
23 {
24 }
25
26
27 void
SetConsoleLogging(bool enabled)28 HttpDebugLogger::SetConsoleLogging(bool enabled)
29 {
30 fConsoleLogging = enabled;
31 }
32
33
34 void
SetFileLogging(const char * path)35 HttpDebugLogger::SetFileLogging(const char* path)
36 {
37 if (auto status = fLogFile.SetTo(path, B_WRITE_ONLY | B_CREATE_FILE | B_OPEN_AT_END);
38 status != B_OK)
39 throw BSystemError("BFile::SetTo()", status);
40 }
41
42
43 void
MessageReceived(BMessage * message)44 HttpDebugLogger::MessageReceived(BMessage* message)
45 {
46 BString output;
47
48 if (!message->HasInt32(UrlEventData::Id))
49 return BLooper::MessageReceived(message);
50 int32 id = message->FindInt32(UrlEventData::Id);
51 output << "[" << id << "] ";
52
53 switch (message->what) {
54 case UrlEvent::HostNameResolved:
55 {
56 BString hostname;
57 message->FindString(UrlEventData::HostName, &hostname);
58 output << "<HostNameResolved> " << hostname;
59 break;
60 }
61 case UrlEvent::ConnectionOpened:
62 output << "<ConnectionOpened>";
63 break;
64 case UrlEvent::UploadProgress:
65 {
66 off_t numBytes = message->GetInt64(UrlEventData::NumBytes, -1);
67 off_t totalBytes = message->GetInt64(UrlEventData::TotalBytes, -1);
68 output << "<UploadProgress> bytes uploaded " << numBytes;
69 if (totalBytes == -1)
70 output << " (total unknown)";
71 else
72 output << " (" << totalBytes << " total)";
73 break;
74 }
75 case UrlEvent::ResponseStarted:
76 {
77 output << "<ResponseStarted>";
78 break;
79 }
80 case UrlEvent::HttpRedirect:
81 {
82 BString redirectUrl;
83 message->FindString(UrlEventData::HttpRedirectUrl, &redirectUrl);
84 output << "<HttpRedirect> to: " << redirectUrl;
85 break;
86 }
87 case UrlEvent::HttpStatus:
88 {
89 int16 status = message->FindInt16(UrlEventData::HttpStatusCode);
90 output << "<HttpStatus> code: " << status;
91 break;
92 }
93 case UrlEvent::HttpFields:
94 {
95 output << "<HttpFields> All fields parsed";
96 break;
97 }
98 case UrlEvent::DownloadProgress:
99 {
100 off_t numBytes = message->GetInt64(UrlEventData::NumBytes, -1);
101 off_t totalBytes = message->GetInt64(UrlEventData::TotalBytes, -1);
102 output << "<DownloadProgress> bytes downloaded " << numBytes;
103 if (totalBytes == -1)
104 output << " (total unknown)";
105 else
106 output << " (" << totalBytes << " total)";
107 break;
108 }
109 case UrlEvent::BytesWritten:
110 {
111 off_t numBytes = message->GetInt64(UrlEventData::NumBytes, -1);
112 output << "<BytesWritten> bytes written to output: " << numBytes;
113 break;
114 }
115 case UrlEvent::RequestCompleted:
116 {
117 bool success = message->GetBool(UrlEventData::Success, false);
118 output << "<RequestCompleted> success: ";
119 if (success)
120 output << "true";
121 else
122 output << "false";
123 break;
124 }
125 case UrlEvent::DebugMessage:
126 {
127 uint32 debugType = message->GetUInt32(UrlEventData::DebugType, 0);
128 BString debugMessage;
129 message->FindString(UrlEventData::DebugMessage, &debugMessage);
130 output << "<DebugMessage> ";
131 switch (debugType) {
132 case UrlEventData::DebugInfo:
133 output << "INFO: ";
134 break;
135 case UrlEventData::DebugWarning:
136 output << "WARNING: ";
137 break;
138 case UrlEventData::DebugError:
139 output << "ERROR: ";
140 break;
141 default:
142 output << "UNKNOWN: ";
143 break;
144 }
145 output << debugMessage;
146 break;
147 }
148 default:
149 return BLooper::MessageReceived(message);
150 }
151
152 if (fConsoleLogging)
153 std::cout << output.String() << std::endl;
154
155 if (fLogFile.InitCheck() == B_OK) {
156 output += '\n';
157 if (auto status = fLogFile.WriteExactly(output.String(), output.Length()); status != B_OK)
158 throw BSystemError("BFile::WriteExactly()", status);
159 if (auto status = fLogFile.Flush(); status != B_OK)
160 throw BSystemError("BFile::Flush()", status);
161 }
162 }
163