@Override public void build() { ResponseHeaders responseHeaders = getObjectFactory().createResponseHeaders(); responseHeaders.getFidelity().addAll(fidelity); if (fidelityValidator.hasValidFidelity()) { for (String headerName : response.getHeaderNames()) { if (fidelityValidator.hasStarFidelity()) { ComplexParameter complexParameter = getObjectFactory().createComplexParameter(); complexParameter.setName(headerName); for (String nextElement : response.getHeaders(headerName)) { complexParameter.getValue().add(nextElement); } responseHeaders.getHeader().add(complexParameter); } } } responseHead.setHeaders(responseHeaders); }
/** * Initialize the source for this response. It may be corrected later if the request headers * forbids network use. */ private void initResponseSource() throws IOException { responseSource = ResponseSource.NETWORK; if (!policy.getUseCaches()) return; OkResponseCache responseCache = client.getOkResponseCache(); if (responseCache == null) return; CacheResponse candidate = responseCache.get(uri, method, requestHeaders.getHeaders().toMultimap(false)); if (candidate == null) return; Map<String, List<String>> responseHeadersMap = candidate.getHeaders(); cachedResponseBody = candidate.getBody(); if (!acceptCacheResponseType(candidate) || responseHeadersMap == null || cachedResponseBody == null) { Util.closeQuietly(cachedResponseBody); return; } RawHeaders rawResponseHeaders = RawHeaders.fromMultimap(responseHeadersMap, true); cachedResponseHeaders = new ResponseHeaders(uri, rawResponseHeaders); long now = System.currentTimeMillis(); this.responseSource = cachedResponseHeaders.chooseResponseSource(now, requestHeaders); if (responseSource == ResponseSource.CACHE) { this.cacheResponse = candidate; setResponse(cachedResponseHeaders, cachedResponseBody); } else if (responseSource == ResponseSource.CONDITIONAL_CACHE) { this.cacheResponse = candidate; } else if (responseSource == ResponseSource.NETWORK) { Util.closeQuietly(cachedResponseBody); } else { throw new AssertionError(); } }
private void initContentStream(InputStream transferStream) throws IOException { responseTransferIn = transferStream; if (transparentGzip && responseHeaders.isContentEncodingGzip()) { // If the response was transparently gzipped, remove the gzip header field // so clients don't double decompress. http://b/3009828 // // Also remove the Content-Length in this case because it contains the // length 528 of the gzipped response. This isn't terribly useful and is // dangerous because 529 clients can query the content length, but not // the content encoding. responseHeaders.stripContentEncoding(); responseHeaders.stripContentLength(); responseBodyIn = new GZIPInputStream(transferStream); } else { responseBodyIn = transferStream; } }
/** * Returns true if the response must have a (possibly 0-length) body. See RFC 2616 section 4.3. */ public final boolean hasResponseBody() { int responseCode = responseHeaders.getHeaders().getResponseCode(); // HEAD requests never yield a body regardless of the response headers. if (method.equals("HEAD")) { return false; } if ((responseCode < HTTP_CONTINUE || responseCode >= 200) && responseCode != HttpURLConnectionImpl.HTTP_NO_CONTENT && responseCode != HttpURLConnectionImpl.HTTP_NOT_MODIFIED) { return true; } // If the Content-Length or Transfer-Encoding headers disagree with the // response code, the response is malformed. For best compatibility, we // honor the headers. if (responseHeaders.getContentLength() != -1 || responseHeaders.isChunked()) { return true; } return false; }
private void maybeCache() throws IOException { // Are we caching at all? if (!policy.getUseCaches()) return; OkResponseCache responseCache = client.getOkResponseCache(); if (responseCache == null) return; HttpURLConnection connectionToCache = policy.getHttpConnectionToCache(); // Should we cache this response for this request? if (!responseHeaders.isCacheable(requestHeaders)) { responseCache.maybeRemove(connectionToCache.getRequestMethod(), uri); return; } // Offer this request to the cache. cacheRequest = responseCache.put(uri, connectionToCache); }
public ResourceMethod(MethodDeclaration delegate, Resource parent) { super(delegate); Set<String> httpMethods = new TreeSet<String>(); Collection<AnnotationMirror> mirrors = delegate.getAnnotationMirrors(); for (AnnotationMirror mirror : mirrors) { AnnotationTypeDeclaration annotationDeclaration = mirror.getAnnotationType().getDeclaration(); HttpMethod httpMethodInfo = annotationDeclaration.getAnnotation(HttpMethod.class); if (httpMethodInfo != null) { // request method designator found. httpMethods.add(httpMethodInfo.value()); } } if (httpMethods.isEmpty()) { throw new IllegalStateException( "A resource method must specify an HTTP method by using a request method designator annotation."); } this.httpMethods = httpMethods; Set<String> consumes; Consumes consumesInfo = delegate.getAnnotation(Consumes.class); if (consumesInfo != null) { consumes = new TreeSet<String>(Arrays.asList(JAXRSUtils.value(consumesInfo))); } else { consumes = new TreeSet<String>(parent.getConsumesMime()); } this.consumesMime = consumes; Set<String> produces; Produces producesInfo = delegate.getAnnotation(Produces.class); if (producesInfo != null) { produces = new TreeSet<String>(Arrays.asList(JAXRSUtils.value(producesInfo))); } else { produces = new TreeSet<String>(parent.getProducesMime()); } this.producesMime = produces; String subpath = null; Path pathInfo = delegate.getAnnotation(Path.class); if (pathInfo != null) { subpath = pathInfo.value(); } ResourceEntityParameter entityParameter; List<ResourceEntityParameter> declaredEntityParameters = new ArrayList<ResourceEntityParameter>(); List<ResourceParameter> resourceParameters; ResourceRepresentationMetadata outputPayload; ResourceMethodSignature signatureOverride = delegate.getAnnotation(ResourceMethodSignature.class); if (signatureOverride == null) { entityParameter = null; resourceParameters = new ArrayList<ResourceParameter>(); // if we're not overriding the signature, assume we use the real method signature. for (ParameterDeclaration parameterDeclaration : getParameters()) { if (ResourceParameter.isResourceParameter(parameterDeclaration)) { resourceParameters.add(new ResourceParameter(parameterDeclaration)); } else if (ResourceParameter.isFormBeanParameter(parameterDeclaration)) { resourceParameters.addAll(ResourceParameter.getFormBeanParameters(parameterDeclaration)); } else if (parameterDeclaration.getAnnotation(Context.class) == null) { entityParameter = new ResourceEntityParameter(this, parameterDeclaration); declaredEntityParameters.add(entityParameter); } } DecoratedTypeMirror returnTypeMirror; TypeHint hintInfo = getAnnotation(TypeHint.class); if (hintInfo != null) { try { Class hint = hintInfo.value(); AnnotationProcessorEnvironment env = net.sf.jelly.apt.Context.getCurrentEnvironment(); if (TypeHint.NO_CONTENT.class.equals(hint)) { returnTypeMirror = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(env.getTypeUtils().getVoidType()); } else { String hintName = hint.getName(); if (TypeHint.NONE.class.equals(hint)) { hintName = hintInfo.qualifiedName(); } if (!"##NONE".equals(hintName)) { TypeDeclaration type = env.getTypeDeclaration(hintName); returnTypeMirror = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(env.getTypeUtils().getDeclaredType(type)); } else { returnTypeMirror = (DecoratedTypeMirror) getReturnType(); } } } catch (MirroredTypeException e) { returnTypeMirror = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(e.getTypeMirror()); } returnTypeMirror.setDocComment(((DecoratedTypeMirror) getReturnType()).getDocComment()); } else { returnTypeMirror = (DecoratedTypeMirror) getReturnType(); if (getJavaDoc().get("returnWrapped") != null) { // support jax-doclets. see http://jira.codehaus.org/browse/ENUNCIATE-690 String fqn = getJavaDoc().get("returnWrapped").get(0); AnnotationProcessorEnvironment env = net.sf.jelly.apt.Context.getCurrentEnvironment(); TypeDeclaration type = env.getTypeDeclaration(fqn); if (type != null) { returnTypeMirror = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(env.getTypeUtils().getDeclaredType(type)); } } // in the case where the return type is com.sun.jersey.api.JResponse, // we can use the type argument to get the entity type if (returnTypeMirror.isClass() && returnTypeMirror.isInstanceOf("com.sun.jersey.api.JResponse")) { DecoratedClassType jresponse = (DecoratedClassType) returnTypeMirror; if (!jresponse.getActualTypeArguments().isEmpty()) { DecoratedTypeMirror responseType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate( jresponse.getActualTypeArguments().iterator().next()); if (responseType.isDeclared()) { responseType.setDocComment(returnTypeMirror.getDocComment()); returnTypeMirror = responseType; } } } } outputPayload = returnTypeMirror.isVoid() ? null : new ResourceRepresentationMetadata(returnTypeMirror); } else { entityParameter = loadEntityParameter(signatureOverride); declaredEntityParameters.add(entityParameter); resourceParameters = loadResourceParameters(signatureOverride); outputPayload = loadOutputPayload(signatureOverride); } JavaDoc.JavaDocTagList doclets = getJavaDoc() .get( "RequestHeader"); // support jax-doclets. see // http://jira.codehaus.org/browse/ENUNCIATE-690 if (doclets != null) { for (String doclet : doclets) { int firstspace = doclet.indexOf(' '); String header = firstspace > 0 ? doclet.substring(0, firstspace) : doclet; String doc = ((firstspace > 0) && (firstspace + 1 < doclet.length())) ? doclet.substring(firstspace + 1) : ""; resourceParameters.add( new ExplicitResourceParameter(this, doc, header, ResourceParameterType.HEADER)); } } ArrayList<ResponseCode> statusCodes = new ArrayList<ResponseCode>(); ArrayList<ResponseCode> warnings = new ArrayList<ResponseCode>(); StatusCodes codes = getAnnotation(StatusCodes.class); if (codes != null) { for (org.codehaus.enunciate.jaxrs.ResponseCode code : codes.value()) { ResponseCode rc = new ResponseCode(); rc.setCode(code.code()); rc.setCondition(code.condition()); statusCodes.add(rc); } } doclets = getJavaDoc() .get("HTTP"); // support jax-doclets. see http://jira.codehaus.org/browse/ENUNCIATE-690 if (doclets != null) { for (String doclet : doclets) { int firstspace = doclet.indexOf(' '); String code = firstspace > 0 ? doclet.substring(0, firstspace) : doclet; String doc = ((firstspace > 0) && (firstspace + 1 < doclet.length())) ? doclet.substring(firstspace + 1) : ""; try { ResponseCode rc = new ResponseCode(); rc.setCode(Integer.parseInt(code)); rc.setCondition(doc); statusCodes.add(rc); } catch (NumberFormatException e) { // fall through... } } } Warnings warningInfo = getAnnotation(Warnings.class); if (warningInfo != null) { for (org.codehaus.enunciate.jaxrs.ResponseCode code : warningInfo.value()) { ResponseCode rc = new ResponseCode(); rc.setCode(code.code()); rc.setCondition(code.condition()); warnings.add(rc); } } codes = parent.getAnnotation(StatusCodes.class); if (codes != null) { for (org.codehaus.enunciate.jaxrs.ResponseCode code : codes.value()) { ResponseCode rc = new ResponseCode(); rc.setCode(code.code()); rc.setCondition(code.condition()); statusCodes.add(rc); } } warningInfo = parent.getAnnotation(Warnings.class); if (warningInfo != null) { for (org.codehaus.enunciate.jaxrs.ResponseCode code : warningInfo.value()) { ResponseCode rc = new ResponseCode(); rc.setCode(code.code()); rc.setCondition(code.condition()); warnings.add(rc); } } ResponseHeaders responseHeaders = parent.getAnnotation(ResponseHeaders.class); if (responseHeaders != null) { for (ResponseHeader header : responseHeaders.value()) { this.responseHeaders.put(header.name(), header.description()); } } responseHeaders = getAnnotation(ResponseHeaders.class); if (responseHeaders != null) { for (ResponseHeader header : responseHeaders.value()) { this.responseHeaders.put(header.name(), header.description()); } } doclets = getJavaDoc() .get( "ResponseHeader"); // support jax-doclets. see // http://jira.codehaus.org/browse/ENUNCIATE-690 if (doclets != null) { for (String doclet : doclets) { int firstspace = doclet.indexOf(' '); String header = firstspace > 0 ? doclet.substring(0, firstspace) : doclet; String doc = ((firstspace > 0) && (firstspace + 1 < doclet.length())) ? doclet.substring(firstspace + 1) : ""; this.responseHeaders.put(header, doc); } } this.entityParameter = entityParameter; this.resourceParameters = resourceParameters; this.subpath = subpath; this.parent = parent; this.statusCodes = statusCodes; this.warnings = warnings; this.representationMetadata = outputPayload; this.declaredEntityParameters = declaredEntityParameters; }
/** * Flushes the remaining request header and body, parses the HTTP response headers and starts * reading the HTTP response body if it exists. */ public final void readResponse() throws IOException { if (hasResponse()) { responseHeaders.setResponseSource(responseSource); return; } if (responseSource == null) { throw new IllegalStateException("readResponse() without sendRequest()"); } if (!responseSource.requiresConnection()) { return; } if (sentRequestMillis == -1) { if (requestBodyOut instanceof RetryableOutputStream) { int contentLength = ((RetryableOutputStream) requestBodyOut).contentLength(); requestHeaders.setContentLength(contentLength); } transport.writeRequestHeaders(); } if (requestBodyOut != null) { requestBodyOut.close(); if (requestBodyOut instanceof RetryableOutputStream) { transport.writeRequestBody((RetryableOutputStream) requestBodyOut); } } transport.flushRequest(); responseHeaders = transport.readResponseHeaders(); responseHeaders.setLocalTimestamps(sentRequestMillis, System.currentTimeMillis()); responseHeaders.setResponseSource(responseSource); if (responseSource == ResponseSource.CONDITIONAL_CACHE) { if (cachedResponseHeaders.validate(responseHeaders)) { release(false); ResponseHeaders combinedHeaders = cachedResponseHeaders.combine(responseHeaders); this.responseHeaders = combinedHeaders; // Update the cache after applying the combined headers but before initializing the content // stream, otherwise the Content-Encoding header (if present) will be stripped from the // combined headers and not end up in the cache file if transparent gzip compression is // turned on. OkResponseCache responseCache = client.getOkResponseCache(); responseCache.trackConditionalCacheHit(); responseCache.update(cacheResponse, policy.getHttpConnectionToCache()); initContentStream(cachedResponseBody); return; } else { Util.closeQuietly(cachedResponseBody); } } if (hasResponseBody()) { maybeCache(); // reentrant. this calls into user code which may call back into this! } initContentStream(transport.getTransferStream(cacheRequest)); }
public final int getResponseCode() { if (responseHeaders == null) { throw new IllegalStateException(); } return responseHeaders.getHeaders().getResponseCode(); }