All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.main.java.com.mgnt.utils.WebUtils Maven / Gradle / Ivy

package com.mgnt.utils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/*
* This class is commented out because deep-common project does not have "Java EE" packages in its classpath. It only
* contains Java SE. As a result class javax.servlet.http.HttpServletRequest can not be resolved. This is the only
* problem with this class. If Java EE extention will be added to the classpath this class may be uncommented and
* used.
*/


/**
 * This class provides various web related utilities
 *
 * @author Michael Gantman
 */
public class WebUtils {
    //Default buffer size - 8K
    public static final int DEFAULT_BUFFER_SIZE = 8192;

    /*
     * This variable holds the maximum number of subsequent failures allowed. If we attempt to read from the source
     * and the number of read bytes returns as 0 yet no error was reported we will try to read again. but we don't
     * want to get stuck in the infinite loop if this situation keeps reoccuring. So we want to set upper limit
     * for the number of subsequent failures, after which we will give up and report an error.
     */
    public static final int MAX_SUBSEQUENT_FAILURES_LIMIT = 10;

    /**
     * This method reads the content of HTTPServletRequest as binary (raw) info without any modifications. I.e.
     * just as it was received.
     *
     * @param request HTTPServletRequest to be read
     * @return byte array that contains unmodified binary info read from request or null if no info was read
     * @throws IOException if any problems occurred.
     */
    public static byte[] readRequestContentAsByteArray(HttpServletRequest request) throws IOException {
        List resultCollector = null;
        boolean unknownLength = true;
        try (InputStream reader = request.getInputStream()) {
            int length = request.getContentLength();
            switch (length) {
                case -1: {
                    length = DEFAULT_BUFFER_SIZE;
                    break;
                }
                case 0: {
                    /*
					 * Request has no content. It's not expected to occur, but just in case
					 */
                    return null;
                }
                default: {
                    unknownLength = false;
                }
            }
            if (unknownLength) {
                resultCollector = new ArrayList(length);
            }
            int totalNumberOfReadBytes = 0;
            byte[] byteBuffer = new byte[length];
            int numberOfReadBytes = totalNumberOfReadBytes = reader.read(byteBuffer);
            if (numberOfReadBytes < 0) {
                return null;
            }
            if (!unknownLength && totalNumberOfReadBytes == length) {
                return byteBuffer;
            }
            if (unknownLength) {
                for (int i = 0; i < numberOfReadBytes; i++) {
                    resultCollector.add(byteBuffer[i]);
                }
            }
			/*
			 * If the original content length was unknown or if we did not read yet all the info then read until the end
			 */
            int numberOfsubsequentFailures = 0;
            do {
                if (!unknownLength) {
                    numberOfReadBytes = reader.read(byteBuffer, totalNumberOfReadBytes, length - totalNumberOfReadBytes);
                } else {
                    numberOfReadBytes = reader.read(byteBuffer);
                }
                if (numberOfReadBytes > 0) {
					/*
					 * This is the main or expected branch. It occurs if the reading from the source was successful
					 */
                    if (numberOfsubsequentFailures > 0) {
						/*
						 * We have read some bytes successfully. So if before this iteration there was some number
						 * of subsequent failures we just broke that sequence with current success. So we can reset
						 * the number of subsequent failures to 0
						 */
                        numberOfsubsequentFailures = 0;
                    }
                    if (unknownLength) {
                        for (int i = 0; i < numberOfReadBytes; i++) {
                            resultCollector.add(byteBuffer[i]);
                        }
                    }
                    totalNumberOfReadBytes += numberOfReadBytes;
                } else {
					/*
					 * This branch occurs If we attempt to read from the source and the number of read bytes returns as 0
					 * yet no error was reported we will try to read again. But we don't want to get stuck in the infinite
					 * loop if this situation keeps reoccuring. So we want to set upper limit for the number of subsequent
					 * failures uninterrupted by any successful read, after which we will give up and report an error.
					 */
                    if (++numberOfsubsequentFailures >= MAX_SUBSEQUENT_FAILURES_LIMIT) {
						/*
						 * We reached the maximum number of subsequent failures. So we give up and report a reading error
						 */
                        throw new IOException("The reading from the source could not be completed due to unknown error");
                    } else {
						/*
						 * If we just read 0 bytes don't immediately read again. Make a small pause in order not to
						 * exhaust processor resources and to let the source some time to give us something to read
						 */
                        TimeUtils.sleepFor(1L, TimeUnit.MILLISECONDS);
                    }
                }
            } while (numberOfReadBytes >= 0);
            if (!unknownLength && totalNumberOfReadBytes < length) {
                throw new IOException("The length of info read is less the declared content length");
            }
            if (unknownLength) {
                byteBuffer = new byte[resultCollector.size()];
                for (int i = 0; i < resultCollector.size(); i++) {
                    byteBuffer[i] = resultCollector.get(i);
                }
            }
            return byteBuffer;
        } catch (IOException ioe) {
            throw ioe;
        } catch (Exception e) {
            throw new IOException("Unexpected error occurred", e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy