Basically I have a client-side File upload which could be used for uploading files to server, and in my server-side I have limited file size using MultipartConfig to 5MB and if the file has exceeded the limit I need to abort the uploading process.
Server-Side:
#MultipartConfig(location="/tmp", fileSizeThreshold=1024*1024,
maxFileSize=1024*1024*5, maxRequestSize=1024*1024*5*5)
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter() ;
try{
MultipartRequest multipartRequest = new MultipartRequest(request, "D:\\");
} catch(IOException e){
System.out.println(e.getMessage());
return;
}
out.print("Successfully Uploaded");
}
FYI: I have my #MultipartConfig out of my class
As you can see I have a try and catch which if the file limit has exceeded throws an exception saying about the file exceed exception, Here I need to abort the uploading process, and send a simple error to client that limit has exceeded.
You can use httpget.abort() to abort/cancel the request.
public class ClientAbortMethod {
public final static void main(String[] args) throws Exception {
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpGet httpget = new HttpGet("http://httpbin.org/get");
System.out.println("Executing request " + httpget.getURI());
CloseableHttpResponse response = httpclient.execute(httpget);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
// Do not feel like reading the response body
// Call abort on the request object
httpget.abort();
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
}
Refer this
Related
I am trying to create a proxy server in java using Spark Java.
I listed for any incoming request and send any incoming request to the target server via Apache Http Client.
I then transform the incoming request by coping the headers, status and text.
Now this is working pretty fine, except the binary files. The binary files such as fonts are corrupted. My code is :
private static void mapStatus(HttpResponse response, spark.Response res) {
res.status(response.getStatusLine().getStatusCode());
}
private static void mapHeaders(HttpResponse response, spark.Response res) {
for (Header header : response.getAllHeaders()) {
res.header(header.getName(), header.getValue());
}
}
private static String result(HttpResponse response) throws ParseException, IOException {
HttpEntity entity = response.getEntity();
return entity == null ? "" : EntityUtils.toString(entity);
}
I suspect the issue is with the result() method as it treats all the responses as text. How ever I tried by coping the streams as is :
private static void extractResponse(HttpResponse httpResponse, HttpServletResponse response) {
InputStream inputStream = null;
try {
HttpEntity entity = httpResponse.getEntity();
if(entity == null)
return;
inputStream = entity.getContent();
copyStream(inputStream, response.getOutputStream());
} catch (IllegalStateException | IOException e) {
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
}
}
}
private static void copyStream(InputStream input, OutputStream output) throws IOException {
IOUtils.copy(input, output);
}
And the binary files are still bad.
WHat could be the issue here ?
Complete Code Link
I wrote a little programm, that reads an XML-File via http-get.
Loacally it's running fine.
But on the server it keeps breaking without any exception, except a nullpointer because of the empty result
I'm using the apache http lib.
Here is the class, i added the numbers, to track the exact point, where it stops working.
public void get(String url, String user, String pass, File outfile) throws IOException
{
log.info("1");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, "basic"),
new UsernamePasswordCredentials(user, pass));
log.info("2");
CloseableHttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
HttpResponse response = null;
log.info("6");
InputStream content = null;
FileOutputStream outputStream = null;
try
{
HttpGet httpGet = new HttpGet(url);
log.info("3");
httpGet.addHeader("Content-Type", "text/xml");
log.info("4");
httpGet.addHeader("Accept", "text/xml");
log.info("5");
log.info("6");
log.info("7");
outputStream = new FileOutputStream(outfile);
log.info("8");
response = httpClient.execute(httpGet);
log.info("9");
log.info("response: {}", response);
log.info("10");
content = response.getEntity().getContent();
log.info("11");
log.info("content: {}", content);
log.info("12");
IOUtils.copy(content, outputStream);
log.info("13");
}
catch (Exception e)
{
log.error("", e);
}
finally
{
try
{
log.info("14");
log.info(String.valueOf(content));
content.close();
outputStream.close();
}
catch (IOException e)
{
log.error("Error while closing Streams", e);
}
}
}
Here are the log snipets; I tried to mask every sensible data and i hope i didn't miss anything
Local log snipet
Remote log snipet
As you can see, the numbers stop after 8 and start in the finally block again with 14. the rest is missing and I have no idea, why.
The used URL is reachable via browser or comandline.
The problem is a bit tricky: you are running into some sort of Error here. Probably NoClassDefFoundError or something alike.
But as you are catching for Exception this piece of code simply doesn't "see" the real problem.
So to debug the problem: either check the server log files or change your code to catch Throwable instead of Exception.
I have a Servlet which makes a request to my Rest API, and I want it to return the API Response content to the final user through the HttpServletResponse.
The content is actually a .xls file to download which I put in the Response with the StreamingOutput Object.
How can I do that ? I can't cast the Response into a HttpServletResponse
Rest API method :
#GET
#Produces( MediaType.APPLICATION_JSON )
#Path("bla")
public Response getTopicByName() {
final Workbook wb = new HSSFWorkbook();
StreamingOutput stream = new StreamingOutput() {
#Override
public void write(OutputStream output) throws IOException, WebApplicationException {
wb.write(output);
}
};
responseBuilder = responseBuilder.entity(stream);
responseBuilder = responseBuilder.status(Response.Status.OK);
responseBuilder = responseBuilder.header("Content-Disposition", "attachment; filename=" + device + ".xls");
return responseBuilder.build();
}
Servlet POST method :
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(url);
Response res = target. request().get();
if (res.getStatus() == 200) {
// how to put res stream into response stream ?
ServletOutputStream stream = response.getOutputStream();
}
client.close();
}
EDIT :
I tried TedTrippin method and after finding out the way to recover an InputStream from the Response, it worked well.
But I keep getting corrupted xls files. And it is quite annoying. I don't get those corrupted files when I make the request directly from the browser.
Got any clues where it comes from ?
POST method :
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(url + param + format);
Response res = target.request().get();
if (res.getStatus() == 200) {
response.setHeader("Content-Disposition", "attachment; filename=test.xls");
InputStream in = res.readEntity(InputStream.class);
ServletOutputStream out = response.getOutputStream();
byte[] buffer = new byte[1024];
while (in.read(buffer) >= 0) {
out.write(buffer);
}
out.flush();
}
client.close();
}
Simplest way is to read the response stream and write it straight to the response output stream. Either use a library function from IOUtils or Guava or pure java...
try (InputStream in = ...;
OutputStream out = ...) {
byte[] buffer = new byte[1024];
while (in.read(buffer) >= 0)
out.write(buffer);
} catch (IOException ex) {
...
}
A nicer (depending on your view) way would be to read/save the response as a temporary file then you could return that or write it to the output stream.
Third approach would be to create a pipe, but I don't think that would be applicable here.
I deploy the same war with jetty, a local tomcat and a remote tomcat.
For the same request :
With jetty and local tomcat everything is fine and I get a full response.
With remote tomcat response status is 200 but with empty body.
I don't know where to look at and why this difference.
If you can provide me another way to query an URL (which can be public or local to the network where the app is deployed), I'll be glad to hear it.
The code
private void get(String proxiedURIString, HttpServletResponse resp) throws IOException, ServletException {
HttpURLConnection connection = getHttpURLConnection(proxiedURIString, resp);
fillHeaders(resp, connection);
try {
IOUtils.copy(connection.getInputStream(), resp.getOutputStream());
} catch (IOException e) {
String message = String.format("Unable to parse response : %s", proxiedURIString);
LOGGER.error(message);
resp.sendError(500, message);
} finally {
resp.getOutputStream().flush();
connection.disconnect();
}
LOGGER.info("Successfully proxied URI : {}", proxiedURIString);
}
private static void fillHeaders(HttpServletResponse resp, HttpURLConnection connection) {
Map<String, List<String>> headers = connection.getHeaderFields();
for (String header : headers.keySet()) {
if(header == null || headers.get(header) == null) {
continue;
}
for (String headerValue : headers.get(header)) {
if(headerValue == null) {
continue;
}
resp.addHeader(header, headerValue);
}
}
}
private static HttpURLConnection getHttpURLConnection(String proxiedURIString, HttpServletResponse resp) throws ServletException, IOException {
HttpURLConnection connection = null;
try {
URL url = new URL(proxiedURIString);
connection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
String message = String.format("Unable to contact : %s", proxiedURIString);
LOGGER.error(message);
resp.sendError(404, message);
}
return connection;
}
Edit: Edit the code to only work with input/output streams. Also to provide further information, I contact the remote tomcat through an apache http server and the response body is big.
Edit2: Futher information. I mapped the proxied URI with one sending much less data and this time I get a full answer for every configuration.
I use Apache HttpClient to first Request a page for the Cookies, and then post to a page with those Cookies. To be able to get the second page, the Cookie must be sent with the post. I've read somewhere that HttpClient automatically saves and Sends the needed Cookies, but somehow I keep stuck at the first page, probably due to Cookies not being get properly, or not being sent properly.
public class Main {
static BufferedWriter writer;
public static void main(String args[]) throws ClientProtocolException, IOException {
getRequest();
}
public static void getRequest() throws ClientProtocolException, IOException {
HttpClient client = new DefaultHttpClient();
//the request to get the Cookies
HttpGet request = new HttpGet("http://www.SiteNameCutOut.cz");
List <NameValuePair> parameters = new ArrayList <NameValuePair>();
parameters.add(new BasicNameValuePair("view_state", "eaftOTAPef3NDs79"));
parameters.add(new BasicNameValuePair("age", "23"));
parameters.add(new BasicNameValuePair("button", "go"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters);
HttpPost post = new HttpPost("http://www.SameSiteAsAbove.cz");
post.setEntity(entity);
//post.addHeader(request.getFirstHeader("Set-Cookie")); maybe?
post.addHeader("Host","theSiteHost");
post.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.0; rv:2.0.1) Gecko/20100101 Firefox/4.0.1");
post.addHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
post.addHeader("Accept-Language","en-us,en;q=0.5");
post.addHeader("Accept-Encoding","gzip, deflate");
post.addHeader("Accept-Charset","ISO-8859-1,utf-8;q=0.7,*;q=0.7");
post.addHeader("Keep-Alive","115");
post.addHeader("Connection","keep-alive");
client.execute(request);
try {
request.abort();
HttpResponse response = client.execute(post);
writer = new BufferedWriter(new FileWriter("test001.html"));
writer.write(HttpHelper.request(response)); //gets html of the response
} catch (IOException ex) {
System.out.println("**Error**");
} finally {
if(writer != null){
writer.close();
}
else{
System.out.println("Writer is null");
}
}
}
}
So i hope anyone can help me, Thanks !
You should indicate how to manage the cookies like this:
request.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);