View Javadoc
1   /*
2     (C) Copyright IBM Corp. 2005, 2013
3   
4     THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
5     ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
6     CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
7   
8     You can obtain a current copy of the Eclipse Public License from
9     http://www.opensource.org/licenses/eclipse-1.0.php
10  
11    @author : Roberto Pineiro, IBM, roberto.pineiro@us.ibm.com
12   * @author : Chung-hao Tan, IBM, chungtan@us.ibm.com
13   * 
14   * 
15   * Change History
16   * Flag       Date        Prog         Description
17   *------------------------------------------------------------------------------- 
18   * 17620      2005-06-29  thschaef     eliminate ASCIIPrintStream1 in import statement       
19   * 1535756    2006-08-07  lupusalex    Make code warning free
20   * 1565892    2006-11-28  lupusalex    Make SBLIM client JSR48 compliant
21   * 2003590    2008-06-30  blaschke-oss Change licensing from CPL to EPL
22   * 2524131    2009-01-21  raman_arora  Upgrade client to JDK 1.5 (Phase 1)
23   * 3304058    2011-05-20  blaschke-oss Use same date format in change history
24   * 3601894    2013-01-23  blaschke-oss Enhance HTTP and CIM-XML tracing
25   *    2620    2013-02-23  blaschke-oss Chunked output broken
26   */
27  
28  package org.metricshub.wbem.sblim.cimclient.internal.http;
29  
30  /*-
31   * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
32   * WBEM Java Client
33   * ჻჻჻჻჻჻
34   * Copyright 2023 - 2025 MetricsHub
35   * ჻჻჻჻჻჻
36   * Licensed under the Apache License, Version 2.0 (the "License");
37   * you may not use this file except in compliance with the License.
38   * You may obtain a copy of the License at
39   *
40   *      http://www.apache.org/licenses/LICENSE-2.0
41   *
42   * Unless required by applicable law or agreed to in writing, software
43   * distributed under the License is distributed on an "AS IS" BASIS,
44   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45   * See the License for the specific language governing permissions and
46   * limitations under the License.
47   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
48   */
49  
50  import java.io.ByteArrayOutputStream;
51  import java.io.IOException;
52  import java.io.OutputStream;
53  import java.util.logging.Level;
54  import org.metricshub.wbem.sblim.cimclient.internal.http.io.ASCIIPrintStream;
55  import org.metricshub.wbem.sblim.cimclient.internal.http.io.ChunkedOutputStream;
56  import org.metricshub.wbem.sblim.cimclient.internal.http.io.PersistentOutputStream;
57  import org.metricshub.wbem.sblim.cimclient.internal.logging.LogAndTraceBroker;
58  
59  /**
60   * Class MessageWriter is responsible for creating http messages
61   *
62   */
63  public class MessageWriter {
64  	HttpHeader iHeader = null;
65  
66  	HttpServerMethod iMethod = null;
67  
68  	HttpHeader iTrailer = null;
69  
70  	boolean iChunked = false;
71  
72  	boolean iPersistent = false;
73  
74  	ASCIIPrintStream iRealOS;
75  
76  	ASCIIPrintStream iClientOS;
77  
78  	ByteArrayOutputStream iBufferedOS;
79  
80  	/**
81  	 * Ctor.
82  	 *
83  	 * @param pStream
84  	 * @param pPersistent
85  	 * @param pChunked
86  	 */
87  	public MessageWriter(OutputStream pStream, boolean pPersistent, boolean pChunked) {
88  		this.iRealOS = new ASCIIPrintStream(pStream);
89  		this.iChunked = pChunked;
90  		this.iPersistent = pPersistent;
91  		this.iBufferedOS = new ByteArrayOutputStream();
92  		if (pChunked) {
93  			this.iClientOS =
94  				new ASCIIPrintStream(new ChunkedOutputStream(new PersistentOutputStream(this.iBufferedOS, pPersistent), 512));
95  		} else {
96  			this.iClientOS = new ASCIIPrintStream(new PersistentOutputStream(this.iBufferedOS, pPersistent));
97  		}
98  		this.iHeader = new HttpHeader();
99  		this.iMethod =
100 			new HttpServerMethod(HttpConnectionHandler.MAJOR_VERSION, HttpConnectionHandler.MINOR_VERSION, 200, "OK");
101 	}
102 
103 	/**
104 	 * Resets the stream
105 	 */
106 	public void reset() {
107 		this.iBufferedOS.reset();
108 	}
109 
110 	/**
111 	 * Sets the http header
112 	 *
113 	 * @param header
114 	 *            The new value
115 	 */
116 	public void setHeader(HttpHeader header) {
117 		this.iHeader = header;
118 	}
119 
120 	/**
121 	 * Sets the http server method
122 	 *
123 	 * @param method
124 	 *            The new value
125 	 */
126 	public void setMethod(HttpServerMethod method) {
127 		this.iMethod = method;
128 	}
129 
130 	/**
131 	 * Returns the http header
132 	 *
133 	 * @return The http header
134 	 */
135 	public HttpHeader getHeader() {
136 		return this.iHeader;
137 	}
138 
139 	/**
140 	 * Returns the http server method
141 	 *
142 	 * @return The http server method
143 	 */
144 	public HttpServerMethod getMethod() {
145 		return this.iMethod;
146 	}
147 
148 	/**
149 	 * Returns the output stream
150 	 *
151 	 * @return The output stream
152 	 */
153 	public ASCIIPrintStream getOutputStream() {
154 		return this.iClientOS;
155 	}
156 
157 	/**
158 	 * Write the message and flushes the streams
159 	 *
160 	 * @throws IOException
161 	 */
162 	public void close() throws IOException {
163 		this.iMethod.write(this.iRealOS);
164 		this.iRealOS.flush();
165 		if (!this.iChunked) this.iHeader.removeField("Transfer-Encoding"); else this.iHeader.addField(
166 				"Transfer-Encoding",
167 				"chunked"
168 			);
169 		if (this.iPersistent) this.iHeader.addField("Connection", "Keep-iAlive"); else this.iHeader.addField(
170 				"Connection",
171 				"close"
172 			);
173 
174 		this.iHeader.addField("Content-Type", "application/xml;charset=\"utf-8\"");
175 		if (!this.iChunked) this.iHeader.addField("Content-length", Integer.toString(this.iBufferedOS.size()));
176 		LogAndTraceBroker.getBroker().trace(Level.FINER, "Indication Response HTTP Headers= " + this.iHeader.toString());
177 		this.iHeader.write(this.iRealOS);
178 		this.iRealOS.flush();
179 		if (this.iChunked) this.iClientOS.close();
180 		this.iBufferedOS.writeTo(this.iRealOS);
181 		if (this.iChunked && (this.iTrailer != null)) {
182 			LogAndTraceBroker
183 				.getBroker()
184 				.trace(Level.FINER, "Indication Response HTTP Trailer Headers= " + this.iTrailer.toString());
185 			this.iTrailer.write(this.iRealOS);
186 		}
187 		this.iRealOS.flush();
188 	}
189 
190 	/**
191 	 * Sets the trailer
192 	 *
193 	 * @param pTrailer
194 	 *            The new value
195 	 */
196 	public void setTrailer(HttpHeader pTrailer) {
197 		this.iTrailer = pTrailer;
198 	}
199 }