<commit_before>package org.nikkii.embedhttp.impl;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.StringTokenizer;

import org.nikkii.embedhttp.HttpServer;
import org.nikkii.embedhttp.util.HttpUtil;
import org.nikkii.embedhttp.util.MultipartReader;

/**
 * Represents an Http Session
 * 
 * @author Nikki
 * 
 */
public class HttpSession implements Runnable {

	/**
	 * The HttpServer which this session belongs to
	 */
	private HttpServer server;

	/**
	 * The socket of the client
	 */
	private Socket socket;

	/**
	 * The InputStream of the socket
	 */
	private InputStream input;

	/**
	 * The OutputStream of the socket
	 */
	private OutputStream output;

	public HttpSession(HttpServer server, Socket socket) throws IOException {
		this.server = server;
		this.socket = socket;
		this.input = socket.getInputStream();
		this.output = socket.getOutputStream();
	}

	/**
	 * Parse the Http Request
	 */
	@Override
	public void run() {
		try {
			byte[] bytes = new byte[8192];

			int pos = 0;
			
			// Read the first part of the header
			while (true) {
				int read = input.read();
				if (read == -1) {
					break;
				}
				bytes[pos] = (byte) read;
				if (pos >= 4) {
					// Find \r\n\r\n
					if (bytes[pos - 3] == '\r' && bytes[pos - 2] == '\n' && bytes[pos - 1] == '\r' && bytes[pos] == '\n') {
						break;
					}
				}
				pos++;
			}

			// Read from the header data
			BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes, 0, pos)));

			// Read the first line, defined as the status line
			String l = reader.readLine();

			// Sanity check, after not returning data the client MIGHT attempt
			// to send something back and it will end up being something we
			// cannot read.
			if (l == null) {
				sendError(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.toString());
				return;
			}

			// Otherwise continue on
			int idx = l.indexOf(' ');

			// Split out the method and path
			HttpMethod method = HttpMethod.valueOf(l.substring(0, idx));

			// If it's an known method it won't be defined in the enum
			if (method == null) {
				sendError(HttpStatus.METHOD_NOT_ALLOWED, "This server currently does not support this method.");
				return;
			}

			// The URI
			String path = l.substring(idx + 1, l.lastIndexOf(' '));

			// Parse the headers
			Map<String, String> headers = new HashMap<String, String>();
			while ((l = reader.readLine()) != null) {
				// End header.
				if (l.equals(""))
					break;

				// Headers are usually Key: Value
				String key = l.substring(0, l.indexOf(':'));
				String value = l.substring(l.indexOf(':') + 1).trim();

				// Put the header in the map, correcting the header key if
				// needed.
				headers.put(HttpUtil.capitalizeHeader(key), value);
			}

			// Close the reader used for the header
			reader.close();

			HttpRequest request = new HttpRequest(this, method, path, headers);
			<commit_msg>Don't crash on unsupported Http method. Fixes #16<commit_after>package org.nikkii.embedhttp.impl;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.StringTokenizer;

import org.nikkii.embedhttp.HttpServer;
import org.nikkii.embedhttp.util.HttpUtil;
import org.nikkii.embedhttp.util.MultipartReader;

/**
 * Represents an Http Session
 * 
 * @author Nikki
 * 
 */
public class HttpSession implements Runnable {

	/**
	 * The HttpServer which this session belongs to
	 */
	private HttpServer server;

	/**
	 * The socket of the client
	 */
	private Socket socket;

	/**
	 * The InputStream of the socket
	 */
	private InputStream input;

	/**
	 * The OutputStream of the socket
	 */
	private OutputStream output;

	public HttpSession(HttpServer server, Socket socket) throws IOException {
		this.server = server;
		this.socket = socket;
		this.input = socket.getInputStream();
		this.output = socket.getOutputStream();
	}

	/**
	 * Parse the Http Request
	 */
	@Override
	public void run() {
		try {
			byte[] bytes = new byte[8192];

			int pos = 0;
			
			// Read the first part of the header
			while (true) {
				int read = input.read();
				if (read == -1) {
					break;
				}
				bytes[pos] = (byte) read;
				if (pos >= 4) {
					// Find \r\n\r\n
					if (bytes[pos - 3] == '\r' && bytes[pos - 2] == '\n' && bytes[pos - 1] == '\r' && bytes[pos] == '\n') {
						break;
					}
				}
				pos++;
			}

			// Read from the header data
			BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes, 0, pos)));

			// Read the first line, defined as the status line
			String l = reader.readLine();

			// Sanity check, after not returning data the client MIGHT attempt
			// to send something back and it will end up being something we
			// cannot read.
			if (l == null) {
				sendError(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.toString());
				return;
			}

			// Otherwise continue on
			int idx = l.indexOf(' ');

			// Split out the method and path
			String methodString = l.substring(0, idx);
			HttpMethod method = null;

			for (HttpMethod m : HttpMethod.values()) {
				if (m.name().equals(methodString)) {
					method = m;
				}
			}

			// If it's an known method it won't be defined in the enum
			if (method == null) {
				sendError(HttpStatus.METHOD_NOT_ALLOWED, "This server currently does not support this method.");
				return;
			}

			// The URI
			String path = l.substring(idx + 1, l.lastIndexOf(' '));

			// Parse the headers
			Map<String, String> headers = new HashMap<String, String>();
			while ((l = reader.readLine()) != null) {
				// End header.
				if (l.equals(""))
					break;

				// Headers are usually Key: Value
				String key = l.substring(0, l.indexOf(':'));
				String value = l.substring(l.indexOf(':') + 1).trim();

				// Put the header in the map, correcting the header key if
				// needed.
				headers.put(HttpUtil.capitalizeHeader(key), value);
			}

			// Close the reader used for the header
			reader.close();

			HttpRequest request = new HttpRequest(this, method, path, headers);
			
{'fraction_non_alphanumeric': 0.12716931602741724, 'fraction_numerical': 0.004666763890914394, 'mean_word_length': 3.019929660023447, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7056283', 'n_tokens_mistral': 2509, 'n_tokens_neox': 2091, 'n_words': 658}