Barracuda: Updated HttpRequester

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

I have made some updates to the 
org.enhydra.barracuda.plankton.http.HttpRequester class to support the 
use of cookies between server and client. This also involved the 
creation of a new org.enhydra.barracuda.plankton.http.Cookie class to 
represent an HTTP cookie.

I have attached these files to this email, so if someone thinks this 
update may be useful they can use it themselves or a committer can 
commit it to the barracuda tree or whatever you guys feel you want to do 
with it.

Thanks!
-shawn

-- 
====================================
Shawn Wilson [[email protected]]
Software Developer, ATMReports.com
PH: 877-327-0873, FAX: 406-294-5806
====================================
Cookie.java (text/plain, 5.5 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.text.*;
import java.util.*;

//saw_112602.1 - added
/**
 * Basic representation of an HTTP 'cookie'.
 * See http://wp.netscape.com/newsref/std/cookie_spec.html for more
 * information about cookies.
 *
 * @author [email protected]
 */
public class Cookie
{
    protected static final DateFormat df = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss zzz");

    protected String name;
    protected String value;
    protected Date expires;
    protected String domain;
    protected String path;
    protected boolean secure;
    
    /**
     * Construct a cookie from a single 'Set-Cookie' header value string from the server.
     *
     * @throws ParseException if the string cannot be parsed into a valid cookie
     */
    public Cookie(String str) throws ParseException {
        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 {
            name = str1.substring(0, index);
            value = str1.substring(index+1);
        }
        
        while(st.hasMoreTokens()) {
            str1 = st.nextToken();
            String str2 = str1.trim();
            
            if(str2.startsWith("expires=")) {
                try { expires = df.parse(str2.substring(8)); }
                catch(ParseException e) {
                    ParseException ee = new ParseException("Invalid date format for 'expires' option", length+8);
                    ee.initCause(e);
                    throw ee;
                }
            } else if(str2.startsWith("domain=")) {
                domain = str2.substring(7);
            } else if(str2.startsWith("path=")) {
                path = str2.substring(5);
            } else if(str2.equals("secure")) {
                secure = true;
            } else {
                throw new ParseException("Unrecognized option: "+str2, length);
            }
            
            length += 1+str1.length();  // (+1 for the semicolon delimiter)
        }
    }

    /**
     * Construct a minimal cookie.
     * Every cookie must have at least a name and value.
     *
     * @throws NullPointerException is name or value is <code>null</code>.
     */
    public Cookie(String name, String value) {
        this(name, value, (Date)null, null, null, false);
    }

    /**
     * Construct a cookie with the given values.
     * Every cookie must have at least a name and value.
     *
     * @param expires must be in the format defined in the cookie specification
     *
     * @throws NullPointerException is name or value is <code>null</code>.
     * @throws ParseException if the 'expires' parameter is not in the correct format.
     */
    public Cookie(String name, String value, String expires, String domain, String path, boolean secure) throws ParseException {
        this(name, value, (df==null ? null : df.parse(expires)), domain, path, secure);
    }

    /**
     * Construct a cookie with the given values.
     * Every cookie must have at least a name and value.
     *
     * @throws NullPointerException is name or value is <code>null</code>.
     */
    public Cookie(String name, String value, Date expires, String domain, String path, boolean secure) {
        if(name == null || value == null) throw new NullPointerException("Neither 'name' nor 'value' may be null");
        this.name = name;
        this.value = value;
        this.expires = expires;
        this.domain = domain;
        this.path = path;
        this.secure = secure;
    }
    
    public String getName() {
        return name;
    }
    
    public String getValue() {
        return value;
    }
    
    public Date getExpires() {
        return expires;
    }
    
    public String getDomain() {
        return domain;
    }
    
    public String getPath() {
        return path;
    }
    
    public boolean isSecure() {
        return secure;
    }
    
    public String toString() {
        StringBuffer sb = new StringBuffer(name+"="+value);
        if(expires != null) sb.append("; expires=").append(df.format(expires));
        if(domain != null) sb.append("; domain=").append(domain);
        if(path != null) sb.append("; path=").append(path);
        if(secure) sb.append("; secure");
        
        return sb.toString();
    }
};
HttpRequester.java (text/plain, 22.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 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
 *
 * 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_112602.1
    protected List cookies = null;           //saw_112602.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_112602.1 - begin
    /**
     * 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_112602.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;
        
        //POST
        if (method==POST) {
            //open the connection and set output & input to true
            conn = url.openConnection();
            conn.setDoOutput(true);
            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);
            }
            
            //write the key values to the stream
            outStream = conn.getOutputStream();
            getOutputWriter().writeOutput(outStream);
        //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 and set input to true
            conn = url.openConnection();
            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_112602.1 - begin
        //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.
            
            StringBuffer sb = new StringBuffer();
            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.isSecure() || url.getProtocol().equalsIgnoreCase("https")) {
                            sb.append(cookie.getName()).append('=').append(cookie.getValue()).append("; ");
                        } 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(sb.length() > 0) {
                //System.out.println("Sending header Cookie: "+sb.toString());
                conn.setRequestProperty("Cookie", sb.toString());
            }
        }

        //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 = new Cookie(cookieStr);
                    //System.out.println(" COOKIE: "+cookie);
                    cookies.add(cookie);
                } catch(ParseException e) {
                    e.printStackTrace();
                }
            }
        }
    //saw_112602.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_112602.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.