I’m stuck on Stage #QC6.
I’ve tried debugging by seeing what the file path is when creating a file and seeing where the code halts. I believe the file path is correct after checking with other code examples.
Here are my logs:
remote: [compile] Compilation successful.
remote:
remote: [tester::#QV8] Running tests for Stage #QV8 (Read request body)
remote: [tester::#QV8] $ ./your_program.sh --directory /tmp/data/codecrafters.io/http-server-tester/
remote: [your_program] Logs from your program will appear here!
remote: [tester::#QV8] $ curl -v -X POST http://localhost:4221/files/pear_orange_grape_pear -H “Content-Leth: 64” -H “Content-Type: application/octet-stream” -d ‘pineapple blueberry apple grape pineapple blueberrgrape banana’
remote: [your_program] accepted new connection
remote: [tester::#QV8] Failed to read response:
remote: [tester::#QV8] Received: “” (no content received)
remote: [tester::#QV8] ^ error
remote: [tester::#QV8] Error: Expected: HTTP-version, Received: “”
remote: [tester::#QV8] Test failed (try setting ‘debug: true’ in your l to see more details
remote: [your_program] String:POST /files/pear_orange_grape_pear HTTP/1.1Host: localhost:4221Content-Lengt 64Content-Type: application/octet-streampineapple blueberry apple grape pineapple blueberry grape banana
remote: [your_program] body: pineapple blueberry apple grape pineapple blueberry grape banana
remote:
remote: Try our CLI to run tests faster without Git:
remote:
remote: View our article on debugging test failures:
remote:
And here’s my code:
java
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.;
import javax.management.RuntimeErrorException;
import java.io.;
import java.nio.file.*;;
public class Main {
private final int port;
private final ExecutorService executorService;
private final String directory;
public Main(int port, int concurrency,String directory)
{
this.port = port;
this.executorService = Executors.newFixedThreadPool(concurrency);
this.directory = directory;
}
public void run()
{
System.out.println(“Logs from your program will appear here!”);
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
// Since the tester restarts your program quite often, setting SO_REUSEADDR
// ensures that we don't run into 'Address already in use' errors
serverSocket.setReuseAddress(true);
//receive connection
while(true){
final Socket clientSocket = serverSocket.accept(); // Wait for connection from client.
System.out.println("accepted new connection");
//handle request
executorService.submit(() -> handleReq(clientSocket));
//response
}
} catch (IOException e) {
System.out.println("IOException: " + e.getMessage());
}
}
private void handleReq(Socket clientSocket)
{
try{
final InputStream input = clientSocket.getInputStream();
boolean gotFile = false;
byte[] fileBytes = null;
final OutputStream outputStream = clientSocket.getOutputStream();
final InputStreamReader reade = new InputStreamReader(input);
final BufferedReader reader = new BufferedReader(reade);
int l = 0;
//System.out.println(reader.readLine());
String s = reader.readLine();
while(reader.ready())
{
s+=reader.readLine();
}
System.out.println("String:" + s);
String outString = "HTTP/1.1 404 Not Found\r\n\r\n";
//System.out.println(s.substring(0,4));
if(s.substring(0, 4).equalsIgnoreCase("POST"))//read and write data sent to server
{
String body = s.substring(s.indexOf("application/octet-stream")+24);
System.out.println("body: " + body);
System.out.println(directory+"/"+s.substring(12, s.substring(12).indexOf(" ")+12));
String fileName = directory+"/"+s.substring(12, s.substring(12).indexOf(" ")+12);
System.out.println(fileName);
File file = new File(fileName);
if (file.createNewFile()) {
System.out.println("created");
FileWriter fileWriter = new FileWriter(file);
fileWriter.write(body);
fileWriter.close();
System.out.println("finished file creation");
outputStream.write("HTTP/1.1 201 Created\r\n\r\n".getBytes());}
else
outputStream.write("HTTP/1.1 404 Not Found\r\n\r\n".getBytes());
outputStream.flush();
outputStream.close();
return;
}
else if(s.charAt(5)==' ') // / url path
outString = "HTTP/1.1 200 OK\r\n\r\n";
else if(s.substring(5, 9).equals("echo")) //echo string
{
String echoString ="";
for(int i = 10; i<s.length(); i++)
{
if(s.charAt(i)==' ')
break;
echoString+=s.charAt(i);
}
System.out.println(echoString);
outString = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: "+echoString.length()+"\r\n\r\n" + echoString;
}
else if(s.substring(5, 15).equals("user-agent")) //user-agent header
{
String headerString = "";
int startIndex = s.indexOf("User-Agent:");
for(int i = startIndex+12; i<s.length(); i++)
{
if(s.charAt(i)=='\r')
break;
headerString+=s.charAt(i);
//System.out.println(s.charAt(i)); //for debugging
}
System.out.println(headerString);
System.out.println(headerString.length());
outString = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: "+headerString.length()+"\r\n\r\n"+headerString ;
}
else if(s.substring(5, 10).equals("files")) //files header
{
//get file name
String fileString = "";
int startIndex = s.indexOf("/files/");
for(int i = startIndex+7; i<s.length(); i++)
{
if(s.charAt(i)==' ')
break;
fileString+=s.charAt(i);
//System.out.println(s.charAt(i));
}
//get file path
Path filePath = Paths.get(directory, fileString);
System.out.println(directory+fileString);
if(Files.exists(filePath ))
{
gotFile = true;
fileBytes = Files.readAllBytes(filePath);
outString = "HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nContent-Length: "+fileBytes.length+"\r\n\r\n" ;
}
else
{
outString = "HTTP/1.1 404 Not Found\r\n\r\n";
}
System.out.println(fileString);
System.out.println(fileString.length());
}
System.out.println(l);
System.out.println("outstrinf: " + outString);
outputStream.write(outString.getBytes());
if(gotFile)
outputStream.write(fileBytes);
//outputStream.flush();
}
catch(IOException e)
{
throw new RuntimeException(e);
}
}
public static void main(String args) {
// You can use print statements as follows for debugging, they’ll be visible when running tests.
String directory = null;
if(args.length==2 && args[0].equalsIgnoreCase(“–directory”))
directory = args[1];
Main server = new Main(4221,10,directory);
server.run();
}
}