@@ -39,10 +39,12 @@ public void setStatusCode(int statusCode) {
3939
4040 public void setBody (String body ) {
4141 this .body = body != null ? body : "" ;
42+ this .bytebody = null ; // Clear byte body when setting string body
4243 }
4344
4445 public void setBody (byte [] body ) {
4546 this .bytebody = body ;
47+ this .body = "" ; // Clear string body when setting byte body
4648 }
4749
4850 public void setHeaders (Map <String , String > headers ) {
@@ -59,47 +61,58 @@ public void setContentTypeFromFilename(String filename) {
5961 setHeader ("Content-Type" , mimeType );
6062 }
6163
62- public String build () {
63- StringBuilder sb = new StringBuilder ();
64-
65- // Calculate content length (both String and byte[] body)
64+ /*
65+ * Builds the complete HTTP response as a byte array and preserves binary content without corruption.
66+ * @return Complete HTTP response (headers + body) as byte[]
67+ */
68+ public byte [] build () {
69+ // Determine content body and length
70+ byte [] contentBody ;
6671 int contentLength ;
67- if (body .isEmpty () && bytebody != null ) {
72+
73+ if (bytebody != null ) {
74+ contentBody = bytebody ;
6875 contentLength = bytebody .length ;
69- setBody (new String (bytebody , StandardCharsets .UTF_8 ));
7076 } else {
71- contentLength = body .getBytes (StandardCharsets .UTF_8 ).length ;
77+ contentBody = body .getBytes (StandardCharsets .UTF_8 );
78+ contentLength = contentBody .length ;
7279 }
7380
81+ // Build headers as String
82+ StringBuilder headerBuilder = new StringBuilder ();
83+
7484 // Status line
7585 String reason = REASON_PHRASES .getOrDefault (statusCode , "" );
76- sb .append (PROTOCOL ).append (" " ).append (statusCode );
86+ headerBuilder .append (PROTOCOL ).append (" " ).append (statusCode );
7787 if (!reason .isEmpty ()) {
78- sb .append (" " ).append (reason );
88+ headerBuilder .append (" " ).append (reason );
7989 }
80- sb .append (CRLF );
90+ headerBuilder .append (CRLF );
8191
8292 // User-defined headers
83- headers .forEach ((k , v ) -> sb .append (k ).append (": " ).append (v ).append (CRLF ));
93+ headers .forEach ((k , v ) -> headerBuilder .append (k ).append (": " ).append (v ).append (CRLF ));
8494
85- // Auto-append Content-Length if not set
95+ // Auto-append Content-Length if not set.
8696 if (!headers .containsKey ("Content-Length" )) {
87- sb .append ("Content-Length: " )
88- .append (contentLength )
89- .append (CRLF );
97+ headerBuilder .append ("Content-Length: " ).append (contentLength ).append (CRLF );
9098 }
9199
92- // Auto-append Connection if not set
100+ // Auto-append Connection if not set.
93101 if (!headers .containsKey ("Connection" )) {
94- sb .append ("Connection: close" ).append (CRLF );
102+ headerBuilder .append ("Connection: close" ).append (CRLF );
95103 }
96104
97105 // Blank line before body
98- sb .append (CRLF );
106+ headerBuilder .append (CRLF );
107+
108+ // Convert headers to bytes
109+ byte [] headerBytes = headerBuilder .toString ().getBytes (StandardCharsets .UTF_8 );
99110
100- // Body
101- sb .append (body );
111+ // Combine headers + body into single byte array
112+ byte [] response = new byte [headerBytes .length + contentBody .length ];
113+ System .arraycopy (headerBytes , 0 , response , 0 , headerBytes .length );
114+ System .arraycopy (contentBody , 0 , response , headerBytes .length , contentBody .length );
102115
103- return sb . toString () ;
116+ return response ;
104117 }
105118}
0 commit comments