1 16 17 package org.apache.cocoon.reading; 18 19 import java.io.ByteArrayOutputStream ; 20 import java.io.IOException ; 21 import java.io.OutputStream ; 22 import java.util.Map ; 23 24 import javax.servlet.ServletContext ; 25 import javax.servlet.http.HttpServletRequest ; 26 import javax.servlet.http.HttpServletResponse ; 27 import javax.servlet.http.HttpUtils ; 28 import javax.xml.soap.SOAPException ; 29 30 import org.apache.avalon.framework.activity.Disposable; 31 import org.apache.avalon.framework.configuration.Configurable; 32 import org.apache.avalon.framework.configuration.Configuration; 33 import org.apache.avalon.framework.configuration.ConfigurationException; 34 import org.apache.avalon.framework.parameters.Parameters; 35 import org.apache.avalon.framework.service.ServiceException; 36 import org.apache.avalon.framework.service.ServiceManager; 37 38 import org.apache.axis.AxisFault; 39 import org.apache.axis.Constants; 40 import org.apache.axis.Message; 41 import org.apache.axis.MessageContext; 42 import org.apache.axis.soap.SOAPConstants; 43 import org.apache.axis.transport.http.AxisHttpSession; 44 import org.apache.axis.transport.http.HTTPConstants; 45 46 import org.apache.cocoon.ProcessingException; 47 import org.apache.cocoon.components.axis.SoapServer; 48 import org.apache.cocoon.environment.ObjectModelHelper; 49 import org.apache.cocoon.environment.SourceResolver; 50 import org.apache.cocoon.environment.http.HttpEnvironment; 51 52 import org.w3c.dom.Element ; 53 import org.xml.sax.SAXException ; 54 55 81 public class AxisRPCReader extends ServiceableReader 82 implements Configurable, Disposable { 83 84 private SoapServer m_server; 86 87 88 private boolean m_isDevelompent = false; 89 90 93 public void configure(Configuration config) throws ConfigurationException { 94 m_isDevelompent = config.getChild("development-stage").getValueAsBoolean(m_isDevelompent ); 95 } 96 97 public void service(final ServiceManager manager) throws ServiceException { 98 super.service(manager); 99 m_server = (SoapServer) manager.lookup(SoapServer.ROLE); 101 } 102 103 121 public void setup( 122 final SourceResolver resolver, 123 final Map objectModel, 124 final String src, 125 final Parameters parameters) 126 throws ProcessingException, IOException , SAXException { 127 super.setup(resolver, objectModel, src, parameters); 128 129 checkHTTPPost(objectModel); 130 131 if (getLogger().isDebugEnabled()) { 132 getLogger().debug("AxisRPCReader.setup() complete"); 133 } 134 } 135 136 142 private void checkHTTPPost(final Map objectModel) 143 throws ProcessingException { 144 String method = ObjectModelHelper.getRequest(objectModel).getMethod(); 145 146 if (!"POST".equalsIgnoreCase(method)) 147 throw new ProcessingException( 148 "Reader only supports HTTP-POST (supplied was " + method + ")" 149 ); 150 } 151 152 164 public void generate() 165 throws IOException , SAXException , ProcessingException { 166 HttpServletRequest req = 167 (HttpServletRequest ) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT); 168 HttpServletResponse res = 169 (HttpServletResponse ) objectModel.get(HttpEnvironment.HTTP_RESPONSE_OBJECT); 170 ServletContext con = 171 (ServletContext ) objectModel.get(HttpEnvironment.HTTP_SERVLET_CONTEXT); 172 173 String soapAction = null; 174 MessageContext msgContext = null; 175 Message responseMsg = null; 176 177 try { 178 res.setBufferSize(1024 * 8); 180 msgContext = m_server.createMessageContext(req, res, con); 182 183 Message requestMsg = 185 new Message( 186 req.getInputStream(), false, 187 req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE), 188 req.getHeader(HTTPConstants.HEADER_CONTENT_LOCATION) 189 ); 190 191 if (getLogger().isDebugEnabled()) { 192 getLogger().debug("Request message:\n" + messageToString(requestMsg)); 193 } 194 195 msgContext.setRequestMessage(requestMsg); 197 String url = HttpUtils.getRequestURL(req).toString(); 198 msgContext.setProperty(MessageContext.TRANS_URL, url); 199 200 try { 201 soapAction = getSoapAction(req); 211 212 if (soapAction != null) { 213 msgContext.setUseSOAPAction(true); 214 msgContext.setSOAPActionURI(soapAction); 215 } 216 217 msgContext.setSession(new AxisHttpSession(req)); 219 220 if(getLogger().isDebugEnabled()) { 222 getLogger().debug("Invoking Axis Engine"); 223 } 224 225 m_server.invoke(msgContext); 226 227 if(getLogger().isDebugEnabled()) { 228 getLogger().debug("Return from Axis Engine"); 229 } 230 231 responseMsg = msgContext.getResponseMessage(); 232 if (responseMsg == null) { 233 throw new Exception ("no response message"); 235 } 236 } catch (AxisFault fault) { 237 if (getLogger().isErrorEnabled()) { 238 getLogger().error("Axis Fault", fault); 239 } 240 241 processAxisFault(fault); 243 configureResponseFromAxisFault(res, fault); 244 responseMsg = msgContext.getResponseMessage(); 245 if (responseMsg == null) { 246 responseMsg = new Message(fault); 247 } 248 } catch (Exception e) { 249 responseMsg = msgContext.getResponseMessage(); 251 res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 252 if (getLogger().isErrorEnabled()) { 253 getLogger().error("Error during SOAP call", e); 254 } 255 if (responseMsg == null) { 256 AxisFault fault = AxisFault.makeFault(e); 257 processAxisFault(fault); 258 responseMsg = new Message(fault); 259 } 260 } 261 } catch (AxisFault fault) { 262 if (getLogger().isErrorEnabled()) { 263 getLogger().error("Axis fault occured while perforing request", fault); 264 } 265 processAxisFault(fault); 266 configureResponseFromAxisFault(res, fault); 267 responseMsg = msgContext.getResponseMessage(); 268 if( responseMsg == null) { 269 responseMsg = new Message(fault); 270 } 271 } catch (Exception e) { 272 throw new ProcessingException("Exception thrown while performing request", e); 273 } 274 275 if (responseMsg != null) { 277 if (getLogger().isDebugEnabled()) { 278 getLogger().debug("Sending response:\n" + messageToString(responseMsg)); 279 } 280 281 sendResponse(getProtocolVersion(req), msgContext.getSOAPConstants(), res, responseMsg); 282 } 283 284 if (getLogger().isDebugEnabled()) { 285 getLogger().debug("AxisRPCReader.generate() complete"); 286 } 287 } 288 289 295 protected void processAxisFault(AxisFault fault) { 296 Element runtimeException = fault.lookupFaultDetail( 298 Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION); 299 if (runtimeException != null) { 300 getLogger().info("AxisFault:", fault); 301 fault.removeFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION); 303 } else if (getLogger().isDebugEnabled()) { 304 getLogger().debug("AxisFault:", fault); 305 } 306 if (m_isDevelompent) { 308 fault.removeFaultDetail(Constants.QNAME_FAULTDETAIL_STACKTRACE); 310 } 311 } 312 313 319 private void configureResponseFromAxisFault(HttpServletResponse response, 320 AxisFault fault) { 321 int status = getHttpServletResponseStatus(fault); 325 if (status == HttpServletResponse.SC_UNAUTHORIZED) { 326 response.setHeader("WWW-Authenticate","Basic realm=\"AXIS\""); 329 } 330 response.setStatus(status); 331 } 332 333 339 protected int getHttpServletResponseStatus(AxisFault af) { 340 return af.getFaultCode().getLocalPart().startsWith("Server.Unauth") 342 ? HttpServletResponse.SC_UNAUTHORIZED 343 : HttpServletResponse.SC_INTERNAL_SERVER_ERROR; 344 } 345 346 355 private void sendResponse( 356 final String clientVersion, 357 final SOAPConstants constants, 358 final HttpServletResponse res, 359 final Message responseMsg) 360 throws AxisFault, IOException { 361 if (responseMsg == null) { 362 res.setStatus(HttpServletResponse.SC_NO_CONTENT); 363 364 if (getLogger().isDebugEnabled()) { 365 getLogger().debug("No axis response, not sending one"); 366 } 367 } else { 368 if (getLogger().isDebugEnabled()) { 369 getLogger().debug("Returned Content-Type:" + responseMsg.getContentType(constants)); 370 getLogger().debug("Returned Content-Length:" + responseMsg.getContentLength()); 371 } 372 373 try { 374 res.setContentType(responseMsg.getContentType(constants)); 375 responseMsg.writeTo(res.getOutputStream()); 376 } catch (SOAPException e) { 377 getLogger().error("Exception sending response", e); 378 } 379 } 380 381 if (!res.isCommitted()) { 382 res.flushBuffer(); } 384 } 385 386 394 private String getSoapAction(HttpServletRequest req) 395 throws AxisFault { 396 String soapAction = req.getHeader(HTTPConstants.HEADER_SOAP_ACTION); 397 398 if (getLogger().isDebugEnabled()) { 399 getLogger().debug("HEADER_SOAP_ACTION:" + soapAction); 400 } 401 402 if (soapAction == null) { 407 throw new AxisFault( 408 "Client.NoSOAPAction", 409 "No SOAPAction header", 410 null, null 411 ); 412 } 413 414 if (soapAction.length() == 0) 415 soapAction = req.getContextPath(); 417 return soapAction; 418 } 419 420 424 private String getProtocolVersion(HttpServletRequest req) { 425 String ret = HTTPConstants.HEADER_PROTOCOL_V10; 426 String prot = req.getProtocol(); 427 if (prot!= null) { 428 int sindex= prot.indexOf('/'); 429 if (-1 != sindex) { 430 String ver= prot.substring(sindex+1); 431 if (HTTPConstants.HEADER_PROTOCOL_V11.equals(ver.trim())) { 432 ret = HTTPConstants.HEADER_PROTOCOL_V11; 433 } 434 } 435 } 436 return ret; 437 } 438 439 446 private String messageToString(final Message msg) { 447 try { 448 OutputStream os = new ByteArrayOutputStream (); 449 msg.writeTo(os); 450 return os.toString(); 451 } catch (Exception e) { 452 if (getLogger().isWarnEnabled()) { 453 getLogger().warn( 454 "Warning, could not convert message (" + msg + ") into string", e 455 ); 456 } 457 458 return null; 459 } 460 } 461 462 465 public void dispose() { 466 manager.release(m_server); 467 } 468 } 469 | Popular Tags |