src/org/ohmage/request/image/ImageReadRequest.java
@Override
	public void respond(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
		LOGGER.info("Writing the image read response.");
		
		if(ANDROID_CLIENT_NAME.equals(getClient())) {

			// TODO move to web server configuration for all image file types?
			// For now, this allows images to be stored by clients for one year
			// and specifies private to disable intermediaries from caching the
			// image. (HTTP 1.1)
			httpResponse.setHeader("Cache-Control", "max-age=1051200, private");  
						
		} else {

			// Sets the HTTP headers to disable caching
			expireResponse(httpResponse);
		}
				
		// Open the connection to the image if it is not null.
		InputStream imageStream = null;
		try {
			if(image != null) {
				imageStream = image.getInputStream(size);
			}
		}
		catch(DomainException e) {
			LOGGER.error("Could not connect to the image.", e);
			this.setFailed(ErrorCode.SYSTEM_GENERAL_ERROR, "Image not found.");
			httpResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
			super.respond(httpRequest, httpResponse, (JSONObject) null);
			return;
		}
		
		// If the request hasn't failed, attempt to write the file to the
		// output stream. 
		try {
			if(isFailed()) {
				httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
				super.respond(httpRequest, httpResponse, (JSONObject) null);
			}
			else {
				// Set the type of the value.
				// FIXME: This isn't necessarily the case. We might want to do
				// some sort of image inspection to figure out what this should
				// be.
				httpResponse.setContentType(image.getContentType(size));
				httpResponse.setHeader(
						"Content-Length", 
						new Long(image.getSizeBytes(size)).toString());
				
				// If available, set the token.
				if(getUser() != null) {
					final String token = getUser().getToken(); 
					if(token != null) {
						CookieUtils.setCookieValue(
								httpResponse, 
								InputKeys.AUTH_TOKEN, 
								token);
					}
				}

				// Creates the writer that will write the response, success or 
				// fail.
				OutputStream os;
				try {
					os = httpResponse.getOutputStream();
				}
				catch(IOException e) {
					LOGGER.error(
							"Unable to create writer object. Aborting.", 
							e);
					return;
				}
				
				// Set the output stream to the response.
				DataOutputStream dos = new DataOutputStream(os);
				byte[] bytes = new byte[CHUNK_SIZE];
				int currRead;
				try {
					while((currRead = imageStream.read(bytes)) != -1) {
						dos.write(bytes, 0, currRead);
					}
				}
				finally {
					// Close the data output stream to which we were writing.
					try {
						dos.close();
					}
					// SN: commenting as this exception is a subclass of IOException
					// and the exception is tomcat-specific.
					//catch(ClientAbortException e) {
					//	LOGGER.info("The client hung up unexpectedly.", e);
					//}
					catch(IOException e) {
						LOGGER.warn("Error closing the data output stream.", e);
					}
				}
			}
		}
		// If there was an error getting the image's information, abort
		// the whole operation and return an error.
		catch(DomainException e) {
			LOGGER.error(
				"There was a problem reading or writing the image.", 
				e);
			setFailed();
			httpResponse.setStatus(
				HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
		}
		// SN: commenting as this exception is a subclass of IOException
		// and the exception is tomcat-specific.
		//catch(ClientAbortException e) {
		//	LOGGER.info("The client hung up unexpectedly.", e);
		//}
		// If the error occurred while reading from the input stream or
		// writing to the output stream, abort the whole operation and
		// return an error.
		catch(IOException e) {
			LOGGER.error(
				"The contents of the file could not be read or written to the response.", 
				e);
			setFailed();
			httpResponse.setStatus(
				HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
		}
		// No matter what, try to close the input stream if it exists.
		finally {
			try {
				if(imageStream != null) {
					imageStream.close();
				}
			}
			// SN: commenting as this exception is a subclass of IOException
			// and the exception is tomcat-specific.
			//catch(ClientAbortException e) {
			//	LOGGER.info("The client hung up unexpectedly.", e);
			//}
			catch(IOException e) {
				LOGGER.warn("Could not close the image stream.", e);
				// We don't care about failing the request, because, either, it
				// has already been failed or we wrote everything already.
			}
		}
	}
/**
	 * Responds to the request with an image if it was successful or JSON if it
	 * was not.
	 */
Responds to the request with an image if it was successful or JSON if it
was not.
Responds to the request with an image if it was successful or JSON if it was not .
@Override
	public void respond(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
		LOGGER.info("Writing the image read response.");
		if(ANDROID_CLIENT_NAME.equals(getClient())) {
			httpResponse.setHeader("Cache-Control", "max-age=1051200, private");  
		} else {
			expireResponse(httpResponse);
		}
		InputStream imageStream = null;
		try {
			if(image != null) {
				imageStream = image.getInputStream(size);
			}
		}
		catch(DomainException e) {
			LOGGER.error("Could not connect to the image.", e);
			this.setFailed(ErrorCode.SYSTEM_GENERAL_ERROR, "Image not found.");
			httpResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
			super.respond(httpRequest, httpResponse, (JSONObject) null);
			return;
		}
		try {
			if(isFailed()) {
				httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
				super.respond(httpRequest, httpResponse, (JSONObject) null);
			}
			else {
				httpResponse.setContentType(image.getContentType(size));
				httpResponse.setHeader(
						"Content-Length", 
						new Long(image.getSizeBytes(size)).toString());
				if(getUser() != null) {
					final String token = getUser().getToken(); 
					if(token != null) {
						CookieUtils.setCookieValue(
								httpResponse, 
								InputKeys.AUTH_TOKEN, 
								token);
					}
				}
				OutputStream os;
				try {
					os = httpResponse.getOutputStream();
				}
				catch(IOException e) {
					LOGGER.error(
							"Unable to create writer object. Aborting.", 
							e);
					return;
				}
				DataOutputStream dos = new DataOutputStream(os);
				byte[] bytes = new byte[CHUNK_SIZE];
				int currRead;
				try {
					while((currRead = imageStream.read(bytes)) != -1) {
						dos.write(bytes, 0, currRead);
					}
				}
				finally {
					try {
						dos.close();
					}
					catch(IOException e) {
						LOGGER.warn("Error closing the data output stream.", e);
					}
				}
			}
		}
		catch(DomainException e) {
			LOGGER.error(
				"There was a problem reading or writing the image.", 
				e);
			setFailed();
			httpResponse.setStatus(
				HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
		}
		catch(IOException e) {
			LOGGER.error(
				"The contents of the file could not be read or written to the response.", 
				e);
			setFailed();
			httpResponse.setStatus(
				HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
		}
		finally {
			try {
				if(imageStream != null) {
					imageStream.close();
				}
			}
			catch(IOException e) {
				LOGGER.warn("Could not close the image stream.", e);
			}
		}
	}
@ Override public void respond ( HttpServletRequest httpRequest , HttpServletResponse httpResponse ) { LOGGER . info ( "Writing the image read response." ) ; if ( ANDROID_CLIENT_NAME . equals ( getClient ( ) ) ) { httpResponse . setHeader ( "Cache-Control" , "max-age=1051200, private" ) ; } else { expireResponse ( httpResponse ) ; } InputStream imageStream = null ; try { if ( image != null ) { imageStream = image . getInputStream ( size ) ; } } catch ( DomainException e ) { LOGGER . error ( "Could not connect to the image." , e ) ; this . setFailed ( ErrorCode . SYSTEM_GENERAL_ERROR , "Image not found." ) ; httpResponse . setStatus ( HttpServletResponse . SC_NOT_FOUND ) ; super . respond ( httpRequest , httpResponse , ( JSONObject ) null ) ; return ; } try { if ( isFailed ( ) ) { httpResponse . setStatus ( HttpServletResponse . SC_BAD_REQUEST ) ; super . respond ( httpRequest , httpResponse , ( JSONObject ) null ) ; } else { httpResponse . setContentType ( image . getContentType ( size ) ) ; httpResponse . setHeader ( "Content-Length" , new Long ( image . getSizeBytes ( size ) ) . toString ( ) ) ; if ( getUser ( ) != null ) { final String token = getUser ( ) . getToken ( ) ; if ( token != null ) { CookieUtils . setCookieValue ( httpResponse , InputKeys . AUTH_TOKEN , token ) ; } } OutputStream os ; try { os = httpResponse . getOutputStream ( ) ; } catch ( IOException e ) { LOGGER . error ( "Unable to create writer object. Aborting." , e ) ; return ; } DataOutputStream dos = new DataOutputStream ( os ) ; byte [ ] bytes = new byte [ CHUNK_SIZE ] ; int currRead ; try { while ( ( currRead = imageStream . read ( bytes ) ) != - 1 ) { dos . write ( bytes , 0 , currRead ) ; } } finally { try { dos . close ( ) ; } catch ( IOException e ) { LOGGER . warn ( "Error closing the data output stream." , e ) ; } } } } catch ( DomainException e ) { LOGGER . error ( "There was a problem reading or writing the image." , e ) ; setFailed ( ) ; httpResponse . setStatus ( HttpServletResponse . SC_INTERNAL_SERVER_ERROR ) ; } catch ( IOException e ) { LOGGER . error ( "The contents of the file could not be read or written to the response." , e ) ; setFailed ( ) ; httpResponse . setStatus ( HttpServletResponse . SC_INTERNAL_SERVER_ERROR ) ; } finally { try { if ( imageStream != null ) { imageStream . close ( ) ; } } catch ( IOException e ) { LOGGER . warn ( "Could not close the image stream." , e ) ; } } }
Responds to the request with an image if it was successful or JSON if it
 was not.
Responds to the request with an image if it was successful or JSON if it was not .
// TODO move to web server configuration for all image file types? // For now, this allows images to be stored by clients for one year // and specifies private to disable intermediaries from caching the // image. (HTTP 1.1) // Sets the HTTP headers to disable caching // Open the connection to the image if it is not null. // If the request hasn't failed, attempt to write the file to the // output stream.  // Set the type of the value. // FIXME: This isn't necessarily the case. We might want to do // some sort of image inspection to figure out what this should // be. // If available, set the token. // Creates the writer that will write the response, success or  // fail. // Set the output stream to the response. // Close the data output stream to which we were writing. // SN: commenting as this exception is a subclass of IOException // and the exception is tomcat-specific. //catch(ClientAbortException e) { //	LOGGER.info("The client hung up unexpectedly.", e); //} // If there was an error getting the image's information, abort // the whole operation and return an error. // SN: commenting as this exception is a subclass of IOException // and the exception is tomcat-specific. //catch(ClientAbortException e) { //	LOGGER.info("The client hung up unexpectedly.", e); //} // If the error occurred while reading from the input stream or // writing to the output stream, abort the whole operation and // return an error. // No matter what, try to close the input stream if it exists. // SN: commenting as this exception is a subclass of IOException // and the exception is tomcat-specific. //catch(ClientAbortException e) { //	LOGGER.info("The client hung up unexpectedly.", e); //} // We don't care about failing the request, because, either, it // has already been failed or we wrote everything already.