xref: /haiku/src/tests/kits/net/netservices2/HttpDebugLogger.cpp (revision 71e29bbeea760848317843508c711f2a0b446fbb)
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