1 28 29 package HTTPClient; 30 31 import java.io.IOException ; 32 import java.net.ProtocolException ; 33 34 35 46 47 class ContentMD5Module implements HTTPClientModule, GlobalConstants 48 { 49 51 ContentMD5Module() 52 { 53 } 54 55 56 58 61 public int requestHandler(Request req, Response[] resp) 62 { 63 return REQ_CONTINUE; 64 } 65 66 67 70 public void responsePhase1Handler(Response resp, RoRequest req) 71 { 72 } 73 74 75 78 public int responsePhase2Handler(Response resp, Request req) 79 { 80 return RSP_CONTINUE; 81 } 82 83 84 87 public void responsePhase3Handler(Response resp, RoRequest req) 88 throws IOException , ModuleException 89 { 90 if (req.getMethod().equals("HEAD")) 91 return; 92 93 String md5_digest = resp.getHeader("Content-MD5"); 94 String trailer = resp.getHeader("Trailer"); 95 boolean md5_tok = false; 96 try 97 { 98 if (trailer != null) 99 md5_tok = Util.hasToken(trailer, "Content-MD5"); 100 } 101 catch (ParseException pe) 102 { throw new ModuleException(pe.toString()); } 103 104 if ((md5_digest == null && !md5_tok) || 105 resp.getHeader("Transfer-Encoding") != null) 106 return; 107 108 if (DebugMods) 109 { 110 if (md5_digest != null) 111 System.err.println("CMD5M: Received digest: " + md5_digest + 112 " - pushing md5-check-stream"); 113 else 114 System.err.println("CMD5M: Expecting digest in trailer " + 115 " - pushing md5-check-stream"); 116 } 117 118 resp.inp_stream = new MD5InputStream(resp.inp_stream, 119 new VerifyMD5(resp)); 120 } 121 122 123 126 public void trailerHandler(Response resp, RoRequest req) 127 { 128 } 129 } 130 131 132 class VerifyMD5 implements HashVerifier, GlobalConstants 133 { 134 RoResponse resp; 135 136 137 public VerifyMD5(RoResponse resp) 138 { 139 this.resp = resp; 140 } 141 142 143 public void verifyHash(byte[] hash, long len) throws IOException 144 { 145 String hdr; 146 try 147 { 148 if ((hdr = resp.getHeader("Content-MD5")) == null) 149 hdr = resp.getTrailer("Content-MD5"); 150 } 151 catch (IOException ioe) 152 { return; } 154 if (hdr == null) return; 155 156 hdr = hdr.trim(); 157 byte[] ContMD5 = new byte[hdr.length()]; 158 hdr.getBytes(0, ContMD5.length, ContMD5, 0); 159 ContMD5 = Codecs.base64Decode(ContMD5); 160 161 for (int idx=0; idx<hash.length; idx++) 162 { 163 if (hash[idx] != ContMD5[idx]) 164 throw new IOException ("MD5-Digest mismatch: expected " + 165 hex(ContMD5) + " but calculated " + 166 hex(hash)); 167 } 168 169 if (DebugMods) 170 System.err.println("CMD5M: hash successfully verified"); 171 } 172 173 174 177 private static String hex(byte[] buf) 178 { 179 StringBuffer str = new StringBuffer (buf.length*3); 180 for (int idx=0; idx<buf.length; idx++) 181 { 182 str.append(Character.forDigit((buf[idx] >>> 4) & 15, 16)); 183 str.append(Character.forDigit(buf[idx] & 15, 16)); 184 str.append(':'); 185 } 186 str.setLength(str.length()-1); 187 188 return str.toString(); 189 } 190 } 191 192 | Popular Tags |