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.sentrysoftware.wbem.sblim.cimclient.internal.http;
29  
30  /*-
31   * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
32   * WBEM Java Client
33   * ჻჻჻჻჻჻
34   * Copyright (C) 2023 Sentry Software
35   * ჻჻჻჻჻჻
36   * This program is free software: you can redistribute it and/or modify
37   * it under the terms of the GNU Lesser General Public License as
38   * published by the Free Software Foundation, either version 3 of the
39   * License, or (at your option) any later version.
40   *
41   * This program is distributed in the hope that it will be useful,
42   * but WITHOUT ANY WARRANTY; without even the implied warranty of
43   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
44   * GNU General Lesser Public License for more details.
45   *
46   * You should have received a copy of the GNU General Lesser Public
47   * License along with this program.  If not, see
48   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
49   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
50   */
51  
52  import java.io.ByteArrayOutputStream;
53  import java.io.IOException;
54  import java.io.OutputStream;
55  import java.util.logging.Level;
56  
57  import org.sentrysoftware.wbem.sblim.cimclient.internal.http.io.ASCIIPrintStream;
58  import org.sentrysoftware.wbem.sblim.cimclient.internal.http.io.ChunkedOutputStream;
59  import org.sentrysoftware.wbem.sblim.cimclient.internal.http.io.PersistentOutputStream;
60  import org.sentrysoftware.wbem.sblim.cimclient.internal.logging.LogAndTraceBroker;
61  
62  /**
63   * Class MessageWriter is responsible for creating http messages
64   * 
65   */
66  public class MessageWriter {
67  
68  	HttpHeader iHeader = null;
69  
70  	HttpServerMethod iMethod = null;
71  
72  	HttpHeader iTrailer = null;
73  
74  	boolean iChunked = false;
75  
76  	boolean iPersistent = false;
77  
78  	ASCIIPrintStream iRealOS;
79  
80  	ASCIIPrintStream iClientOS;
81  
82  	ByteArrayOutputStream iBufferedOS;
83  
84  	/**
85  	 * Ctor.
86  	 * 
87  	 * @param pStream
88  	 * @param pPersistent
89  	 * @param pChunked
90  	 */
91  	public MessageWriter(OutputStream pStream, boolean pPersistent, boolean pChunked) {
92  		this.iRealOS = new ASCIIPrintStream(pStream);
93  		this.iChunked = pChunked;
94  		this.iPersistent = pPersistent;
95  		this.iBufferedOS = new ByteArrayOutputStream();
96  		if (pChunked) {
97  			this.iClientOS = new ASCIIPrintStream(new ChunkedOutputStream(
98  					new PersistentOutputStream(this.iBufferedOS, pPersistent), 512));
99  		} else {
100 			this.iClientOS = new ASCIIPrintStream(new PersistentOutputStream(this.iBufferedOS,
101 					pPersistent));
102 		}
103 		this.iHeader = new HttpHeader();
104 		this.iMethod = new HttpServerMethod(HttpConnectionHandler.MAJOR_VERSION,
105 				HttpConnectionHandler.MINOR_VERSION, 200, "OK");
106 	}
107 
108 	/**
109 	 * Resets the stream
110 	 */
111 	public void reset() {
112 		this.iBufferedOS.reset();
113 	}
114 
115 	/**
116 	 * Sets the http header
117 	 * 
118 	 * @param header
119 	 *            The new value
120 	 */
121 	public void setHeader(HttpHeader header) {
122 		this.iHeader = header;
123 	}
124 
125 	/**
126 	 * Sets the http server method
127 	 * 
128 	 * @param method
129 	 *            The new value
130 	 */
131 	public void setMethod(HttpServerMethod method) {
132 		this.iMethod = method;
133 	}
134 
135 	/**
136 	 * Returns the http header
137 	 * 
138 	 * @return The http header
139 	 */
140 	public HttpHeader getHeader() {
141 		return this.iHeader;
142 	}
143 
144 	/**
145 	 * Returns the http server method
146 	 * 
147 	 * @return The http server method
148 	 */
149 	public HttpServerMethod getMethod() {
150 		return this.iMethod;
151 	}
152 
153 	/**
154 	 * Returns the output stream
155 	 * 
156 	 * @return The output stream
157 	 */
158 	public ASCIIPrintStream getOutputStream() {
159 		return this.iClientOS;
160 	}
161 
162 	/**
163 	 * Write the message and flushes the streams
164 	 * 
165 	 * @throws IOException
166 	 */
167 	public void close() throws IOException {
168 		this.iMethod.write(this.iRealOS);
169 		this.iRealOS.flush();
170 		if (!this.iChunked) this.iHeader.removeField("Transfer-Encoding");
171 		else this.iHeader.addField("Transfer-Encoding", "chunked");
172 		if (this.iPersistent) this.iHeader.addField("Connection", "Keep-iAlive");
173 		else this.iHeader.addField("Connection", "close");
174 
175 		this.iHeader.addField("Content-Type", "application/xml;charset=\"utf-8\"");
176 		if (!this.iChunked) this.iHeader.addField("Content-length", Integer
177 				.toString(this.iBufferedOS.size()));
178 		LogAndTraceBroker.getBroker().trace(Level.FINER,
179 				"Indication Response HTTP Headers= " + this.iHeader.toString());
180 		this.iHeader.write(this.iRealOS);
181 		this.iRealOS.flush();
182 		if (this.iChunked) this.iClientOS.close();
183 		this.iBufferedOS.writeTo(this.iRealOS);
184 		if (this.iChunked && (this.iTrailer != null)) {
185 			LogAndTraceBroker.getBroker().trace(Level.FINER,
186 					"Indication Response HTTP Trailer Headers= " + this.iTrailer.toString());
187 			this.iTrailer.write(this.iRealOS);
188 		}
189 		this.iRealOS.flush();
190 	}
191 
192 	/**
193 	 * Sets the trailer
194 	 * 
195 	 * @param pTrailer
196 	 *            The new value
197 	 */
198 	public void setTrailer(HttpHeader pTrailer) {
199 		this.iTrailer = pTrailer;
200 	}
201 }