[Примечание: код, написанный ниже, частично на основе имеющихся на образцах http://www.restlet.org]
HTTP 1.0 и 1.1 имеют заголовок с именем Content-Length
. Каким бы ни было числовое значение этого заголовка, это длина тела HTTP-ответа. Следуя шагу далее в HTTP 1.1, есть еще одно имя заголовка, Tranfer-Encoding: chunked
, которое указывает, что тело ответа делится на частей (куски), а длина каждой части указывается в строке непосредственно перед тем, как доставляется часть . (Я не включая другие значения Transfer-Encoding
держать этот ответ concised.)
Если это мой Restlet сервер:.
package restletapp;
import org.restlet.Component;
import org.restlet.data.Protocol;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
public class RestletApp extends ServerResource {
public static void main(String[] args) throws Exception {
Component component = new Component();
component.getServers().add(Protocol.HTTP, 8182);
component.getDefaultHost().attach("/trace", RestletApp.class);
component.start();
}
@Get
public String toAtGet() {
return "Resource URI : " + getReference() + '\n'
+ "Root URI : " + getRootRef() + '\n'
+ "Routed part : " + getReference().getBaseRef() + '\n'
+ "Remaining part: " + getReference().getRemainingPart()
;
}
}
И это мой клиент (написано с использованием сокетов в Java Просто посылает минимальный HTTP-запрос и печатает каждый символ ответа на консоли.)
package restletapp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Requester {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s=new Socket("localhost", 8182);
OutputStream os = s.getOutputStream();
os.write((
"GET /trace HTTP/1.1\r\n" //request
+ "host: localhost:8182\r\n" //request
+ "Connection-type: close\r\n\r\n" //request
).getBytes());
InputStream is = s.getInputStream();
for(int ch;(ch=is.read())!=-1;System.out.flush())
System.out.write(ch); //response, one char at a time.
is.close();
os.close();
s.close();
}
}
Клиентский процесс никогда не заканчивается. Но если я изменю свою клиентскую программу к этому:
package restletapp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Requester {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s=new Socket("localhost", 8182);
OutputStream os = s.getOutputStream();
os.write((
"GET /trace HTTP/1.1\r\n"
+ "host: localhost:8182\r\n"
+ "Connection-type: close\r\n\r\n"
).getBytes());
InputStream is = s.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
int bytesRead=0;
int contentLength=0;
//response headers.
for(String line;!(line=br.readLine()).isEmpty();System.out.flush()){
System.out.println(line);
String[] tokens = line.split(":| ");
if(tokens[0].equalsIgnoreCase("content-length")){
contentLength=Integer.parseInt(tokens[2]);
}
}
//response separator, between headers and body.
System.out.println();
//response body.
while(bytesRead<contentLength){
System.out.write(br.read());
System.out.flush();
bytesRead++;
}
is.close();
os.close();
s.close();
}
}
Во второй версии Requester
, вы можете увидеть, что соединение закрываются клиентом при content-length
-количества тела ответа о символах считываются.
Это то, что я получаю с помощью завиток:
command line $ curl -i "http://localhost:8182/trace"
HTTP/1.1 200 OK
Date: Fri, 14 Jun 2013 11:54:32 GMT
Server: Restlet-Framework/2.0.15
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Content-Length: 148
Content-Type: text/plain; charset=UTF-8
Resource URI : http://localhost:8182/trace
Root URI : http://localhost:8182/trace
Routed part : http://localhost:8182/trace
Remaining part:
command line $
Вы можете видеть, что локон выходит после прочтения содержания.