Re: Barracuda: Updated HttpRequester

Shawn Wilson <[email protected]>
Newsgroups gmane.comp.java.enhydra.barracuda.general
Organization ATMReports.com
Message-ID <[email protected]>
Jake,

I finally got around to finishing this up. I went ahead and utilized the 
servlet Cookie class and created an HttpServices class to provide 
utility cookie parsing and formatting methods (instead of extended 
javax.servlet.http.Cookie).

The updated code should pretty much support both Version 0 and Version 1 
cookie specifications, though I haven't been able to thoroughly test it. 
Search the attached files for "saw_121102.1" to see my changes.

Christian told me he'll go ahead and incorporate this into CVS if all 
looks well.

Thanks,
-shawn

Jacob Kjome wrote:
> Hello Shawn,
> 
> That would make more sense.  You might want to check if there are any
> differences between the servlet-2.2 and servlet-2.3 api for the Cookie
> class.  Hopefully they are the same.  If not, make sure to document
> what is servlet-2.3 specific.  And, yes, you could go ahead extend
> Cookie.  However, I still would like to know what functionality you
> are looking to get out of your custom Cookie class that the servlet api doesn't provide?
> Like I said, a simple getCookie() is the only thing I see lacking and
> that isn't even really a problem with the Cookie class, it is a
> problem with the HttpServletRequest class....
> 
> public static Cookie getCookie(HttpServletRequest req, String cookieName) {
>     Cookie cookie = null;
>     Cookie[] cookies = req.getCookies();
>     if (cookies!=null) {
>         for (int i=0; i < cookies.length; i++) {
>             if (cookies[i].getName().equals(cookieName)) {
>                 cookie = cookies[i];
>                 break;
>             }
>         }    
>     }
>     return cookie;
> }
> 
> I would think this could be put in something like
> RequestServices.java which would be analogous to classes like
> SessionServices or ContextServices in
> org.enhydra.barracuda.plankton.http.
> 
> I think it confuses the issue to extend the Cookie
> class if you aren't going to override existing behavior.  We should
> make use of the servlet api directly as much as possible, otherwise we
> have some extra maintenance on our hands.
> 
> What do you think?
> 
> Jake
> 
> Wednesday, November 27, 2002, 2:10:27 PM, you wrote:
> 
> SW> Jake,
> 
> SW> You have a good point. When I looked for an existing basic Cookie class, 
> SW> I looked through the J2SE 1.4 API docs but I didn't think to look 
> SW> through the J2EE API (where the servlet packages are).
> 
> SW> Looking at javax.servlet.http.Cookie now, I probably could have just 
> SW> extended that class to add a few additional constructors and methods I 
> SW> provide in mine. If you think it is worth it, I can go ahead and make 
> SW> this change and post the updated code.
> 
> SW> Thanks,
> SW> -shawn
> 
> SW> Jacob Kjome wrote:
> 
>>>Hello Shawn,
>>>
>>>I haven't looked at this much, but doesn't the Cookie class duplicate
>>>the functionality of the servlet api's Cookie class?
>>>
>>>The only real thing lacking with the servlet api's Cookie class is
>>>that it doesn't have a getCookie("mycookie") method.  You have to get
>>>all cookies and loop through them.  A utility method for this would be
>>>fine, but why the duplication of the whole Cookie class?
>>>
>>>Jake
>>>
>>>Wednesday, November 27, 2002, 12:49:32 PM, you wrote:
>>>
>>>SW> Folks,
>>>
>>>SW> I have made some updates to the 
>>>SW> org.enhydra.barracuda.plankton.http.HttpRequester class to support the 
>>>SW> use of cookies between server and client. This also involved the 
>>>SW> creation of a new org.enhydra.barracuda.plankton.http.Cookie class to 
>>>SW> represent an HTTP cookie.
>>>
>>>SW> I have attached these files to this email, so if someone thinks this 
>>>SW> update may be useful they can use it themselves or a committer can 
>>>SW> commit it to the barracuda tree or whatever you guys feel you want to do 
>>>SW> with it.
>>>
>>>SW> Thanks!
>>>SW> -shawn
>>>
>>>
>>>
>>>
> 
> 
> 
> 
> 

-- 
====================================
Shawn Wilson [[email protected]]
Software Developer, ATMReports.com
PH: 877-327-0873, FAX: 406-294-5806
====================================
HttpServices.java (text/plain, 6 KB)
/*
 * Enhydra Java Application Server Project
 * 
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License on
 * the Enhydra web site (http://www.enhydra.org/).
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
 * the License for the specific terms governing rights and limitations
 * under the License.
 * 
 * The Initial Developer of the Enhydra Application Server is Lutris
 * Technologies, Inc. The Enhydra Application Server and portions created
 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s):
 * 
 * $Id:$
 */
package org.enhydra.barracuda.plankton.http;
//saw_121102.1 - created

import java.text.*;
import java.util.*;
import javax.servlet.http.*;

/**
 * This class provides HTTP-related utility methods.
 *
 * @author [email protected]
 */
public class HttpServices
{
    protected static final DateFormat cookieDF = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss zzz");
    
    /**
     * Return a Cookie from a single 'Set-Cookie' header value string from the server.
     * The value string must conform to either the Version 0 (by Netscape) or Version 1
     * (by RFC 2109) cookie specification.
     *
     * @throws ParseException if the string cannot be parsed into a valid cookie
     *
     * @see <a href="http://wp.netscape.com/newsref/std/cookie_spec.html">Cookie Specification, Version 0</a>
     * @see <a href="http://rfc-2109.rfc-list.org/">Cookie Specification, Version 1</a>
     */
    public static Cookie parseCookie(String str) throws ParseException {
        Cookie cookie;
        StringTokenizer st = new StringTokenizer(str, ";");
        int length = 0; // to keep track of position for ParseExceptions
        
        String str1 = st.nextToken();
        length += str1.length();
        str1 = str1.trim();
        int index = str1.indexOf('=');
        
        if(index < 0) throw new ParseException("Missing name=value pair", 0);
        else if(index == 0) throw new ParseException("Missing name for name=value pair", 0);
        else if(index == str1.length()) throw new ParseException("Missing value for name=value pair", 0);
        else cookie = new Cookie(str1.substring(0, index), str1.substring(index+1));
        
        while(st.hasMoreTokens()) {
            str1 = st.nextToken();
            index = str1.indexOf('=');
            
            if(index < 0) {
                if(str1.trim().equalsIgnoreCase("secure")) {
                    cookie.setSecure(true);
                } else {
                    //throw new ParseException("Unrecognized option: "+str1, length);
                    // for compatibility with future cookie specifications, we will simply
                    // silently ignore any unrecognized fields
                }
            } else if(index > 0) {
                String key = str1.substring(0, index).trim().toLowerCase();
                String val = str1.substring(index+1);
                
                if(key.equals("comment")) {
                    cookie.setComment(val);
                } else if(key.equals("domain")) {
                    cookie.setDomain(val);
                } else if(key.equals("max-age")) {
                    try { cookie.setMaxAge(Integer.parseInt(val)); }
                    catch(NumberFormatException e) {
                        ParseException ee = new ParseException("Not an integer for 'max-age' field", length+8);
                        ee.initCause(e);
                        throw ee;
                    }
                } else if(key.equals("path")) {
                    cookie.setPath(val);
                } else if(key.equals("version")) {
                    try { cookie.setVersion(Integer.parseInt(val)); }
                    catch(NumberFormatException e) {
                        ParseException ee = new ParseException("Not an integer for 'version' field", length+8);
                        ee.initCause(e);
                        throw ee;
                    }
                } else if(key.equals("expires")) {
                    // provided for Version 0 compatibility
                    try { cookie.setMaxAge( (int)(cookieDF.parse(val).getTime()/1000) ); }
                    catch(ParseException e) {
                        ParseException ee = new ParseException("Invalid date format for 'expires' field", length+8);
                        ee.initCause(e);
                        throw ee;
                    }
                } else {
                    //throw new ParseException("Unrecognized option: "+str1, length);
                    // for compatibility with future cookie specifications, we will simply
                    // silently ignore any unrecognized fields
                }
            } else {
                throw new ParseException("Missing option: "+str1, length);
            }
            
            length += 1+str1.length();  // (+1 for the semicolon delimiter)
        }
        
        return cookie;
    }
    
    /**
     * Return a formatted cookie string for use in a 'Set-Cookie' header.
     */
    public static String formatCookie(Cookie cookie) {
        StringBuffer sb = new StringBuffer(cookie.getName()+"="+cookie.getValue());
        if(cookie.getComment() != null) sb.append(";Comment=").append(cookie.getComment());
        if(cookie.getDomain() != null) sb.append(";Domain=").append(cookie.getDomain());
        if(cookie.getPath() != null) sb.append(";Path=").append(cookie.getPath());
        if(cookie.getSecure()) sb.append(";Secure");
        if(cookie.getVersion() == 0) {
            if(cookie.getMaxAge() >= 0) sb.append(";Expires=").append(cookieDF.format(new Date(cookie.getMaxAge())));
        } else {
            sb.append(";Version=").append(cookie.getVersion());
            sb.append(";Max-Age=").append(cookie.getMaxAge());
        }
        
        return sb.toString();
    }
};
HttpRequester.java (text/plain, 24.6 KB)
/*
 * Enhydra Java Application Server Project
 * 
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License on
 * the Enhydra web site (http://www.enhydra.org/).
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
 * the License for the specific terms governing rights and limitations
 * under the License.
 * 
 * The Initial Developer of the Enhydra Application Server is Lutris
 * Technologies, Inc. The Enhydra Application Server and portions created
 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s):
 * 
 * $Id: HttpRequester.java,v 1.1 2002/11/02 19:15:53 cryd0221 Exp $
 */
package org.enhydra.barracuda.plankton.http;

import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import javax.servlet.http.*;

import org.enhydra.barracuda.plankton.data.Base64;

/**
 * This class encapsulates access to/from a URL via both POST and GET methods. 
 * To use, simply set the URL, the method (POST/GET), and the params. If you're
 * using get, the params are optional (they can be included as part of the URL). 
 * Also note that you can pass a username and password if you need to do basic 
 * authentication. This class also now supports cookies, thanks to Shawn Wilson 
 * [[email protected]] - look at the sample code down in the main method for
 * an example of how to use it (basically, you just use the requestor to access a
 * URL, thereby getting the cookie, and then you re-use the requestor to access
 * any other URLs which depend on that cookie).
 *
 * Refer to the source for this class (main method) to see an example of
 * how you would use this class for both POST and GET methods:
 */
public class HttpRequester {

    public static final String POST = "POST";
    public static final String GET = "GET";

    protected URL url = null;
    protected String method = GET;
    protected Map props = null;
    protected HttpOutputWriter outputWriter = null;
    protected String user = null;
    protected String password = null;
    protected boolean authenticate = false;
    protected boolean acceptCookies = true;  //saw_121102.1
    protected List cookies = null;           //saw_121102.1

    protected OutputStream outStream = null;
    protected InputStream inStream = null;
    protected BufferedReader in = null;

    /**
     * Set the Request. This is a convenience method to encapsulate
     * calls to setUrl, setMethod, and setParams all in one fell swoop.
     *
     * @param url the URL we wish to access
     * @param method the method we wish to use (either GET or POST)
     * @param props the Map contains our key-value URL parameter pairs.
     *       If the value is a Set, the resulting URL will contain a key-value
     *        mapping for each entry in the Set.
     * @throws MalformedURLException
     */
    public void setRequest(String iurl, String imethod, Map iprops) throws MalformedURLException {
        setRequest(iurl, imethod, iprops, null);
    }

    /**
     * Set the Request. This is a convenience method to encapsulate
     * calls to setUrl, setMethod, and setParams all in one fell swoop.
     *
     * @param url the URL we wish to access
     * @param method the method we wish to use (either GET or POST)
     * @param props the Map contains our key-value URL parameter pairs.
     *       If the value is a Set, the resulting URL will contain a key-value
     *        mapping for each entry in the Set.
     * @throws MalformedURLException
     */
    public void setRequest(URL iurl, String imethod, Map iprops) throws MalformedURLException {
        setRequest(iurl, imethod, iprops, null);
    }

    /**
     * Set the Request. This is a convenience method to encapsulate
     * calls to setUrl, setMethod, and setParams all in one fell swoop.
     *
     * @param url the URL we wish to access
     * @param method the method we wish to use (either GET or POST)
     * @param props the Map contains our key-value URL parameter pairs.
     *       If the value is a Set, the resulting URL will contain a key-value
     *        mapping for each entry in the Set.
     * @param outputWriter the HttpOutputWriter we wish to write to
     * @throws MalformedURLException
     */
    public void setRequest(String iurl, String imethod, Map iprops, HttpOutputWriter ioutputWriter) throws MalformedURLException {
        setRequest(iurl, imethod, iprops, null, null, null);
    }

    /**
     * Set the Request. This is a convenience method to encapsulate
     * calls to setUrl, setMethod, and setParams all in one fell swoop.
     *
     * @param url the URL we wish to access
     * @param method the method we wish to use (either GET or POST)
     * @param props the Map contains our key-value URL parameter pairs.
     *       If the value is a Set, the resulting URL will contain a key-value
     *        mapping for each entry in the Set.
     * @param outputWriter the HttpOutputWriter we wish to write to
     * @throws MalformedURLException
     */
    public void setRequest(URL iurl, String imethod, Map iprops, HttpOutputWriter ioutputWriter) throws MalformedURLException {
        setRequest(iurl, imethod, iprops, null, null, null);
    }

    /**
     * Set the Request. This is a convenience method to encapsulate
     * calls to setUrl, setMethod, and setParams all in one fell swoop.
     *
     * @param url the URL we wish to access
     * @param method the method we wish to use (either GET or POST)
     * @param props the Map contains our key-value URL parameter pairs.
     *       If the value is a Set, the resulting URL will contain a key-value
     *        mapping for each entry in the Set.
     * @param user the user named required to connect
     * @param password the password named required to connect
     * @param outputWriter the HttpOutputWriter we wish to write to
     * @throws MalformedURLException
     */
    public void setRequest(String iurl, String imethod, Map iprops, String iuser, String ipwd, HttpOutputWriter ioutputWriter) throws MalformedURLException {
        if (iurl!=null) setUrl(iurl);
        if (imethod!=null) setMethod(imethod);
        if (iprops!=null) setParams(iprops);
        if (iuser!=null) setUser(iuser);
        if (ipwd!=null) setPassword(ipwd);
        if (ioutputWriter!=null) setOutputWriter(ioutputWriter);
    }

    /**
     * Set the Request. This is a convenience method to encapsulate
     * calls to setUrl, setMethod, and setParams all in one fell swoop.
     *
     * @param url the URL we wish to access
     * @param method the method we wish to use (either GET or POST)
     * @param props the Map contains our key-value URL parameter pairs.
     *       If the value is a Set, the resulting URL will contain a key-value
     *        mapping for each entry in the Set.
     * @param user the user named required to connect
     * @param password the password named required to connect
     * @param outputWriter the HttpOutputWriter we wish to write to
     * @throws MalformedURLException
     */
    public void setRequest (URL iurl, String imethod, Map iprops, String iuser, String ipwd, HttpOutputWriter ioutputWriter) throws MalformedURLException {
        if (iurl!=null) setUrl(iurl);
        if (imethod!=null) setMethod(imethod);
        if (iprops!=null) setParams(iprops);
        if (iuser!=null) setUser(iuser);
        if (ipwd!=null) setPassword(ipwd);
        if (ioutputWriter!=null) setOutputWriter(ioutputWriter);
    }

    /**
     * Set the URL we wish to access
     *
     * @param url the URL we wish to access
     * @throws MalformedURLException
     */
    public void setUrl (String iurl) throws MalformedURLException {
        //if we're setting it back to null, otherwise, create the url 
        //which represents the servlet which will do the generation
        if (iurl==null) url = null;
        else setUrl (new URL (iurl));
    }

    /**
     * Set the URL we wish to access
     *
     * @param url the URL we wish to access
     */
    public void setUrl (URL iurl) {
        url = iurl;
    }

    /**
     * Get the URL for the HttpRequest object
     *
     * @return the URL behind this request
     */
    public URL getUrl () {
        return url;
    }

    /**
     * Set the method we wish to use. Valid values are either GET
     * or POST. Default is GET.
     *
     * @param  method the method we wish to use (either GET or POST)
     */
    public void setMethod (String imethod) {
        if (imethod.toUpperCase().equals(POST)) method = POST;
        else method = GET;
    }

    /**
     * Get the method we're using for this HttpRequest object
     *
     * @return the method we're using (either GET or POST)
     */
    public String getMethod () {
        return method;
    }

    /**
     * Set the parmeters we wish to pass to the URL as name-value pairs.
     * If you are using the POST method, it will look for properties in
     * here. If you are using the get method, you can manually pass the
     * properties as part of the URL string, and just ignore this method.
     *
     * @param  props the Map contains our key-value URL parameter pairs.
     *       If the value is a Set, the resulting URL will contain a key-value
     *        mapping for each entry in the Set.
     */
    public void setParams (Map iprops) {
        props = iprops;
    }

    /**
     * Return the HashMap object for this HttpRequest. If the map is null (ie.
     * because you are using the GET method), we attempt to look for the
     * properties in the actual URL string and build a HashMap from that.
     *
     * @return a Map containing all the parameters for this HttpRequest
     */
    public Map getParams () {
        //if someone asks for the param map and its null, try
        //and build it based on the actual URL string
        if (props==null) {
            //avoid the obvious errs
            if (url==null) return null;

            //build the HashMap
            props = HttpConverter.cvtURLStringToMap (url.toString(), "&");
        }

        //return the HashMap
        return props;
    }

    /**
     * Set the user (if we need to authenticate in order to make the connection)
     *
     * @param user the user name
     */
    public void setUser(String iuser) {
        user = iuser;
        authenticate = (user!=null);
    }

    /**
     * Get the user name
     *
     * @return the user name
     */
    public String getUser() {
        return user;
    }

    /**
     * Set the password (if we need to authenticate in order to make the connection)
     *
     * @param password the password
     */
    public void setPassword(String ipassword) {
        password = ipassword;
        authenticate = (password!=null);
    }

    /**
     * Get the password
     *
     * @return the password
     */
    protected String getPassword() {
        return password;
    }

    //saw_121102.1_start
    /**
     * Set whether or not to accept cookies from the server.
     * The default is <code>true</code>.
     *
     * Setting this value to <code>false</code> after cookies
     * have already been obtained does not clear the current
     * cookies, it simply will not accept any new cookies.
     *
     * @see #clearCookies()
     */
    public void setAcceptCookies(boolean accept) {
        this.acceptCookies = accept;
    }

    /**
     * Determine whether or not we are accepting cookies.
     */
    public boolean getAcceptCookies() {
        return acceptCookies;
    }

    /**
     * Return a list of cookies this client is sending to the server
     *
     * @return a list of {@link Cookie cookies}, or <code>null</code> if
     * the server has not set any cookies in the client
     *
     * @see Cookie
     */
    public List getCookies() {
        return cookies;
    }
    
    /**
     * Clear any cookies this client knows about.
     */
    public void clearCookies() {
        cookies = null;
    }
    //saw_121102.1_end

    /**
     * Set the output writer to be used for posting data
     *
     * @param  ioutputWriter the HttpOutputWriter
     */
    public void setOutputWriter (HttpOutputWriter ioutputWriter) {
        outputWriter = ioutputWriter;
    }

    /**
     * Return the output writer. If none is set, the default will be used.
     *
     * @return the HttpOutputWriter
     */
    public HttpOutputWriter getOutputWriter () {
        //if someone asks for the output writer and its null,
        //return the default
        if (outputWriter==null) {
            return new DefaultOutputWriter ();
        } else
            return outputWriter;
    }

    /**
     * Connect to the URL
     *
     * @throws ConnectException
     * @throws IOException
     */
    public void connect() throws ConnectException, IOException {
        //pre-launch checks
        if (url==null) throw new ConnectException ("Invalid URL. URL can not be NULL");
        if (method!=POST && method!=GET) throw new ConnectException ("Invalid Method. Method must be either POST or GET");

        URLConnection conn = null;  //saw_121102.1

        //POST
        if (method==POST) {
            //open the connection for both output and input
//saw_121102.1            URLConnection conn = url.openConnection();
            conn = url.openConnection();    //saw_121102.1
            conn.setDoOutput(true);

            //Set up an authorization header with our credentials (this chunk of
            //code stolen from org.apache.catalina.ant.AbstractCatalinaTask; 
            //thanks to Craig R. McClanahan [[email protected]] for pointing
            //me to this example)
            if (authenticate) {
                String input = user + ":" + password;
                String output = new String(Base64.encode(input.getBytes()));
                conn.setRequestProperty("Authorization", "Basic " + output);
            }
            
            //write the key values to the stream
            outStream = conn.getOutputStream();
            getOutputWriter().writeOutput(outStream);

//saw_121102.1_start - deferred to down below
            //now open an input stream to read the response
//            inStream = conn.getInputStream();
//            in = new BufferedReader(new InputStreamReader(inStream));
//saw_121102.1_end
        //GET
        } else {
            //first see if we have a param structure...if so, build a URL String.
            if (props!=null) {
                //figure out what the current URL is and strip off any parameters
                String newUrl = getUrl().toString();
                int pos = newUrl.indexOf("?");
                if (pos>0) newUrl = newUrl.substring(0,pos);

                //now run through the map and build a new url string
                setUrl(newUrl+"?"+ HttpConverter.cvtMapToURLString(props, "&"));
                newUrl = getUrl().toString();
                if (newUrl.endsWith("?")) setUrl(newUrl.substring(0,newUrl.length()-1));

                //now set the url and set the params object back to null so we don't
                //need to rebuild the URL string again
                setParams(null);
            }

            //open the connection for input
//saw_121102.1            URLConnection conn = url.openConnection();
            conn = url.openConnection();    //saw_121102.1
            conn.setDoInput(true);
            
            //Set up an authorization header with our credentials (this chunk of
            //code stolen from org.apache.catalina.ant.AbstractCatalinaTask; 
            //thanks to Craig R. McClanahan [[email protected]] for pointing
            //me to this example)
            if (authenticate) {
                String input = user + ":" + password;
                String output = new String(Base64.encode(input.getBytes()));
                conn.setRequestProperty("Authorization", "Basic " + output);
            }
            
//saw_121102.1_start - deferred to down below
            //now get an input stream
//            inStream = conn.getInputStream();
//            in = new BufferedReader(new InputStreamReader(inStream));
//saw_121102.1_end
        }

        //saw_121102.1_start
        //do we have cookies to send?
        if(cookies != null) {
            //NOTE: this implementation of cookie support is very basic and
            //does not completely follow spec. Specifically, cookie expiration
            //is not checked and a single repeated cookie is not ordered by
            //the path specifications as the spec requires.
            
            StringBuffer sb = new StringBuffer();
            int maxVersion = 0;
            boolean haveCookies = false;
            Iterator it = cookies.iterator();
            while (it.hasNext()) {
                Cookie cookie = (Cookie)it.next();
                if (cookie.getDomain() == null || url.getHost().toLowerCase().endsWith(cookie.getDomain().toLowerCase())) {
                    if (cookie.getPath() == null || url.getPath().startsWith(cookie.getPath())) {
                        if (!cookie.getSecure() || url.getProtocol().equalsIgnoreCase("https")) {
                            // if we're here, then it's safe to transmit the cookie
                            haveCookies = true;
                            
                            sb.append(';').append(cookie.getName()).append('=').append(cookie.getValue());
                            if(cookie.getVersion() > 0) {
                                if(cookie.getVersion() > maxVersion) maxVersion = cookie.getVersion();
                                if(cookie.getPath() != null) sb.append(";$Path=").append(cookie.getPath());
                                if(cookie.getDomain() != null) sb.append(";$Domain=").append(cookie.getDomain());
                            }
                        } else {
                            //System.out.println("Ignoring cookie for secure transmission");
                        }
                    } else {
                        //System.out.println("Ignoring cookie for different path: "+cookie.getPath());
                    }
                } else {
                    //System.out.println("Ignoring cookie for different domain: "+cookie.getDomain());
                }
            }
            
            if (haveCookies) {
                String cookieStr;
                if(maxVersion == 0) cookieStr = sb.substring(1);    // gets rid of first semicolon
                else cookieStr = "$Version="+maxVersion+sb.toString();
                
                //System.out.println("Sending header Cookie: "+cookieStr);
                conn.setRequestProperty("Cookie", cookieStr);
            }
        }

        //now open an input stream to read the response
        inStream = conn.getInputStream();
        in = new BufferedReader(new InputStreamReader(inStream));
        
        //are we accepting cookies, and did the server send any back?
        List scookies = (List) conn.getHeaderFields().get("Set-Cookie");
        if (acceptCookies && scookies != null) {
            cookies = new ArrayList(scookies.size());
            //System.out.println("Got cookie header(s) from server:");
            Iterator it = scookies.iterator();
            while (it.hasNext()) {
                String cookieStr = (String) it.next();
                //System.out.println(" --> " + cookieStr);
                try {
                    Cookie cookie = HttpServices.parseCookie(cookieStr);
                    //System.out.println(" COOKIE: "+HttpServices.formatCookie(cookie));
                    //cookie.setVersion(1);   //### FOR TESTING ONLY
                    cookies.add(cookie);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
        //saw_121102.1_end
    }

    /**
     * Read responses from the URL
     *
     * @return a String representation of what we got back
     * @throws ConnectException
     * @throws IOException
     */
    public String readLine() throws ConnectException, IOException {
        //pre-launch checks
        if (in==null) throw new ConnectException ("Connection is not active");

        //get the line
        String inputLine = in.readLine();

        //if its null, auto disconnect
        if (inputLine==null) disconnect();

        //now return the String
        return inputLine;
    }

    /**
     * Get the underlying output stream
     *
     * @return the output stream
     * @throws ConnectException
     */
    public OutputStream getOutputStream() throws ConnectException {
        //pre-launch checks
        if (outStream==null) throw new ConnectException ("Connection is not active");

        //return the input stream
        return outStream;
    }

    /**
     * Get the underlying input stream
     *
     * @return the input stream
     * @throws ConnectException
     */
    public InputStream getInputStream() throws ConnectException {
        //pre-launch checks
        if (inStream==null) throw new ConnectException ("Connection is not active");

        //return the input stream
        return inStream;
    }

    /**
     * Disconnect from the URL. You really only need to call this
     * if you terminate the readLine process on your end. if
     * readLine() encounters a null value, it assumes input is
     * complete and automatically calls this method.
     */
    public void disconnect() {
        if (outStream!=null) try {outStream.close();} catch (IOException ioe) {}
        outStream = null;
        if (in!=null) try {in.close();} catch (IOException ioe) {}
        in = null;
        if (inStream!=null) try {inStream.close();} catch (IOException ioe) {}
        inStream = null;
    }

    /**
     * This inner class provides the default mechanism to write to an output stream
     */
    class DefaultOutputWriter implements HttpOutputWriter {
        public void writeOutput(OutputStream outputStream) throws IOException {
            System.out.println ("Using default HttpOutputWriter to POST data");
            PrintWriter out = new PrintWriter(outputStream);
            try {
                String paramStr = HttpConverter.cvtMapToURLString(props, "&");
                if (paramStr!=null && paramStr.trim().length()>0) out.print (paramStr);
                System.out.println ("Data posted!");
            } finally {
                out.close();
                outputStream.close();
            }
        }
    }


    public static void main(String[] args) {
        //sample GET
        try {
            HttpRequester hr = new HttpRequester();
//            String urlStr = "http://localhost:8080/manager/list";   //connect to Tomcat manager app
//            String paramStr = "";
            String urlStr = "http://localhost:8080/manager/reload?path=/examples";   //connect to Tomcat manager app
            String paramStr = null;
            Map props = null;
            if (paramStr!=null) HttpConverter.cvtURLStringToMap (paramStr, "&");
            hr.setRequest(urlStr, HttpRequester.GET, props, "admin", "123123", null);
            hr.connect();
            String inputLine;
            while ((inputLine = hr.readLine()) != null) {
                System.out.println(inputLine);
            }
            hr.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }    
/*        
        //sample POST
        try {
            HttpRequester hr = new HttpRequester();
            String urlStr = "http://localhost:8010/EventHandler6/rocks.examples.ex1.TestEvent.event";
            String paramStr = "parm1=foo&parm2=blah&parm2=boo";
            Map props = HttpConverter.cvtURLStringToMap (paramStr, "&");
            hr.setRequest (urlStr, HttpRequester.POST, props);
            hr.connect();
            String inputLine;
            while ((inputLine = hr.readLine()) != null) {
                System.out.println(inputLine);
            }
            hr.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }    
*/

        //sample cookie support check - saw_121102.1
        try {
            HttpRequester hr = new HttpRequester();
            hr.setRequest("http://www.psycinfo.com/cookie/set-cookie.cfm", HttpRequester.GET, null);
            hr.connect();
            String inputLine;
            while ((inputLine = hr.readLine()) != null) {
                System.out.println(inputLine);
            }
            hr.disconnect();
            
            hr.setRequest("http://www.psycinfo.com/cookie/check-cookie.cfm", HttpRequester.GET, null);
            hr.connect();
            while ((inputLine = hr.readLine()) != null) {
                System.out.println(inputLine);
            }
            hr.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.