private void addContentType(Path path, final HttpResponse response) { if (response.getEntity() != null && response.getEntity().getContentType() != null) { WebServerLog.log( this, "Response entity already contains content type: " + response.getEntity().getContentType().getValue()); return; } if (response.containsHeader(HttpHeaders.CONTENT_TYPE)) { response.removeHeaders(HttpHeaders.CONTENT_TYPE); } String contentType = null; final int i = path.toString().lastIndexOf('.'); if (i >= 0) { String extension = path.toString().substring(i + 1); contentType = extension2contentType.get(extension); } if (contentType == null) { return; } response.addHeader(HttpHeaders.CONTENT_TYPE, contentType); }
/** Process the incoming request */ @SuppressWarnings({"unchecked"}) public void run() { String method = request.getRequestLine().getMethod().toUpperCase(); msgContext.setProperty( Constants.Configuration.HTTP_METHOD, request.getRequestLine().getMethod()); if (NHttpConfiguration.getInstance().isHttpMethodDisabled(method)) { handleException("Unsupported method : " + method, null); } // String uri = request.getRequestLine().getUri(); String oriUri = request.getRequestLine().getUri(); String restUrlPostfix = NhttpUtil.getRestUrlPostfix(oriUri, cfgCtx.getServicePath()); msgContext.setProperty(NhttpConstants.REST_URL_POSTFIX, restUrlPostfix); String servicePrefix = oriUri.substring(0, oriUri.indexOf(restUrlPostfix)); if (servicePrefix.indexOf("://") == -1) { HttpInetConnection inetConn = (HttpInetConnection) conn; InetAddress localAddr = inetConn.getLocalAddress(); if (localAddr != null) { servicePrefix = schemeName + "://" + localAddr.getHostName() + ":" + inetConn.getLocalPort() + servicePrefix; } if (inetConn.getLocalPort() > 0) { msgContext.setProperty(NhttpConstants.SERVER_PORT, inetConn.getLocalPort()); } } msgContext.setProperty(NhttpConstants.SERVICE_PREFIX, servicePrefix); if ("GET".equals(method)) { httpGetRequestProcessor.process(request, response, msgContext, conn, os, isRestDispatching); } else if ("POST".equals(method)) { processEntityEnclosingMethod(); } else if ("PUT".equals(method)) { processEntityEnclosingMethod(); } else if ("HEAD".equals(method)) { processNonEntityEnclosingMethod(); } else if ("OPTIONS".equals(method)) { processNonEntityEnclosingMethod(); } else if ("DELETE".equals(method)) { processGetAndDelete("DELETE"); } else if ("TRACE".equals(method)) { processNonEntityEnclosingMethod(); } else { handleException("Unsupported method : " + method, null); } // here the RequestResponseTransport plays an important role when it comes to // dual channel invocation. This is becasue we need to ACK to the request once the request // is received to synapse. Otherwise we will not be able to support the single channel // invocation within the actual service and synapse for a dual channel request from the // client. if (isAckRequired()) { String respWritten = ""; if (msgContext.getOperationContext() != null) { respWritten = (String) msgContext.getOperationContext().getProperty(Constants.RESPONSE_WRITTEN); } boolean respWillFollow = !Constants.VALUE_TRUE.equals(respWritten) && !"SKIP".equals(respWritten); boolean acked = (((RequestResponseTransport) msgContext.getProperty(RequestResponseTransport.TRANSPORT_CONTROL)) .getStatus() == RequestResponseTransport.RequestResponseTransportStatus.ACKED); boolean forced = msgContext.isPropertyTrue(NhttpConstants.FORCE_SC_ACCEPTED); boolean nioAck = msgContext.isPropertyTrue("NIO-ACK-Requested", false); if (respWillFollow || acked || forced || nioAck) { if (!nioAck) { if (log.isDebugEnabled()) { log.debug( "Sending 202 Accepted response for MessageID : " + msgContext.getMessageID() + " response written : " + respWritten + " response will follow : " + respWillFollow + " acked : " + acked + " forced ack : " + forced); } response.setStatusCode(HttpStatus.SC_ACCEPTED); } else { if (log.isDebugEnabled()) { log.debug( "Sending ACK response with status " + msgContext.getProperty(NhttpConstants.HTTP_SC) + ", for MessageID : " + msgContext.getMessageID()); } response.setStatusCode( Integer.parseInt(msgContext.getProperty(NhttpConstants.HTTP_SC).toString())); Map<String, String> responseHeaders = (Map<String, String>) msgContext.getProperty(MessageContext.TRANSPORT_HEADERS); if (responseHeaders != null) { for (String headerName : responseHeaders.keySet()) { response.addHeader(headerName, responseHeaders.get(headerName)); String excessProp = NhttpConstants.EXCESS_TRANSPORT_HEADERS; Map map = (Map) msgContext.getProperty(excessProp); if (map != null) { log.debug( "Number of excess values for " + headerName + " header is : " + ((Collection) (map.get(headerName))).size()); for (Iterator iterator = map.keySet().iterator(); iterator.hasNext(); ) { String key = (String) iterator.next(); for (String excessVal : (Collection<String>) map.get(key)) { response.addHeader(headerName, (String) excessVal); } } } } } } if (metrics != null) { metrics.incrementMessagesSent(); } try { /* * Remove Content-Length and Transfer-Encoding headers, if already present. * */ response.removeHeaders(HTTP.TRANSFER_ENCODING); response.removeHeaders(HTTP.CONTENT_LEN); serverHandler.commitResponse(conn, response); } catch (HttpException e) { if (metrics != null) { metrics.incrementFaultsSending(); } handleException("Unexpected HTTP protocol error : " + e.getMessage(), e); } catch (ConnectionClosedException e) { if (metrics != null) { metrics.incrementFaultsSending(); } log.warn("Connection closed by client (Connection closed)"); } catch (IllegalStateException e) { if (metrics != null) { metrics.incrementFaultsSending(); } log.warn("Connection closed by client (Buffer closed)"); } catch (IOException e) { if (metrics != null) { metrics.incrementFaultsSending(); } handleException("IO Error sending response message", e); } catch (Exception e) { if (metrics != null) { metrics.incrementFaultsSending(); } handleException("General Error sending response message", e); } if (is != null) { try { is.close(); } catch (IOException ignore) { } } // make sure that the output stream is flushed and closed properly try { os.flush(); os.close(); } catch (IOException ignore) { } } } }