@@ -46,7 +46,7 @@ private static OriginalHttpResponse common(Request request, boolean followRedire
46
46
while (RateLimitHandler .getInstance (accountId ).shouldWait (request )) {
47
47
if (rateLimitHit ){
48
48
if (!(request .url ().toString ().contains ("insertRuntimeLog" ) || request .url ().toString ().contains ("insertTestingLog" ) || request .url ().toString ().contains ("insertProtectionLog" ))) {
49
- loggerMaker .infoAndAddToDb ("Rate limit hit, sleeping" , LogDb . TESTING );
49
+ loggerMaker .infoAndAddToDb ("Rate limit hit, sleeping" );
50
50
}else {
51
51
System .out .println ("Rate limit hit, sleeping" );
52
52
}
@@ -57,7 +57,7 @@ private static OriginalHttpResponse common(Request request, boolean followRedire
57
57
58
58
if (i %30 == 0 ) {
59
59
if (!(request .url ().toString ().contains ("insertRuntimeLog" ) || request .url ().toString ().contains ("insertTestingLog" ) || request .url ().toString ().contains ("insertProtectionLog" ))) {
60
- loggerMaker .infoAndAddToDb ("waiting for rate limit availability" , LogDb . TESTING );
60
+ loggerMaker .infoAndAddToDb ("waiting for rate limit availability" );
61
61
}else {
62
62
System .out .println ("waiting for rate limit availability" );
63
63
}
@@ -81,13 +81,27 @@ private static OriginalHttpResponse common(Request request, boolean followRedire
81
81
82
82
Call call = client .newCall (request );
83
83
Response response = null ;
84
- String body ;
84
+ String body = null ;
85
85
byte [] grpcBody = null ;
86
+ Map <String , List <String >> responseHeaders = new HashMap <>();
86
87
try {
87
88
response = call .execute ();
88
- ResponseBody responseBody = response .peekBody (MAX_RESPONSE_SIZE );
89
- if (responseBody == null ) {
90
- throw new Exception ("Couldn't read response body" );
89
+ Headers headers = response .headers ();
90
+ responseHeaders = generateHeadersMapFromHeadersObject (headers );
91
+
92
+ String contentTypeHeader = getHeaderValue (responseHeaders , HttpRequestResponseUtils .CONTENT_TYPE );
93
+
94
+ if (contentTypeHeader != null && !contentTypeHeader .isEmpty () &&
95
+ contentTypeHeader .equalsIgnoreCase (HttpRequestResponseUtils .TEXT_EVENT_STREAM_CONTENT_TYPE )) {
96
+ body = getEventStreamResponseBodyWithTimeout (response , 20000 ); // 20 seconds timeout
97
+ }
98
+
99
+ ResponseBody responseBody = null ;
100
+ if (body == null ) {
101
+ responseBody = response .peekBody (MAX_RESPONSE_SIZE );
102
+ if (responseBody == null ) {
103
+ throw new Exception ("Couldn't read response body" );
104
+ }
91
105
}
92
106
try {
93
107
if (requestProtocol != null && requestProtocol .contains (HttpRequestResponseUtils .GRPC_CONTENT_TYPE )) {//GRPC request
@@ -98,13 +112,13 @@ private static OriginalHttpResponse common(Request request, boolean followRedire
98
112
builder .append (b ).append ("," );
99
113
}
100
114
if (!(request .url ().toString ().contains ("insertRuntimeLog" ) || request .url ().toString ().contains ("insertTestingLog" ) || request .url ().toString ().contains ("insertProtectionLog" ))) {
101
- loggerMaker .infoAndAddToDb (builder .toString (), LogDb . TESTING );
115
+ loggerMaker .infoAndAddToDb (builder .toString ());
102
116
}else {
103
117
System .out .println (builder .toString ());
104
118
}
105
119
String responseBase64Encoded = Base64 .getEncoder ().encodeToString (grpcBody );
106
120
if (!(request .url ().toString ().contains ("insertRuntimeLog" ) || request .url ().toString ().contains ("insertTestingLog" ) || request .url ().toString ().contains ("insertProtectionLog" ))) {
107
- loggerMaker .infoAndAddToDb ("grpc response base64 encoded:" + responseBase64Encoded , LogDb . TESTING );
121
+ loggerMaker .infoAndAddToDb ("grpc response base64 encoded:" + responseBase64Encoded );
108
122
}else {
109
123
System .out .println ("grpc response base64 encoded:" + responseBase64Encoded );
110
124
}
@@ -115,7 +129,13 @@ private static OriginalHttpResponse common(Request request, boolean followRedire
115
129
body = HttpRequestResponseUtils .convertXmlToJson (responseBody .string ());
116
130
}
117
131
else {
118
- body = responseBody .string ();
132
+ if (body == null ) {
133
+ if (responseBody != null ){
134
+ body = responseBody .string ();
135
+ } else {
136
+ body = "{}" ; // default to empty json if response body is null
137
+ }
138
+ }
119
139
}
120
140
} catch (IOException e ) {
121
141
if (!(request .url ().toString ().contains ("insertRuntimeLog" ) || request .url ().toString ().contains ("insertTestingLog" ) || request .url ().toString ().contains ("insertProtectionLog" ))) {
@@ -138,14 +158,36 @@ private static OriginalHttpResponse common(Request request, boolean followRedire
138
158
}
139
159
}
140
160
141
- int statusCode = response .code ();
142
- Headers headers = response .headers ();
143
-
144
- Map <String , List <String >> responseHeaders = generateHeadersMapFromHeadersObject (headers );
161
+ int statusCode = -1 ;
162
+ if (response != null ) {
163
+ statusCode = response .code ();
164
+ } else {
165
+ loggerMaker .errorAndAddToDb ("Response is null when trying to access status code and headers" , LogDb .TESTING );
166
+ }
145
167
return new OriginalHttpResponse (body , responseHeaders , statusCode );
146
168
}
147
169
170
+ private static String getHeaderValue (Map <String , List <String >> responseHeaders , String headerName ) {
171
+ if (responseHeaders == null || responseHeaders .isEmpty ()) {
172
+ return null ;
173
+ }
174
+
175
+ for (String key : responseHeaders .keySet ()) {
176
+ if (key .equalsIgnoreCase (headerName )) {
177
+ List <String > values = responseHeaders .get (key );
178
+ if (values != null && !values .isEmpty ()) {
179
+ return values .get (0 ).toUpperCase ();
180
+ }
181
+ }
182
+ }
183
+ return null ;
184
+ }
185
+
148
186
public static Map <String , List <String >> generateHeadersMapFromHeadersObject (Headers headers ) {
187
+ if (headers == null || headers .size () == 0 ) {
188
+ return Collections .emptyMap ();
189
+ }
190
+
149
191
Iterator <Pair <String , String >> headersIterator = headers .iterator ();
150
192
Map <String , List <String >> responseHeaders = new HashMap <>();
151
193
while (headersIterator .hasNext ()) {
@@ -556,6 +598,39 @@ private static boolean isJsonRpcRequest(OriginalHttpRequest request) {
556
598
return false ;
557
599
}
558
600
}
601
+
602
+ private static String getEventStreamResponseBodyWithTimeout (Response response , long timeoutMs ) throws IOException {
603
+ StringBuilder sb = new StringBuilder ();
604
+ InputStream is = response .body ().byteStream ();
605
+ Scanner scanner = new Scanner (is );
606
+
607
+ long startTime = System .currentTimeMillis ();
608
+ int waitLoopCount = 0 ;
609
+
610
+ try {
611
+ while (System .currentTimeMillis () - startTime < timeoutMs ) {
612
+ if (scanner .hasNextLine ()) {
613
+ String line = scanner .nextLine ();
614
+ sb .append (line ).append ("\n " );
615
+ waitLoopCount = 0 ; // Reset wait loop count on new data
616
+ } else {
617
+ // Avoid tight CPU loop; sleep briefly
618
+ waitLoopCount ++;
619
+ if (waitLoopCount > 20 ) { // If no data for a while, break
620
+ break ;
621
+ }
622
+ Thread .sleep (100 );
623
+ }
624
+ }
625
+ } catch (Exception e ) {
626
+ // Read timeout or interruption: end gracefully
627
+ sb .append ("\n [Stream ended early: " ).append (e .getMessage ()).append ("]" );
628
+ } finally {
629
+ scanner .close ();
630
+ }
631
+ return sb .toString ();
632
+ }
633
+
559
634
560
635
private static class SseSession {
561
636
String sessionId ;
@@ -597,6 +672,7 @@ private static SseSession openSseSession(String host, boolean debug) throws Exce
597
672
}
598
673
}
599
674
}
675
+ scanner .close ();
600
676
// Keep the stream open for later reading
601
677
session .messages = Collections .synchronizedList (new ArrayList <>());
602
678
new Thread (() -> {
0 commit comments