Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 353839 - ajp component error when upload file
Summary: ajp component error when upload file
Status: RESOLVED FIXED
Alias: None
Product: Jetty
Classification: RT
Component: other (show other bugs)
Version: 7.2.2   Edit
Hardware: PC All
: P3 minor (vote)
Target Milestone: 7.5.x   Edit
Assignee: Greg Wilkins CLA
QA Contact: Thomas Becker CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-08-04 00:17 EDT by weijx CLA
Modified: 2011-09-22 06:09 EDT (History)
2 users (show)

See Also:


Attachments
proposed patch (23.00 KB, application/x-tar)
2011-09-22 05:51 EDT, Thomas Becker CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description weijx CLA 2011-08-04 00:17:51 EDT
Build Identifier: 

hi, friends.

I use apache and jetty together with ajp13 protocal. when I upload a file to server, the jetty at behind can not receive the file data correctly.

the test code :

public class FileUploadServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
		out.println("<HTML>");
		out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
		out.println("  <BODY>");
		
		// receive file data
		InputStream input = request.getInputStream();
		int c = -1;
		byte[] b = new byte[1024*32];
		while((c=input.read(b))!=-1){
			System.out.println("read content : "+c);
		}
		
		out.print("    This is ");
		out.print(this.getClass());
		out.println(", using the POST method");
		out.println("  </BODY>");
		out.println("</HTML>");
		out.flush();
		out.close();
	}
}

generally speaking, reading file data is before writing response data. but response must have response buffer. the ahead writing data should in buffer, not write apache directly.

modify org.eclipse.jetty.ajp.Ajp13Generator class the getBodyChunk method, when the container asks for more data, it must send AJP13_MORE_CONTENT immediately: 

    public void getBodyChunk() throws IOException
    {
        // write Get Body Chunk directly
        ByteArrayBuffer bf = new ByteArrayBuffer(AJP13_MORE_CONTENT);
        _endp.flush(bf);
    	
        // the old code
        //_needMore = true;
        //_expectMore = true;
        //flushBuffer();
    }


I find the ajp component 's code is hard to understand, the Ajp13Parser.parseNext method is more than 350 line. This method is the best reconstruction.

Reproducible: Always
Comment 1 Greg Wilkins CLA 2011-08-29 01:52:00 EDT
weijx,

note that AJP is not the most loved code in the jetty code base.  We greatly prefer using mod_proxy_http and mod_proxy_balancer rather than AJP.   The code is not our best either.

But thanks for the test case and proposed fix, we will look at it shortly.
Comment 2 Greg Wilkins CLA 2011-09-20 02:55:20 EDT
Thomas,
can you have a look at this one.  you will need to set up apache and mod_jk. 
Low priority.
Comment 3 Thomas Becker CLA 2011-09-20 02:56:35 EDT
Sure, will take care of this.
Comment 4 Thomas Becker CLA 2011-09-22 05:51:08 EDT
Created attachment 203828 [details]
proposed patch

I've setup an apache + jetty and can confirm the behaviour. Tested the proposed patch (thx for providing it) and it works fine. Did some very basic ajp13 tests with test.war and it works fine.

Patch attached.
Comment 5 Simone Bordet CLA 2011-09-22 06:09:29 EDT
Patch applied.