|
13 | 13 | import net.tootallnate.websocket.Handshakedata; |
14 | 14 | import net.tootallnate.websocket.HandshakedataImpl1; |
15 | 15 | import net.tootallnate.websocket.WebSocket; |
| 16 | +import net.tootallnate.websocket.exeptions.InvalidHandshakeException; |
16 | 17 |
|
17 | 18 | public class Draft_76 extends Draft_75 { |
18 | 19 |
|
19 | 20 | @Override |
20 | 21 | public boolean acceptHandshakeAsClient( Handshakedata request , Handshakedata response ) { |
21 | | - if( response.getContent ().length >= 20 && new String ( response.getContent () ).endsWith ( "\r\n\r\n" )){ |
22 | | - /*{ //TODO finish function |
23 | | - if ( reply == null ) { |
24 | | - return false; |
25 | | - } |
26 | | - byte[] challenge = new byte[] { |
27 | | - (byte)( this.number1 >> 24 ), |
28 | | - (byte)( (this.number1 << 8) >> 24 ), |
29 | | - (byte)( (this.number1 << 16) >> 24 ), |
30 | | - (byte)( (this.number1 << 24) >> 24 ), |
31 | | - (byte)( this.number2 >> 24 ), |
32 | | - (byte)( (this.number2 << 8) >> 24 ), |
33 | | - (byte)( (this.number2 << 16) >> 24 ), |
34 | | - (byte)( (this.number2 << 24) >> 24 ), |
35 | | - this.key3[0], |
36 | | - this.key3[1], |
37 | | - this.key3[2], |
38 | | - this.key3[3], |
39 | | - this.key3[4], |
40 | | - this.key3[5], |
41 | | - this.key3[6], |
42 | | - this.key3[7] |
43 | | - }; |
44 | | - MessageDigest md5; |
45 | | - try { |
46 | | - md5 = MessageDigest.getInstance( "MD5" ); |
47 | | - } catch ( NoSuchAlgorithmException e ) { |
48 | | - throw new RuntimeException ( e );//Will never occur on a valid jre. |
49 | | - } |
50 | | - byte[] expected = md5.digest(challenge); |
51 | | - for (int i = 0; i < reply.length; i++) { |
52 | | - if (expected[i] != reply[i]) { |
53 | | - return false; |
54 | | - } |
55 | | - } |
56 | | - }*/ |
57 | | - return true; |
58 | | - } |
59 | | - return false; |
| 22 | + return super.acceptHandshakeAsClient( request , response );//TODO validate the handshake |
60 | 23 | } |
61 | 24 |
|
62 | 25 | @Override |
63 | 26 | public boolean acceptHandshakeAsServer( Handshakedata handshakedata ) { |
64 | 27 |
|
65 | | - if( handshakedata.getFieldValue ( "Sec-WebSocket-Key1" ).equals ( "8" ) && new String ( handshakedata.getContent () ).endsWith ( "\r\n\r\n" )) |
| 28 | + if( !handshakedata.getFieldValue ( "Sec-WebSocket-Key1" ).isEmpty() |
| 29 | + && !handshakedata.getFieldValue ( "Sec-WebSocket-Key1" ).isEmpty() |
| 30 | + /*new String ( handshakedata.getContent () ).endsWith ( "\r\n\r\n" )*/) |
66 | 31 | return true; |
67 | 32 | return false; |
68 | 33 | } |
@@ -101,14 +66,69 @@ private String generateKey() { |
101 | 66 | public HandshakeBuilder postProcessHandshakeRequestAsClient( HandshakeBuilder request ) { |
102 | 67 | request.put ( "Sec-WebSocket-Key1" , this.generateKey() ); |
103 | 68 | request.put ( "Sec-WebSocket-Key2" , this.generateKey() ); |
| 69 | + byte[] key3 = new byte[8]; |
| 70 | + (new Random()).nextBytes( key3 ); |
| 71 | + request.setContent( key3 ); |
104 | 72 | return request; |
105 | 73 |
|
106 | 74 | } |
107 | | - |
108 | | - |
109 | 75 |
|
110 | 76 | @Override |
111 | | - public HandshakeBuilder postProcessHandshakeResponseAsServer( Handshakedata response , HandshakeBuilder request ) { |
112 | | - throw new RuntimeException ( "not yet implemented" ); |
| 77 | + public HandshakeBuilder postProcessHandshakeResponseAsServer( Handshakedata request , HandshakeBuilder response ) throws InvalidHandshakeException { |
| 78 | + super.postProcessHandshakeResponseAsServer( request , response ); |
| 79 | + String key1 = request.getFieldValue("Sec-WebSocket-Key1"); |
| 80 | + String key2 = request.getFieldValue("Sec-WebSocket-Key2"); |
| 81 | + byte[] key3 = request.getContent(); |
| 82 | + if (key1 == null || key2 == null || key3 == null || key3.length != 8) { |
| 83 | + throw new InvalidHandshakeException("Bad keys"); |
| 84 | + } |
| 85 | + response.setContent( createChallenge( key1 , key2 , key3 ) ); |
| 86 | + return response; |
| 87 | + } |
| 88 | + |
| 89 | + private static byte[] getPart(String key) throws InvalidHandshakeException { |
| 90 | + try { |
| 91 | + long keyNumber = Long.parseLong(key.replaceAll("[^0-9]","")); |
| 92 | + long keySpace = key.split("\u0020").length - 1; |
| 93 | + long part = new Long(keyNumber / keySpace); |
| 94 | + return new byte[] { |
| 95 | + (byte)( part >> 24 ), |
| 96 | + (byte)( (part << 8) >> 24 ), |
| 97 | + (byte)( (part << 16) >> 24 ), |
| 98 | + (byte)( (part << 24) >> 24 ) |
| 99 | + }; |
| 100 | + } catch ( NumberFormatException e ) { |
| 101 | + throw new InvalidHandshakeException("invalid Sec-WebSocket-Key (/key2/ or /key3/)"); |
| 102 | + } |
| 103 | + } |
| 104 | + |
| 105 | + |
| 106 | + public static byte[] createChallenge( String key1 , String key2, byte[] key3 ) throws InvalidHandshakeException{ |
| 107 | + byte[] part1 = getPart(key1); |
| 108 | + byte[] part2 = getPart(key2); |
| 109 | + byte[] challenge = new byte[16]; |
| 110 | + challenge[0] = part1[0]; |
| 111 | + challenge[1] = part1[1]; |
| 112 | + challenge[2] = part1[2]; |
| 113 | + challenge[3] = part1[3]; |
| 114 | + challenge[4] = part2[0]; |
| 115 | + challenge[5] = part2[1]; |
| 116 | + challenge[6] = part2[2]; |
| 117 | + challenge[7] = part2[3]; |
| 118 | + challenge[8] = key3[0]; |
| 119 | + challenge[9] = key3[1]; |
| 120 | + challenge[10] = key3[2]; |
| 121 | + challenge[11] = key3[3]; |
| 122 | + challenge[12] = key3[4]; |
| 123 | + challenge[13] = key3[5]; |
| 124 | + challenge[14] = key3[6]; |
| 125 | + challenge[15] = key3[7]; |
| 126 | + MessageDigest md5; |
| 127 | + try { |
| 128 | + md5 = MessageDigest.getInstance("MD5"); |
| 129 | + } catch ( NoSuchAlgorithmException e ) { |
| 130 | + throw new RuntimeException(e); |
| 131 | + } |
| 132 | + return md5.digest(challenge); |
113 | 133 | } |
114 | 134 | } |
0 commit comments