NGINXUploadProcessor.java 5.62 KB
package com.brainfood.servlet;

import java.io.IOException;
import java.io.File;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.ofbiz.base.util.HttpClient;

public class NGINXUploadProcessor extends HttpServlet {
	class ProgressRecord {
        boolean complete = false;
		long bytesRead;
		long contentLength;
		int items;
		
		public ProgressRecord(long bytesRead, long contentLength, int items) {
			this.bytesRead = bytesRead;
			this.contentLength = contentLength;
			this.items = items;
		}
	}

	private static final long serialVersionUID = 1L;
	private ServletConfig config;
	private static final ConcurrentHashMap<String, ProgressRecord> progress = new ConcurrentHashMap<String, ProgressRecord>();

	@Override
	public void destroy() {
		// TODO Auto-generated method stub		
	}

	@Override
	public ServletConfig getServletConfig() {
		// TODO Auto-generated method stub
		return this.config;
	}

	@Override
	public String getServletInfo() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		this.config = config;
	}

	@Override
	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
        if (request.getRequestURI().contains("progress")) {
            PrintWriter out = new PrintWriter(response.getWriter());
            String xProgressId = request.getHeader("X-Progress-ID");
            System.err.println("QUERY PROGRESS: [" + xProgressId + "] - " + progress.get(xProgressId));
            if (xProgressId != null && progress.get(xProgressId) != null) {
                ProgressRecord record = progress.get(xProgressId);
                out.println("({ \"state\" : \""+ (record.complete ? "done" : "uploading") +"\", \"received\" : " +
			        record.bytesRead + ", \"size\" : " + record.contentLength + " });");
            } else {
                out.println("({ \"error\" : \"Invalid X-Progress-ID\" });");
            }
            out.close();
        } else {
            String xProgressId = request.getParameter("X-Progress-ID");
            System.err.println("STORE: [" + xProgressId + "]");
	        progress.put(xProgressId, new ProgressRecord(-1, 0, 1));

            if (ServletFileUpload.isMultipartContent(request)) {
                // Create a factory for disk-based file items
                DiskFileItemFactory factory = new DiskFileItemFactory();

                // Configure a repository (to ensure a secure temp location is used)
                ServletContext servletContext = this.getServletConfig()
                        .getServletContext();
                File repository = (File) servletContext
                        .getAttribute("javax.servlet.context.tempdir");
                factory.setRepository(repository);
        
                // Create a new file upload handler
                ServletFileUpload upload = new ServletFileUpload(factory);
        
                // Parse the request
                PrintWriter out = new PrintWriter(response.getWriter());
                try {
                	Map<String, FileItem> itemMap = new HashMap<String, FileItem>();

                	class UploadProgressListener implements ProgressListener {
                		String xProgressId;
                		Map<String, ProgressRecord> progress;
                		
                		public UploadProgressListener(String xProgressId, Map<String, ProgressRecord> progress) {
                			this.xProgressId = xProgressId;
                			this.progress = progress;
                		}
						@Override
						public void update(long sent, long length, int items) {
							System.err.println("PROGRESS: " + sent + " " + length + " " + items);
							progress.put(xProgressId, new ProgressRecord(sent, length, items));
						}                		
                	};
                	
                	ProgressListener listener = (ProgressListener) new UploadProgressListener(xProgressId, this.progress); 
                	upload.setProgressListener(listener);
                    List<FileItem> items = (List<FileItem>)upload.parseRequest(request);

                    for (FileItem item : items) {
                       	itemMap.put(item.getFieldName(), item);	
                    }
                    
                    HashMap parameters = new HashMap();
                    parameters.put("file.path", ((DiskFileItem)itemMap.get("file")).getStoreLocation().getPath());
                    parameters.put("X-Progress-ID", xProgressId);
                    String token = itemMap.get("token").getString();
                    parameters.put("token", token);
                    
                    HttpClient http = new HttpClient("http://localhost:8080/bfp/control/upload", parameters);
                    String pResponse = http.post();
                    System.err.println("FINISHED:" + pResponse);
                    out.print(pResponse);

                    progress.get(xProgressId).complete = true;
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                out.close();
            } else {
                PrintWriter out = new PrintWriter(response.getWriter());
                out.println("Must be a multipart upload");
                out.close();
            }
        }
	}
}