From 95530f2f0fd0354a761879cea2429bfdc075da07 Mon Sep 17 00:00:00 2001 From: michi Date: Tue, 17 Jul 2007 16:12:09 +0000 Subject: [PATCH] fixed bug 525: it is now possible.. * to specify a maximum response size * to define a custom response handler (e.g. for directly writing the response to the disk) * to specify credentials directly in the URL additionallz the returned result-object now contains a map with all header-fields. --- helma/Http.js | 118 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 89 insertions(+), 29 deletions(-) diff --git a/helma/Http.js b/helma/Http.js index 7aaeebe6..a9c052f7 100644 --- a/helma/Http.js +++ b/helma/Http.js @@ -9,9 +9,9 @@ * Copyright 1998-2006 Helma Software. All Rights Reserved. * * $RCSfile: Http.js,v $ - * $Author: robert $ - * $Revision: 1.5 $ - * $Date: 2007/04/23 12:10:07 $ + * $Author: michi $ + * $Revision: 1.6 $ + * $Date: 2007/05/03 11:09:05 $ */ @@ -39,6 +39,7 @@ if (!global.helma) { * @constructor */ helma.Http = function() { + var self = this; var proxy = null; var content = ""; var userAgent = "Helma Http Client"; @@ -52,6 +53,31 @@ helma.Http = function() { "connect": 0, "socket": 0 }; + var maxResponseSize = null; + + var responseHandler = function(connection, result) { + var input = new java.io.BufferedInputStream(connection.getInputStream()); + var body = new java.io.ByteArrayOutputStream(); + var buf = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024); + var len; + var currentSize = 0; + var maxResponseSize = self.getMaxResponseSize(); + while ((len = input.read(buf)) > -1) { + body.write(buf, 0, len); + currentSize += len; + if (maxResponseSize && currentSize > maxResponseSize) { + throw new Error("Maximum allowed response size is exceeded"); + } + } + input.close(); + if (binaryMode) { + result.content = body.toByteArray(); + } else { + result.content = result.charset ? + body.toString(result.charset) : + body.toString(); + } + }; /** @private */ var setTimeout = function(type, value) { @@ -351,6 +377,36 @@ helma.Http = function() { return binaryMode; }; + /** + * Sets the max allowed size for the response stream + * @param {Integer} Size in Byte + */ + this.setMaxResponseSize = function(size) { + maxResponseSize = size; + return; + }; + + /** + * Returns the currently set max response size + * @returns The max responsesize + * @type Integer + * @see #setMaxResponseSize + */ + this.getMaxResponseSize = function() { + return maxResponseSize; + }; + + /** + * Overloads the default response handler + * Use this do implement your own response handling, like storing the response directly to the harddisk + * The handler function gets two parameter, first is the Connection and second is the result object + * @param {function} Response handler function + */ + this.setResponseHandler = function(callback) { + responseHandler = callback; + return; + }; + /** * Executes a http request * @param {String} url The url to request @@ -365,11 +421,13 @@ helma.Http = function() { *
  • message: (String) An optional HTTP response message
  • *
  • length: (Number) The content length of the response
  • *
  • type: (String) The mimetype of the response
  • + *
  • charset: (String) The character set of the response
  • *
  • encoding: (String) An optional encoding to use with the response
  • *
  • lastModified: (String) The value of the lastModified response header field
  • *
  • eTag: (String) The eTag as received from the remote server
  • *
  • cookie: (helma.Http.Cookie) An object containing the cookie parameters, if the remote server has set the "Set-Cookie" header field
  • + *
  • headers: (java.util.Map) A map object containing the headers, access them using get("headername") *
  • content: (String|ByteArray) The response received from the server. Can be either a string or a byte array (see #setBinaryMode)
  • * @@ -394,6 +452,12 @@ helma.Http = function() { else if ((typeof opt == "string") && (opt.length > 0)) conn.setRequestProperty("If-None-Match", opt); } + + var userinfo; + if (userinfo = url.getUserInfo()) { + userinfo = userinfo.split(/:/, 2); + this.setCredentials(userinfo[0], userinfo[1]); + } if (credentials != null) { conn.setRequestProperty("Authorization", "Basic " + credentials); } @@ -435,16 +499,18 @@ helma.Http = function() { lastModified: null, eTag: conn.getHeaderField("ETag"), cookies: null, + headers: conn.getHeaderFields(), content: null, } + // parse all "Set-Cookie" header fields into an array of // helma.Http.Cookie instances - var cookies = conn.getHeaderFields().get("Set-Cookie"); - if (cookies != null) { + var setCookies = conn.getHeaderFields().get("Set-Cookie"); + if (setCookies != null) { var arr = []; var cookie; - for (var i=0; i maxResponseSize) { + throw new Error("Maximum allowed response size is exceeded"); + } + + if (result.type && result.type.indexOf("charset=") != -1) { + var charset = result.type.substring(result.type.indexOf("charset=") + 8); + charset = charset.replace('"', ' ').trim(); + result.charset = charset; + } + if (result.length != 0 && result.code == 200) { - var body = new java.io.ByteArrayOutputStream(); - var input = new java.io.BufferedInputStream(conn.getInputStream()); - var buf = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024); - var str; - while ((str = input.read(buf)) > -1) { - body.write(buf, 0, str); + responseHandler(conn, result); + if (result.content) { + result.length = result.content.length; } - input.close(); - if (binaryMode) { - result.content = body.toByteArray(); - } else { - var charset; - if (result.type && result.type.indexOf("charset=") != -1) { - charset = result.type.substring(result.type.indexOf("charset=") + 8); - charset = charset.replace('"', ' ').trim(); - } - result.content = charset ? - body.toString(charset) : - body.toString(); - } - result.length = result.content.length; } conn.disconnect(); return result;