Mercurial Hosting > luan
annotate src/goodjava/webserver/Connection.java @ 1738:9713f7fd50b3
server-sent events
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 03 Nov 2022 19:23:53 -0600 |
parents | a02a75e3daa8 |
children | c7b3c327248a |
rev | line source |
---|---|
1402
27efb1fcbcb5
move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents:
1347
diff
changeset
|
1 package goodjava.webserver; |
1137 | 2 |
3 import java.io.InputStream; | |
4 import java.io.OutputStream; | |
5 import java.io.IOException; | |
6 import java.net.Socket; | |
1402
27efb1fcbcb5
move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents:
1347
diff
changeset
|
7 import goodjava.logging.Logger; |
27efb1fcbcb5
move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents:
1347
diff
changeset
|
8 import goodjava.logging.LoggerFactory; |
27efb1fcbcb5
move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents:
1347
diff
changeset
|
9 import goodjava.parser.ParseException; |
1493 | 10 import goodjava.io.IoUtils; |
1137 | 11 |
12 | |
13 final class Connection { | |
14 private static final Logger logger = LoggerFactory.getLogger(Connection.class); | |
15 | |
1142
0f59eab45f3d
webserver - threading
Franklin Schmidt <fschmidt@gmail.com>
parents:
1138
diff
changeset
|
16 static void handle(Server server,Socket socket) { |
0f59eab45f3d
webserver - threading
Franklin Schmidt <fschmidt@gmail.com>
parents:
1138
diff
changeset
|
17 new Connection(server,socket).handle(); |
0f59eab45f3d
webserver - threading
Franklin Schmidt <fschmidt@gmail.com>
parents:
1138
diff
changeset
|
18 } |
0f59eab45f3d
webserver - threading
Franklin Schmidt <fschmidt@gmail.com>
parents:
1138
diff
changeset
|
19 |
1137 | 20 private final Server server; |
21 private final Socket socket; | |
22 | |
1142
0f59eab45f3d
webserver - threading
Franklin Schmidt <fschmidt@gmail.com>
parents:
1138
diff
changeset
|
23 private Connection(Server server,Socket socket) { |
1137 | 24 this.server = server; |
25 this.socket = socket; | |
26 } | |
27 | |
28 private void handle() { | |
1736
a02a75e3daa8
webserver error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
1607
diff
changeset
|
29 String rawHead = ""; |
1137 | 30 try { |
1144
ae0a048f3bc7
webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents:
1142
diff
changeset
|
31 Request request = new Request(); |
1194
bd0420fb3dd0
handle ParseException in webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
1162
diff
changeset
|
32 Response response; |
1513 | 33 String contentType = null; |
1194
bd0420fb3dd0
handle ParseException in webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
1162
diff
changeset
|
34 try { |
1738 | 35 InputStream in = socket.getInputStream(); |
36 byte[] a = new byte[8192]; | |
37 int endOfHeader; | |
38 int size = 0; | |
39 int left = a.length; | |
40 outer: while(true) { | |
41 int n = in.read(a,size,left); | |
42 if( n == -1 ) { | |
43 if( size == 0 ) { | |
44 socket.close(); | |
45 return; | |
46 } | |
47 throw new IOException("unexpected end of input at "+size); | |
48 } | |
49 size += n; | |
50 for( int i=0; i<=size-4; i++ ) { | |
51 if( a[i]=='\r' && a[i+1]=='\n' && a[i+2]=='\r' && a[i+3]=='\n' ) { | |
52 endOfHeader = i + 4; | |
53 break outer; | |
54 } | |
55 } | |
56 left -= n; | |
57 if( left == 0 ) { | |
58 byte[] a2 = new byte[2*a.length]; | |
59 System.arraycopy(a,0,a2,0,size); | |
60 a = a2; | |
61 left = a.length - size; | |
62 } | |
63 } | |
64 rawHead = new String(a,0,endOfHeader); | |
65 //System.out.println(rawHead); | |
66 request.rawHead = rawHead; | |
67 RequestParser parser = new RequestParser(request); | |
68 parser.parseHead(); | |
69 | |
70 String lenStr = (String)request.headers.get("content-length"); | |
71 if( lenStr != null ) { | |
72 int len = Integer.parseInt(lenStr); | |
73 byte[] body = new byte[len]; | |
74 size -= endOfHeader; | |
75 System.arraycopy(a,endOfHeader,body,0,size); | |
76 while( size < len ) { | |
77 int n = in.read(body,size,len-size); | |
1144
ae0a048f3bc7
webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents:
1142
diff
changeset
|
78 if( n == -1 ) { |
ae0a048f3bc7
webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents:
1142
diff
changeset
|
79 throw new IOException("unexpected end of input at "+size); |
ae0a048f3bc7
webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents:
1142
diff
changeset
|
80 } |
ae0a048f3bc7
webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents:
1142
diff
changeset
|
81 size += n; |
ae0a048f3bc7
webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents:
1142
diff
changeset
|
82 } |
1738 | 83 request.body = body; |
84 //System.out.println(new String(request.body)); | |
85 } | |
86 | |
87 contentType = (String)request.headers.get("content-type"); | |
88 if( contentType != null ) { | |
89 contentType = contentType.toLowerCase(); | |
90 if( contentType.equals("application/x-www-form-urlencoded") ) { | |
91 parser.parseUrlencoded(null); | |
92 } else if( contentType.equals("application/x-www-form-urlencoded; charset=utf-8") ) { | |
93 parser.parseUrlencoded("utf-8"); | |
94 } else if( contentType.startsWith("multipart/form-data;") ) { | |
95 parser.parseMultipart(); | |
96 } else if( contentType.equals("application/json") ) { | |
97 parser.parseJson(null); | |
98 } else if( contentType.equals("application/json; charset=utf-8") ) { | |
99 parser.parseJson("utf-8"); | |
100 } else { | |
101 logger.info("unknown request content-type: "+contentType); | |
1194
bd0420fb3dd0
handle ParseException in webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
1162
diff
changeset
|
102 } |
1738 | 103 } |
104 | |
105 String scheme = (String)request.headers.get("x-forwarded-proto"); | |
106 if( scheme != null ) | |
107 request.scheme = scheme; | |
1237 | 108 |
1738 | 109 if( "text/event-stream".equals(request.headers.get("accept")) ) { |
110 ServerSentEvents.add(socket,request); | |
111 return; | |
1137 | 112 } |
1738 | 113 |
1194
bd0420fb3dd0
handle ParseException in webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
1162
diff
changeset
|
114 response = server.handler.handle(request); |
bd0420fb3dd0
handle ParseException in webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
1162
diff
changeset
|
115 } catch(ParseException e) { |
1229 | 116 logger.warn("parse error\n"+request.rawHead.trim()+"\n",e); |
1513 | 117 String msg = e.toString(); |
118 if( contentType != null ) | |
119 msg = "invalid content for content-type " + contentType + "\n" + msg; | |
120 response = Response.errorResponse(Status.BAD_REQUEST,msg); | |
1137 | 121 } |
1607 | 122 response.headers.put("Connection","close"); |
123 response.headers.put("Content-Length",Long.toString(response.body.length)); | |
1137 | 124 byte[] header = response.toHeaderString().getBytes(); |
125 | |
126 OutputStream out = socket.getOutputStream(); | |
127 out.write(header); | |
1493 | 128 IoUtils.copyAll(response.body.content,out); |
1137 | 129 out.close(); |
130 socket.close(); | |
131 } catch(IOException e) { | |
1736
a02a75e3daa8
webserver error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
1607
diff
changeset
|
132 logger.info(rawHead.trim()+"\n",e); |
a02a75e3daa8
webserver error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
1607
diff
changeset
|
133 } catch(RuntimeException e) { |
a02a75e3daa8
webserver error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
1607
diff
changeset
|
134 logger.error(rawHead.trim()+"\n",e); |
a02a75e3daa8
webserver error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
1607
diff
changeset
|
135 throw e; |
1137 | 136 } |
137 } | |
138 | |
139 } |