/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package tests.support;

import java.io.*;
import java.lang.Thread;
import java.net.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Logger;

/**
 * TestWebServer is a simulated controllable test server that
 * can respond to requests from HTTP clients.
 *
 * The server can be controlled to change how it reacts to any
 * requests, and can be told to simulate various events (such as
 * network failure) that would happen in a real environment.
 */
public class Support_TestWebServer implements Support_HttpConstants {

    /* static class data/methods */

    /* The ANDROID_LOG_TAG */
    private final static String LOGTAG = "httpsv";

    /* Where worker threads stand idle */
    Vector threads = new Vector();

    /* List of all active worker threads */
    Vector activeThreads = new Vector();

    /* timeout on client connections */
    int timeout = 0;

    /* max # worker threads */
    int workers = 5;

    /* Default port for this server to listen on */
    final static int DEFAULT_PORT = 8080;

    /* Default socket timeout value */
    final static int DEFAULT_TIMEOUT = 5000;

    /* Version string (configurable) */
    protected String HTTP_VERSION_STRING = "HTTP/1.1";

    /* Indicator for whether this server is configured as a HTTP/1.1
     * or HTTP/1.0 server
     */
    private boolean http11 = true;

    /* The thread handling new requests from clients */
    private AcceptThread acceptT;

    /* timeout on client connections */
    int mTimeout;

    /* Server port */
    int mPort;

    /* Switch on/off logging */
    boolean mLog = false;

    /* If set, this will keep connections alive after a request has been
     * processed.
     */
    boolean keepAlive = true;

    /* If set, this will cause response data to be sent in 'chunked' format */
    boolean chunked = false;

    /* If set, this will indicate a new redirection host */
    String redirectHost = null;

    /* If set, this indicates the reason for redirection */
    int redirectCode = -1;

    /* Set the number of connections the server will accept before shutdown */
    int acceptLimit = 100;

    /* Count of number of accepted connections */
    int acceptedConnections = 0;

    public Support_TestWebServer() {
    }

    /**
     * Initialize a new server with default port and timeout.
     * @param log Set true if you want trace output
     */
    public void initServer(boolean log) throws Exception {
        initServer(DEFAULT_PORT, DEFAULT_TIMEOUT, log);
    }

    /**
     * Initialize a new server with default timeout.
     * @param port Sets the server to listen on this port
     * @param log Set true if you want trace output
     */
    public void initServer(int port, boolean log) throws Exception {
        initServer(port, DEFAULT_TIMEOUT, log);
    }

    /**
     * Initialize a new server with default timeout and disabled log.
     * @param port Sets the server to listen on this port
     * @param servePath the path to the dynamic web test data
     * @param contentType the type of the dynamic web test data
     */
    public void initServer(int port, String servePath, String contentType)
            throws Exception {
        Support_TestWebData.initDynamicTestWebData(servePath, contentType);
        initServer(port, DEFAULT_TIMEOUT, false);
    }

    /**
     * Initialize a new server with default port and timeout.
     * @param port Sets the server to listen on this port
     * @param timeout Indicates the period of time to wait until a socket is
     *                closed
     * @param log Set true if you want trace output
     */
    public void initServer(int port, int timeout, boolean log) throws Exception {
        mPort = port;
        mTimeout = timeout;
        mLog = log;
        keepAlive = true;

        if (acceptT == null) {
            acceptT = new AcceptThread();
            acceptT.init();
            acceptT.start();
        }
    }

    /**
     * Print to the log file (if logging enabled)
     * @param s String to send to the log
     */
    protected void log(String s) {
        if (mLog) {
            Logger.global.fine(s);
        }
    }

    /**
     * Set the server to be an HTTP/1.0 or HTTP/1.1 server.
     * This should be called prior to any requests being sent
     * to the server.
     * @param set True for the server to be HTTP/1.1, false for HTTP/1.0
     */
    public void setHttpVersion11(boolean set) {
        http11 = set;
        if (set) {
            HTTP_VERSION_STRING = "HTTP/1.1";
        } else {
            HTTP_VERSION_STRING = "HTTP/1.0";
        }
    }

    /**
     * Call this to determine whether server connection should remain open
     * @param value Set true to keep connections open after a request
     *              completes
     */
    public void setKeepAlive(boolean value) {
        keepAlive = value;
    }

    /**
     * Call this to indicate whether chunked data should be used
     * @param value Set true to make server respond with chunk encoded
     *              content data.
     */
    public void setChunked(boolean value) {
        chunked = value;
    }

    /**
     * Call this to specify the maximum number of sockets to accept
     * @param limit The number of sockets to accept
     */
    public void setAcceptLimit(int limit) {
        acceptLimit = limit;
    }

    /**
     * Call this to indicate redirection port requirement.
     * When this value is set, the server will respond to a request with
     * a redirect code with the Location response header set to the value
     * specified.
     * @param redirect The location to be redirected to
     * @param redirectCode The code to send when redirecting
     */
    public void setRedirect(String redirect, int code) {
        redirectHost = redirect;
        redirectCode = code;
        log("Server will redirect output to "+redirect+" code "+code);
    }

    /**
     * Cause the thread accepting connections on the server socket to close
     */
    public void close() {
        /* Stop the Accept thread */
        if (acceptT != null) {
            log("Closing AcceptThread"+acceptT);
            acceptT.close();
            acceptT = null;
        }
    }
    /**
     * The AcceptThread is responsible for initiating worker threads
     * to handle incoming requests from clients.
     */
    class AcceptThread extends Thread {

        ServerSocket ss = null;
        boolean running = false;

        public void init() {
            // Networking code doesn't support ServerSocket(port) yet
            InetSocketAddress ia = new InetSocketAddress(mPort);
            while (true) {
                try {
                    ss = new ServerSocket();
                    // Socket timeout functionality is not available yet
                    //ss.setSoTimeout(5000);
                    ss.setReuseAddress(true);
                    ss.bind(ia);
                    break;
                } catch (IOException e) {
                    log("IOException in AcceptThread.init()");                    
                    // wait and retry
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }
                }
            }
        }

        /**
         * Main thread responding to new connections
         */
        public synchronized void run() {
            running = true;
            try {
                while (running) {
                    // Log.d(LOGTAG, "TestWebServer run() calling accept()");
                    Socket s = ss.accept();
                    acceptedConnections++;
                    if (acceptedConnections >= acceptLimit) {
                        running = false;
                    }

                    Worker w = null;
                    synchronized (threads) {
                        if (threads.isEmpty()) {
                            Worker ws = new Worker();
                            ws.setSocket(s);
                            activeThreads.addElement(ws);
                            (new Thread(ws, "additional worker")).start();
                        } else {
                            w = (Worker) threads.elementAt(0);
                            threads.removeElementAt(0);
                            w.setSocket(s);
                        }
                    }
                }
            } catch (SocketException e) {
                log("SocketException in AcceptThread: probably closed during accept");
                running = false;
            } catch (IOException e) {
                log("IOException in AcceptThread");
                running = false;
            }
            log("AcceptThread terminated" + this);
        }

        // Close this socket
        public void close() {
            try {
                running = false;
                /* Stop server socket from processing further. Currently
                   this does not cause the SocketException from ss.accept
                   therefore the acceptLimit functionality has been added
                   to circumvent this limitation */
                ss.close();

                // Stop worker threads from continuing
                for (Enumeration e = activeThreads.elements(); e.hasMoreElements();) {
                    Worker w = (Worker)e.nextElement();
                    w.close();
                }
                activeThreads.clear();

            } catch (IOException e) {
                /* We are shutting down the server, so we expect
                 * things to die. Don't propagate.
                 */
                log("IOException caught by server socket close");
            }
        }
    }

    // Size of buffer for reading from the connection
    final static int BUF_SIZE = 2048;

    /* End of line byte sequence */
    static final byte[] EOL = {(byte)'\r', (byte)'\n' };

    /**
     * The worker thread handles all interactions with a current open
     * connection. If pipelining is turned on, this will allow this
     * thread to continuously operate on numerous requests before the
     * connection is closed.
     */
    class Worker implements Support_HttpConstants, Runnable {

        /* buffer to use to hold request data */
        byte[] buf;

        /* Socket to client we're handling */
        private Socket s;

        /* Reference to current request method ID */
        private int requestMethod;

        /* Reference to current requests test file/data */
        private String testID;

        /* Reference to test number from testID */
        private int testNum;

        /* Reference to whether new request has been initiated yet */
        private boolean readStarted;

        /* Indicates whether current request has any data content */
        private boolean hasContent = false;

        boolean running = false;

        /* Request headers are stored here */
        private Hashtable<String, String> headers = new Hashtable<String, String>();

        /* Create a new worker thread */
        Worker() {
            buf = new byte[BUF_SIZE];
            s = null;
        }

        /**
         * Called by the AcceptThread to unblock this Worker to process
         * a request.
         * @param s The socket on which the connection has been made
         */
        synchronized void setSocket(Socket s) {
            this.s = s;
            notify();
        }

        /**
         * Called by the accept thread when it's closing. Potentially unblocks
         * the worker thread to terminate properly
         */
        synchronized void close() {
            running = false;
            notify();
        }

        /**
         * Main worker thread. This will wait until a request has
         * been identified by the accept thread upon which it will
         * service the thread.
         */
        public synchronized void run() {
            running = true;
            while(running) {
                if (s == null) {
                    /* nothing to do */
                    try {
                        log(this+" Moving to wait state");
                        wait();
                    } catch (InterruptedException e) {
                        /* should not happen */
                        continue;
                    }
                    if (!running) break;
                }
                try {
                    handleClient();
                } catch (Exception e) {
                    log("Exception during handleClient in the TestWebServer: "
                            + e.getMessage());
                }
                /* go back in wait queue if there's fewer
                 * than numHandler connections.
                 */
                s = null;
                Vector pool = threads;
                synchronized (pool) {
                    if (pool.size() >= workers) {
                        /* too many threads, exit this one */
                        activeThreads.remove(this);
                        return;
                    } else {
                        pool.addElement(this);
                    }
                }
            }
            log(this+" terminated");
        }

        /**
         * Zero out the buffer from last time
         */
        private void clearBuffer() {
            for (int i = 0; i < BUF_SIZE; i++) {
                buf[i] = 0;
            }
        }

        /**
         * Utility method to read a line of data from the input stream
         * @param is Inputstream to read
         * @return number of bytes read
         */
        private int readOneLine(InputStream is) {

            int read = 0;

            clearBuffer();
            try {
                log("Reading one line: started ="+readStarted+" avail="+is.available());
                StringBuilder log = new StringBuilder();
                while ((!readStarted) || (is.available() > 0)) {
                    int data = is.read();
                    // We shouldn't get EOF but we need tdo check
                    if (data == -1) {
                        log("EOF returned");
                        return -1;
                    }

                    buf[read] = (byte)data;

                    log.append((char)data);

                    readStarted = true;
                    if (buf[read++]==(byte)'\n') {
                        log(log.toString());
                        return read;
                    }
                }
            } catch (IOException e) {
                log("IOException from readOneLine");
            }
            return read;
        }

        /**
         * Read a chunk of data
         * @param is Stream from which to read data
         * @param length Amount of data to read
         * @return number of bytes read
         */
        private int readData(InputStream is, int length) {
            int read = 0;
            int count;
            // At the moment we're only expecting small data amounts
            byte[] buf = new byte[length];

            try {
                while (is.available() > 0) {
                    count = is.read(buf, read, length-read);
                    read += count;
                }
            } catch (IOException e) {
                log("IOException from readData");
            }
            return read;
        }

        /**
         * Read the status line from the input stream extracting method
         * information.
         * @param is Inputstream to read
         * @return number of bytes read
         */
        private int parseStatusLine(InputStream is) {
            int index;
            int nread = 0;

            log("Parse status line");
            // Check for status line first
            nread = readOneLine(is);
            // Bomb out if stream closes prematurely
            if (nread == -1) {
                requestMethod = UNKNOWN_METHOD;
                return -1;
            }

            if (buf[0] == (byte)'G' &&
                buf[1] == (byte)'E' &&
                buf[2] == (byte)'T' &&
                buf[3] == (byte)' ') {
                requestMethod = GET_METHOD;
                log("GET request");
                index = 4;
            } else if (buf[0] == (byte)'H' &&
                       buf[1] == (byte)'E' &&
                       buf[2] == (byte)'A' &&
                       buf[3] == (byte)'D' &&
                       buf[4] == (byte)' ') {
                requestMethod = HEAD_METHOD;
                log("HEAD request");
                index = 5;
            } else if (buf[0] == (byte)'P' &&
                       buf[1] == (byte)'O' &&
                       buf[2] == (byte)'S' &&
                       buf[3] == (byte)'T' &&
                       buf[4] == (byte)' ') {
                requestMethod = POST_METHOD;
                log("POST request");
                index = 5;
            } else {
                // Unhandled request
                requestMethod = UNKNOWN_METHOD;
                return -1;
            }

            // A valid method we understand
            if (requestMethod > UNKNOWN_METHOD) {
                // Read file name
                int i = index;
                while (buf[i] != (byte)' ') {
                    // There should be HTTP/1.x at the end
                    if ((buf[i] == (byte)'\n') || (buf[i] == (byte)'\r')) {
                        requestMethod = UNKNOWN_METHOD;
                        return -1;
                    }
                    i++;
                }

                testID = new String(buf, 0, index, i-index);
                if (testID.startsWith("/")) {
                    testID = testID.substring(1);
                }

                return nread;
            }
            return -1;
        }

        /**
         * Read a header from the input stream
         * @param is Inputstream to read
         * @return number of bytes read
         */
        private int parseHeader(InputStream is) {
            int index = 0;
            int nread = 0;
            log("Parse a header");
            // Check for status line first
            nread = readOneLine(is);
            // Bomb out if stream closes prematurely
            if (nread == -1) {
                requestMethod = UNKNOWN_METHOD;
                return -1;
            }
            // Read header entry 'Header: data'
            int i = index;
            while (buf[i] != (byte)':') {
                // There should be an entry after the header

                if ((buf[i] == (byte)'\n') || (buf[i] == (byte)'\r')) {
                    return UNKNOWN_METHOD;
                }
                i++;
            }

            String headerName = new String(buf, 0, i);
            i++; // Over ':'
            while (buf[i] == ' ') {
                i++;
            }
            String headerValue = new String(buf, i, nread-1);

            headers.put(headerName, headerValue);
            return nread;
        }

        /**
         * Read all headers from the input stream
         * @param is Inputstream to read
         * @return number of bytes read
         */
        private int readHeaders(InputStream is) {
            int nread = 0;
            log("Read headers");
            // Headers should be terminated by empty CRLF line
            while (true) {
                int headerLen = 0;
                headerLen = parseHeader(is);
                if (headerLen == -1)
                    return -1;
                nread += headerLen;
                if (headerLen <= 2) {
                    return nread;
                }
            }
        }

        /**
         * Read content data from the input stream
         * @param is Inputstream to read
         * @return number of bytes read
         */
        private int readContent(InputStream is) {
            int nread = 0;
            log("Read content");
            String lengthString = headers.get(requestHeaders[REQ_CONTENT_LENGTH]);
            int length = new Integer(lengthString).intValue();

            // Read content
            length = readData(is, length);
            return length;
        }

        /**
         * The main loop, reading requests.
         */
        void handleClient() throws IOException {
            InputStream is = new BufferedInputStream(s.getInputStream());
            PrintStream ps = new PrintStream(s.getOutputStream());
            int nread = 0;

            /* we will only block in read for this many milliseconds
             * before we fail with java.io.InterruptedIOException,
             * at which point we will abandon the connection.
             */
            s.setSoTimeout(mTimeout);
            s.setTcpNoDelay(true);

            do {
                nread = parseStatusLine(is);
                if (requestMethod != UNKNOWN_METHOD) {

                    // If status line found, read any headers
                    nread = readHeaders(is);

                    // Then read content (if any)
                    // TODO handle chunked encoding from the client
                    if (headers.get(requestHeaders[REQ_CONTENT_LENGTH]) != null) {
                        nread = readContent(is);
                    }
                } else {
                    if (nread > 0) {
                        /* we don't support this method */
                        ps.print(HTTP_VERSION_STRING + " " + HTTP_BAD_METHOD +
                                 " unsupported method type: ");
                        ps.write(buf, 0, 5);
                        ps.write(EOL);
                        ps.flush();
                    } else {
                    }
                    if (!keepAlive || nread <= 0) {
                        headers.clear();
                        readStarted = false;

                        log("SOCKET CLOSED");
                        s.close();
                        return;
                    }
                }

                // Reset test number prior to outputing data
                testNum = -1;

                // Write out the data
                printStatus(ps);
                printHeaders(ps);

                // Write line between headers and body
                psWriteEOL(ps);

                // Write the body
                if (redirectCode == -1) {
                    switch (requestMethod) {
                        case GET_METHOD:
                            if ((testNum < -1) || (testNum > Support_TestWebData.tests.length - 1)) {
                                send404(ps);
                            } else {
                                sendFile(ps);
                            }
                            break;
                        case HEAD_METHOD:
                            // Nothing to do
                            break;
                        case POST_METHOD:
                            // Post method write body data
                            if ((testNum > 0) || (testNum < Support_TestWebData.tests.length - 1)) {
                                sendFile(ps);
                            }

                            break;
                        default:
                            break;
                    }
                } else { // Redirecting
                    switch (redirectCode) {
                        case 301:
                            // Seems 301 needs a body by neon (although spec
                            // says SHOULD).
                            psPrint(ps, Support_TestWebData.testServerResponse[Support_TestWebData.REDIRECT_301]);
                            break;
                        case 302:
                            //
                            psPrint(ps, Support_TestWebData.testServerResponse[Support_TestWebData.REDIRECT_302]);
                            break;
                        case 303:
                            psPrint(ps, Support_TestWebData.testServerResponse[Support_TestWebData.REDIRECT_303]);
                            break;
                        case 307:
                            psPrint(ps, Support_TestWebData.testServerResponse[Support_TestWebData.REDIRECT_307]);
                            break;
                        default:
                            break;
                    }
                }

                ps.flush();

                // Reset for next request
                readStarted = false;
                headers.clear();

            } while (keepAlive);

            log("SOCKET CLOSED");
            s.close();
        }

        // Print string to log and output stream
        void psPrint(PrintStream ps, String s) throws IOException {
            log(s);
            ps.print(s);
        }

        // Print bytes to log and output stream
        void psWrite(PrintStream ps, byte[] bytes, int len) throws IOException {
            log(new String(bytes));
            ps.write(bytes, 0, len);
        }

        // Print CRLF to log and output stream
        void psWriteEOL(PrintStream ps) throws IOException {
            log("CRLF");
            ps.write(EOL);
        }


        // Print status to log and output stream
        void printStatus(PrintStream ps) throws IOException {
            // Handle redirects first.
            if (redirectCode != -1) {
                log("REDIRECTING TO "+redirectHost+" status "+redirectCode);
                psPrint(ps, HTTP_VERSION_STRING + " " + redirectCode +" Moved permanently");
                psWriteEOL(ps);
                psPrint(ps, "Location: " + redirectHost);
                psWriteEOL(ps);
                return;
            }


            if (testID.startsWith("test")) {
                testNum = Integer.valueOf(testID.substring(4))-1;
            }

            if ((testNum < -1) || (testNum > Support_TestWebData.tests.length - 1)) {
                psPrint(ps, HTTP_VERSION_STRING + " " + HTTP_NOT_FOUND + " not found");
                psWriteEOL(ps);
            }  else {
                psPrint(ps, HTTP_VERSION_STRING + " " + HTTP_OK+" OK");
                psWriteEOL(ps);
            }

            log("Status sent");
        }
        /**
         * Create the server response and output to the stream
         * @param ps The PrintStream to output response headers and data to
         */
        void printHeaders(PrintStream ps) throws IOException {
            if ((testNum < -1) || (testNum > Support_TestWebData.tests.length - 1)) {
                // 404 status already sent
                return;
            }
            SimpleDateFormat df = new SimpleDateFormat("EE, dd MMM yyyy HH:mm:ss");

            psPrint(ps,"Server: TestWebServer"+mPort);
            psWriteEOL(ps);
            psPrint(ps, "Date: " + df.format(new Date()));
            psWriteEOL(ps);
            psPrint(ps, "Connection: " + ((keepAlive) ? "Keep-Alive" : "Close"));
            psWriteEOL(ps);

            // Yuk, if we're not redirecting, we add the file details
            if (redirectCode == -1) {

                if (testNum == -1) {
                    if (!Support_TestWebData.test0DataAvailable) {
                        log("testdata was not initilaized");
                        return;
                    }
                    if (chunked) {
                        psPrint(ps, "Transfer-Encoding: chunked");
                    } else {
                        psPrint(ps, "Content-length: "
                                + Support_TestWebData.test0Data.length);
                    }
                    psWriteEOL(ps);

                    psPrint(ps, "Last Modified: " + (new Date(
                            Support_TestWebData.test0Params.testLastModified)));
                    psWriteEOL(ps);

                    psPrint(ps, "Content-type: "
                            + Support_TestWebData.test0Params.testType);
                    psWriteEOL(ps);

                    if (Support_TestWebData.testParams[testNum].testExp > 0) {
                        long exp;
                        exp = Support_TestWebData.testParams[testNum].testExp;
                        psPrint(ps, "expires: "
                                + df.format(exp) + " GMT");
                        psWriteEOL(ps);
                    }
                } else if (!Support_TestWebData.testParams[testNum].testDir) {
                    if (chunked) {
                        psPrint(ps, "Transfer-Encoding: chunked");
                    } else {
                        psPrint(ps, "Content-length: "+Support_TestWebData.testParams[testNum].testLength);
                    }
                    psWriteEOL(ps);

                    psPrint(ps,"Last Modified: " + (new
                                                    Date(Support_TestWebData.testParams[testNum].testLastModified)));
                    psWriteEOL(ps);

                    psPrint(ps, "Content-type: " + Support_TestWebData.testParams[testNum].testType);
                    psWriteEOL(ps);

                    if (Support_TestWebData.testParams[testNum].testExp > 0) {
                        long exp;
                        exp = Support_TestWebData.testParams[testNum].testExp;
                        psPrint(ps, "expires: "
                                + df.format(exp) + " GMT");
                        psWriteEOL(ps);
                    }
                } else {
                    psPrint(ps, "Content-type: text/html");
                    psWriteEOL(ps);
                }
            } else {
                // Content-length of 301, 302, 303, 307 are the same.
                psPrint(ps, "Content-length: "+(Support_TestWebData.testServerResponse[Support_TestWebData.REDIRECT_301]).length());
                psWriteEOL(ps);
                psWriteEOL(ps);
            }
            log("Headers sent");

        }

        /**
         * Sends the 404 not found message
         * @param ps The PrintStream to write to
         */
        void send404(PrintStream ps) throws IOException {
            ps.println("Not Found\n\n"+
                       "The requested resource was not found.\n");
        }

        /**
         * Sends the data associated with the headers
         * @param ps The PrintStream to write to
         */
        void sendFile(PrintStream ps) throws IOException {
            // For now just make a chunk with the whole of the test data
            // It might be worth making this multiple chunks for large
            // test data to test multiple chunks.
            if (testNum == -1) {
                if (!Support_TestWebData.test0DataAvailable) {
                    log("testdata was not initilaized");
                    return;
                }
                int dataSize = Support_TestWebData.test0Data.length;
                if (chunked) {
                    psPrint(ps, Integer.toHexString(dataSize));
                    psWriteEOL(ps);
                    psWrite(ps, Support_TestWebData.test0Data, dataSize);
                    psWriteEOL(ps);
                    psPrint(ps, "0");
                    psWriteEOL(ps);
                    psWriteEOL(ps);
                } else {
                    psWrite(ps, Support_TestWebData.test0Data, dataSize);
                }
            } else {
                int dataSize = Support_TestWebData.tests[testNum].length;
                if (chunked) {
                    psPrint(ps, Integer.toHexString(dataSize));
                    psWriteEOL(ps);
                    psWrite(ps, Support_TestWebData.tests[testNum], dataSize);
                    psWriteEOL(ps);
                    psPrint(ps, "0");
                    psWriteEOL(ps);
                    psWriteEOL(ps);
                } else {
                    psWrite(ps, Support_TestWebData.tests[testNum], dataSize);
                }
            }
        }
    }
}
