<commit_before>/*
 * Zed Attack Proxy (ZAP) and its related class files.
 *
 * ZAP is an HTTP/HTTPS proxy for assessing web application security.
 *
 * Copyright 2018 The ZAP Development Team
 *
 * 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 org.zaproxy.zap.testutils.websocket.server;

import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.NanoWSD;
import fi.iki.elonen.NanoWSD.WebSocketFrame;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.Timer;
import java.util.TimerTask;

/** Represent a WebSocket Test connection. */
public class NanoWebSocketConnection extends NanoWSD.WebSocket {

    private static final String CLOSE_PAYLOAD = "Connection Closed";
    private static final String CLOSE_FROM_PING = "No ping response";
    private byte[] pingPayload;
    private Scheduling scheduling;
    private boolean pongReceived = true;
    private Stack<WebSocketFrame> incomingMessages;
    private Stack<WebSocketFrame> outgoingMessages;
    private WebSocketFrameListener incomingListener;

    public NanoWebSocketConnection(NanoHTTPD.IHTTPSession handshakeRequest) {
        super(handshakeRequest);
        incomingMessages = new Stack<>();
        outgoingMessages = new Stack<>();
    }

    /**
     * Set up a ping Schedule.
     *
     * @param pingInterval how often in milliseconds send ping message.
     * @param pingPayload the ping message.
     */
    public void setPingScheduling(int pingInterval, byte[] pingPayload) {
        scheduling = new Scheduling();
        this.pingPayload = pingPayload;
        scheduling.pingScheduling(pingInterval);
    }

    protected synchronized boolean isPongReceived() {
        return pongReceived;
    }

    protected synchronized void setPongReceived(boolean pongReceived) {
        this.pongReceived = pongReceived;
    }

    /**
     * Sends a ping message to the client. Ping payload defined by {@link
     * NanoWebSocketConnection#setPingMessage(byte[])}
     */
    protected boolean ping() {
        try {
            if (isPongReceived()) {
                super.ping(pingPayload);
                setPongReceived(false);
            } else {
                onClose(WebSocketFrame.CloseCode.AbnormalClosure, CLOSE_FROM_PING, false);
            }
        } catch (IOException e) {
            e.printStackTrace();
            onClose(WebSocketFrame.CloseCode.AbnormalClosure, CLOSE_PAYLOAD, false);
            return false;
        }
        return true;
    }

    @Override
    protected void onOpen() {}

    @Override
    protected void onClose(WebSocketFrame.CloseCode closeCode, String s, boolean b) {}<commit_msg>testutils: sync ping in WebSocket test server<commit_after>/*
 * Zed Attack Proxy (ZAP) and its related class files.
 *
 * ZAP is an HTTP/HTTPS proxy for assessing web application security.
 *
 * Copyright 2018 The ZAP Development Team
 *
 * 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 org.zaproxy.zap.testutils.websocket.server;

import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.NanoWSD;
import fi.iki.elonen.NanoWSD.WebSocketFrame;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.Timer;
import java.util.TimerTask;

/** Represent a WebSocket Test connection. */
public class NanoWebSocketConnection extends NanoWSD.WebSocket {

    private static final String CLOSE_PAYLOAD = "Connection Closed";
    private static final String CLOSE_FROM_PING = "No ping response";
    private byte[] pingPayload;
    private Scheduling scheduling;
    private boolean pongReceived = true;
    private Stack<WebSocketFrame> incomingMessages;
    private Stack<WebSocketFrame> outgoingMessages;
    private WebSocketFrameListener incomingListener;

    public NanoWebSocketConnection(NanoHTTPD.IHTTPSession handshakeRequest) {
        super(handshakeRequest);
        incomingMessages = new Stack<>();
        outgoingMessages = new Stack<>();
    }

    /**
     * Set up a ping Schedule.
     *
     * @param pingInterval how often in milliseconds send ping message.
     * @param pingPayload the ping message.
     */
    public void setPingScheduling(int pingInterval, byte[] pingPayload) {
        scheduling = new Scheduling();
        this.pingPayload = pingPayload;
        scheduling.pingScheduling(pingInterval);
    }

    protected synchronized boolean isPongReceived() {
        return pongReceived;
    }

    protected synchronized void setPongReceived(boolean pongReceived) {
        this.pongReceived = pongReceived;
    }

    /**
     * Sends a ping message to the client. Ping payload defined by {@link
     * NanoWebSocketConnection#setPingMessage(byte[])}
     */
    protected synchronized boolean ping() {
        try {
            if (isPongReceived()) {
                super.ping(pingPayload);
                setPongReceived(false);
            } else {
                onClose(WebSocketFrame.CloseCode.AbnormalClosure, CLOSE_FROM_PING, false);
            }
        } catch (IOException e) {
            e.printStackTrace();
            onClose(WebSocketFrame.CloseCode.AbnormalClosure, CLOSE_PAYLOAD, false);
            return false;
        }
        return true;
    }

    @Override
    protected void onOpen() {}

    @Override
    protected void onClose(WebSocketFrame.CloseCode closeCode, String s, boolean b) {}
{'fraction_non_alphanumeric': 0.0802555711391616, 'fraction_numerical': 0.0024933769674302633, 'mean_word_length': 3.0931122448979593, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6277511', 'n_tokens_mistral': 1782, 'n_tokens_neox': 1694, 'n_words': 549}