/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package io.milton.http; import java.io.OutputStream; import java.util.Date; import java.util.List; import java.util.Map; public interface Response { public final static String HTTP = "text/html"; public final static String IMAGE_JPG = "image/jpg"; public final static String MULTIPART = "multipart/form-data"; public final static String XML = "text/xml; charset=UTF-8"; public enum ContentType { HTTP, MULTIPART, IMAGE_JPG, XML; } public enum ContentEncoding { GZIP( "gzip" ); public String code; ContentEncoding( String code ) { this.code = code; } } enum Header { CACHE_CONTROL( "Cache-Control" ), WWW_AUTHENTICATE( "WWW-Authenticate" ), CONTENT_LENGTH( "Content-Length" ), CONTENT_TYPE( "Content-Type" ), CONTENT_ENCODING( "Content-Encoding" ), LOCATION( "Location" ), ALLOW( "Allow" ), DAV( "DAV" ), DATE( "Date" ), // was all-caps , eg DATE, which is wrong LAST_MODIFIED( "Last-Modified" ), LOCK_TOKEN( "Lock-Token" ), EXPIRES( "Expires" ), ETAG( "ETag" ), VARY( "Vary" ), ACCESS_CONTROL_ALLOW_ORIGIN("Access-Control-Allow-Origin"), ACCEPT_RANGES("Accept-Ranges"), CONTENT_RANGE( "Content-Range" ); public String code; Header( String code ) { this.code = code; } } enum CacheControlResponse { PUBLIC( "public" ), PRIVATE( "private" ), // [ "=" <"> 1#field-name <"> ] ; Section 14.9.1 NO_CACHE( "no-cache" ), // [ "=" <"> 1#field-name <"> ]; Section 14.9.1 NO_STORE( "no-store" ), // ; Section 14.9.2 NO_TRANSFORM( "no-transform" ), // ; Section 14.9.5 MUST_REVALIDATE( "must-revalidate" ), // ; Section 14.9.4 PROXY_REVALIDATE( "proxy-revalidate" ), // ; Section 14.9.4 MAX_AGE( "max-age" ), // "=" delta-seconds ; Section 14.9.3 S_MAX_AGE( "s-maxage" ), // "=" delta-seconds ; Section 14.9.3 CACHE_EXT( "cache-extension" ); // ; Section 14.9.6 public String code; CacheControlResponse( String code ) { this.code = code; } } enum Status { SC_OK( ResponseStatus.SC_OK, "OK" ), SC_CREATED( ResponseStatus.SC_CREATED ), SC_ACCEPTED( ResponseStatus.SC_ACCEPTED ), SC_NO_CONTENT( ResponseStatus.SC_NO_CONTENT ), SC_MULTI_STATUS( 207, "Multi-status" ), SC_MOVED_PERMANENTLY( ResponseStatus.SC_MOVED_PERMANENTLY ), SC_MOVED_TEMPORARILY( ResponseStatus.SC_MOVED_TEMPORARILY ), SC_TEMPORARY_REDIRECT( ResponseStatus.SC_TEMPORARY_REDIRECT ), SC_NOT_MODIFIED( ResponseStatus.SC_NOT_MODIFIED ), SC_BAD_REQUEST( ResponseStatus.SC_BAD_REQUEST ), SC_UNAUTHORIZED( ResponseStatus.SC_UNAUTHORIZED ), SC_FORBIDDEN( ResponseStatus.SC_FORBIDDEN ), SC_NOT_FOUND( ResponseStatus.SC_NOT_FOUND, "Not Found" ), SC_INTERNAL_SERVER_ERROR( ResponseStatus.SC_INTERNAL_SERVER_ERROR ), SC_NOT_IMPLEMENTED( ResponseStatus.SC_NOT_IMPLEMENTED ), SC_BAD_GATEWAY( ResponseStatus.SC_BAD_GATEWAY ), SC_SERVICE_UNAVAILABLE( ResponseStatus.SC_SERVICE_UNAVAILABLE ), SC_PARTIAL_CONTENT( ResponseStatus.SC_PARTIAL_CONTENT ), SC_CONTINUE( 100 ), SC_METHOD_NOT_ALLOWED( 405 ), SC_CONFLICT( 409 ), SC_PRECONDITION_FAILED( 412 ), SC_REQUEST_TOO_LONG( 413 ), SC_UNSUPPORTED_MEDIA_TYPE( 415 ), SC_EXPECTATION_FAILED( ResponseStatus.SC_EXPECTATION_FAILED ), // 417 SC_UNPROCESSABLE_ENTITY( 418 ), SC_INSUFFICIENT_STORAGE( 507 ), SC_METHOD_FAILURE( 420 ), SC_LOCKED( 423 ); public int code; public String text; Status( int code, String text ) { this.code = code; this.text = text; } Status( int code) { this.code = code; this.text = null; } @Override public String toString() { if( text != null ) { return "HTTP/1.1 " + code + " " + text; } else { return "HTTP/1.1 " + code; } } public static Status fromCode( int i ) { for( Status s : values() ) { if( s.code == i ) return s; } return null; } } public interface Entity { void write(Response response, OutputStream outputStream) throws Exception; } public Response.Status getStatus(); public Map<String, String> getHeaders(); /** * * @return - the content length which might have been set by a handler, or null * if none has been set */ public Long getContentLength(); public void setContentEncodingHeader( ContentEncoding encoding ); public void setExpiresHeader( Date expiresAt ); public void setLockTokenHeader( String tokenId ); /** * Must set multiple Authenticate headers, one for each challenge * * This will usually be one each for basic, digest, ntlm, etc * * Note that order might be significant to some clients, so should be * preserved. ie list item zero should be first. * * @param challenges - a list of http authentication challenges */ void setAuthenticateHeader( List<String> challenges ); void setStatus( Status status ); void setEtag( String uniqueId ); void setContentRangeHeader( long start, long finish, Long totalLength ); void setContentLengthHeader( Long totalLength ); void setContentTypeHeader( String string ); String getContentTypeHeader(); Entity getEntity(); void setEntity(Entity entity); /** * Set the cache control header to allow the resource to be cached * for the given number of seconds * * @param deltaSeconds - must not be null */ void setCacheControlMaxAgeHeader( Long deltaSeconds ); void setCacheControlPrivateMaxAgeHeader( Long deltaSeconds ); /** * Set the cache control header to indicate that the resource should not * be cached */ void setCacheControlNoCacheHeader(); void setLastModifiedHeader( Date date ); void setDavHeader( String string ); void setNonStandardHeader( String code, String value ); String getNonStandardHeader( String code ); void setAllowHeader( List<String> methodsAllowed ); OutputStream getOutputStream(); void setLocationHeader( String redirectUrl ); /** * Sets the Vary response header, necessary for response compression * @param string */ void setVaryHeader( String string ); void setDateHeader( Date date ); /** * Used for CORS responses * * @return */ String getAccessControlAllowOrigin(); void setAccessControlAllowOrigin(String s); String getAcceptRanges(); void setAcceptRanges(String s); /** * Called to indicate that the request is completed. Some response implementations * might choose to close the http connection, while others which implement pipelining * might not */ void close(); /** * Called by milton when an error occurs. The underlying HTTP provider should * choose to close the HTTP connection, because the amount of data already sent * might not be consistent with the content length header which may have already * been sent * @param status * @param message */ void sendError(Status status, String message); /** * Will set the status to moved_temporaruly and set the location header * to the given url * * @param url */ void sendRedirect( String url ); /** * The <code>setCookie</code> method is used to set a cookie value * with the cookie name. This will add a cookie to the response * stored under the name of the cookie, when this is committed it * will be added as a Set-Cookie header to the resulting response. * * @param cookie this is the cookie to be added to the response * * @return returns the cookie that has been set in the response */ Cookie setCookie( Cookie cookie ); /** * The <code>setCookie</code> method is used to set a cookie value * with the cookie name. This will add a cookie to the response * stored under the name of the cookie, when this is committed it * will be added as a Set-Cookie header to the resulting response. * This is a convenience method that avoids cookie creation. * * @param name this is the cookie to be added to the response * @param value this is the cookie value that is to be used * * @return returns the cookie that has been set in the response */ Cookie setCookie( String name, String value ); }