1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.ByteBufUtil;
20 import io.netty.util.CharsetUtil;
21
22 import static io.netty.handler.codec.http.HttpConstants.SP;
23
24
25
26
27
28 public class HttpRequestEncoder extends HttpObjectEncoder<HttpRequest> {
29 private static final char SLASH = '/';
30 private static final char QUESTION_MARK = '?';
31 private static final int SLASH_AND_SPACE_SHORT = (SLASH << 8) | SP;
32 private static final int SPACE_SLASH_AND_SPACE_MEDIUM = (SP << 16) | SLASH_AND_SPACE_SHORT;
33
34 @Override
35 public boolean acceptOutboundMessage(Object msg) throws Exception {
36 return super.acceptOutboundMessage(msg) && !(msg instanceof HttpResponse);
37 }
38
39 @Override
40 protected void encodeInitialLine(ByteBuf buf, HttpRequest request) throws Exception {
41 ByteBufUtil.copy(request.method().asciiName(), buf);
42
43 String uri = request.uri();
44
45 if (uri.isEmpty()) {
46
47
48 ByteBufUtil.writeMediumBE(buf, SPACE_SLASH_AND_SPACE_MEDIUM);
49 } else {
50 CharSequence uriCharSequence = uri;
51 boolean needSlash = false;
52 int start = uri.indexOf("://");
53 if (start != -1 && uri.charAt(0) != SLASH) {
54 start += 3;
55
56
57 int index = uri.indexOf(QUESTION_MARK, start);
58 if (index == -1) {
59 if (uri.lastIndexOf(SLASH) < start) {
60 needSlash = true;
61 }
62 } else {
63 if (uri.lastIndexOf(SLASH, index) < start) {
64 uriCharSequence = new StringBuilder(uri).insert(index, SLASH);
65 }
66 }
67 }
68 buf.writeByte(SP).writeCharSequence(uriCharSequence, CharsetUtil.UTF_8);
69 if (needSlash) {
70
71 ByteBufUtil.writeShortBE(buf, SLASH_AND_SPACE_SHORT);
72 } else {
73 buf.writeByte(SP);
74 }
75 }
76
77 request.protocolVersion().encode(buf);
78 ByteBufUtil.writeShortBE(buf, CRLF_SHORT);
79 }
80 }