好吧,所以我有一个非常基本的http服务器,它实现了http 1.0,并且它的功能完美,除了一个巨大的缺陷,当返回一个zip文件或者似乎任何压缩格式时,都存在数据损坏。令我困惑的是,当我在HeaderHandler类中调用writerHeader()方法时,只有腐败,所以当我不调用此方法,只返回请求而不向客户端发送响应头时,所有数据都完好无损和功能。另一个令人困惑的方面是,当我将损坏文件的大小与良好文件的大小进行比较时,它们都完全相同,直到最后一个字节。
package com.tinyhttp.core;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
import java.nio.file.Files;
public class Connection implements Runnable{//soon try to implement http 1.1
private Socket sock;
private BufferedReader in;
private HeaderHandler handler;
private OutputStream out;
public static final String DEFAULT_FILE = "test.zip";
public Connection(Socket sock){
this.sock = sock;
try{
out = sock.getOutputStream();
}catch(IOException e){
}
}
public void run(){
ReceiveRequest();
if(sock.isClosed())
return;
RequestHandel();
}
private void RequestHandel(){
if(handler.getMethod().equals("GET")){
File file = new File(handler.getRequest());
if(file.exists()){
try {
handler.writeHeader(out, file.length(), "200 OK", Files.probeContentType(file.toPath()));
} catch (IOException e) {
e.printStackTrace();
}
ReturnFile(handler.getRequest());
}else if(file.toString().equals("") || file.toString().equals("/")){
try {
handler.writeHeader(out, file.length(), "200 OK", Files.probeContentType(new File(DEFAULT_FILE).toPath()));//works without this line...
ReturnFile(DEFAULT_FILE);
} catch (IOException e) {
e.printStackTrace();
}
}
else{
returnNotFound();
System.out.println("404 NOT FOUND");
}
}
else
ReturnNotImplemented();
close();
}
private void ReceiveRequest(){
try {
handler = new HeaderHandler();
in = new BufferedReader(new InputStreamReader(sock.getInputStream(), "UTF-8"));
String line;
try{
while(!(line = in.readLine()).equals("")){
handler.append(line);
}
}catch(NullPointerException a){
close();
}
}catch (IOException e) {
e.printStackTrace();
}
System.out.println(sock.getInetAddress() + ":\n" + handler.getRequestLine());
}
private void ReturnFile(String req){
FileInputStream in = null;
try {
in = new FileInputStream(req);
} catch (FileNotFoundException e) {
System.out.println("The file " + req +" was not found");
return;
}
try {
byte[] buff = new byte[64*1024];
for(int read; (read = in.read(buff)) > -1;)
out.write(buff, 0, read);;
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public void close(){
try {
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void returnNotFound(){
try {
Writer out = new OutputStreamWriter(this.out, "UTF-8");
out.write("HTTP/1.1 404 NOT FOUND\n\rServer: " + Init.SERVER_ID + "\n\r\n\r");
out.write("<!DOCTYPE html>\n<html>\n<body>\n<h1>404 NOT FOUND</h1>" + handler.returnRawHead() + "\n</body>\n</html>");
close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void ReturnNotImplemented(){
Writer out = null;
try {
out = new OutputStreamWriter(this.out, "UTF-8");
out.write("HTTP/1.1 501 Not Implemented\n\rServer: " + Init.SERVER_ID + "\n\r\n\r");
out.write("<!DOCTYPE html>\n<html>\n<body>\n<h1>501 NOT IMPLEMENTED</h1>" + handler.returnRawHead() + "\n</body>\n</html>");
out.flush();
close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
和处理程序......
package com.tinyhttp.core;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HeaderHandler {
private ArrayList<String> list = new ArrayList<String>();
private String[] sortedheader;
public void append(String line){
list.add(line);
}
private void storeLine(){
sortedheader = new String[list.size()];
sortedheader = list.toArray(sortedheader);
}
public String getRequestLine(){
if(sortedheader == null)
storeLine();
try{
return sortedheader[0];
}catch(ArrayIndexOutOfBoundsException e){
}
return null;
}
public String getFileExtension(String file){
Pattern pat = Pattern.compile("\\..*\\z");
Matcher mat = pat.matcher(file);
mat.find();
try{
return mat.group().substring(1);
}catch(IllegalStateException e){
}
return null;
}
public String getConnectionType(){
if(sortedheader == null)
storeLine();
String headerstring = null;
for(int i = 0; i < sortedheader.length; i++){
Pattern pat = Pattern.compile("[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]");
Matcher mat = pat.matcher(sortedheader[i]);
mat.find();
try{
mat.group();
headerstring = sortedheader[i];
break;
}catch(IllegalStateException e){
}
}
return headerstring.substring(11).trim();
}
public float checkVersion(){
if(sortedheader == null)
storeLine();
String line;
try{
line = sortedheader[0];
}catch(ArrayIndexOutOfBoundsException e){
return -1;
}
Pattern pat = Pattern.compile("\\d\\.\\d");
Matcher mat = pat.matcher(line);
mat.find();
return Float.parseFloat(mat.group());
}
public String returnRawHead(){
if(sortedheader == null) storeLine();
StringBuilder sb = new StringBuilder("");
for(int i = 0; i < sortedheader.length; i++){
sb.append(sortedheader[i] + "\n");
}
return sb.toString();
}
public void writeHeader(OutputStream out, long length, String responsecode, String type){
Writer writer = null;
try {
writer = new OutputStreamWriter(out, "UTF-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
try{
writer.write("HTTP/" + Init.HTTP_IMPLEMENTATION + " " + responsecode + "\n\r");
writer.write("Content-Length: " + length + "\n\r");
writer.write("Server: " + Init.SERVER_ID + "\n\r");
writer.write("Content-Type: " + type + "\n\r");
writer.write("Connection: " + Init.CONNECTION_TYPE + "\n\r");//getting odd results wiv the flushing
writer.flush();
}catch(IOException e){
e.printStackTrace();
}
}
public String getMethod(){
if(sortedheader == null)
storeLine();
Pattern pat = Pattern.compile("[A-Z]{3,6}\\s");
Matcher mat = pat.matcher(sortedheader[0]);
mat.find();
String fin = mat.group();
return fin.substring(0, (fin.length() - 1));
}
public String getRequest(){
if(sortedheader == null)
storeLine();
Pattern pat = Pattern.compile("/.*\\s");
Matcher mat = pat.matcher(sortedheader[0]);
mat.find();
String req = mat.group();
return req.substring(1, (req.length() - 1));
}
public void printProcessed(){
if(sortedheader == null) storeLine();
for(int i = 0; i < sortedheader.length; i++){
System.out.println(sortedheader[i]);
}
}
}
感谢任何帮助,杰克