List of usage examples for org.apache.commons.httpclient ChunkedInputStream ChunkedInputStream
public ChunkedInputStream(InputStream paramInputStream) throws IOException
From source file:phex.connection.BrowseHostConnection.java
public void sendBrowseHostRequest() throws IOException, BrowseHostException { NLogger.debug(BrowseHostConnection.class, "Connection for Browse Host to " + address); results.setBrowseHostStatus(BrowseHostResults.BrowseHostStatus.CONNECTING); SocketFacade socket;//from ww w.j a v a2s . co m try { socket = SocketFactory.connect(address); } catch (IOException exp) {// standard connection failed try push request, if we have a hostGUID if (hostGUID == null) { throw exp; } socket = PushHandler.requestSocketViaPush(peer, hostGUID, // HEX for Phex 50484558); if (socket == null) { throw new IOException("Push request failed"); } } Connection connection = new Connection(socket, peer.getBandwidthService().getNetworkBandwidthController()); HTTPRequest request = new HTTPRequest("GET", "/", true); request.addHeader(new HTTPHeader(HTTPHeaderNames.HOST, address.getFullHostName())); request.addHeader(new HTTPHeader(HTTPHeaderNames.ACCEPT, // "text/html, application/x-gnutella-packets" ) ); "application/x-gnutella-packets")); request.addHeader(new HTTPHeader(HTTPHeaderNames.CONTENT_LENGTH, "0")); request.addHeader(new HTTPHeader(HTTPHeaderNames.CONNECTION, "close")); String httpRequestStr = request.buildHTTPRequestString(); NLogger.debug(BrowseHostConnection.class, "Sending Browse Host request: " + httpRequestStr); connection.write(ByteBuffer.wrap(httpRequestStr.getBytes())); HTTPResponse response; try { response = HTTPProcessor.parseHTTPResponse(connection); } catch (HTTPMessageException exp) { throw new BrowseHostException("Invalid HTTP Response: " + exp.getMessage()); } NLogger.debug(BrowseHostConnection.class, "Received Browse Host response: " + response.buildHTTPResponseString()); if (response.getStatusCode() < 200 || response.getStatusCode() > 299) { throw new BrowseHostException("Browse host request not successfull. StatusCode: " + response.getStatusCode() + ' ' + response.getStatusReason()); } HTTPHeader typeHeader = response.getHeader(HTTPHeaderNames.CONTENT_TYPE); if (typeHeader == null) { throw new BrowseHostException("Unknown content-type."); } InputStream inStream = connection.getInputStream(); HTTPHeader encHeader = response.getHeader(HTTPHeaderNames.TRANSFER_ENCODING); if (encHeader != null) { if (encHeader.getValue().equals("chunked")) { inStream = new ChunkedInputStream(inStream); } } if (typeHeader.getValue().equals("application/x-gnutella-packets")) { results.setBrowseHostStatus(BrowseHostResults.BrowseHostStatus.FETCHING); byte[] headerBuffer = new byte[MsgHeader.DATA_LENGTH]; while (true) { MsgHeader header = MessageProcessor.parseMessageHeader(inStream, headerBuffer); if (header == null) { break; } if (header.getPayload() != MsgHeader.QUERY_HIT_PAYLOAD) { throw new BrowseHostException( "Wrong header payload. Expecting query hit: " + header.getPayload()); } int length = header.getDataLength(); if (length < 0) { throw new IOException("Negative body size. Drop."); } else if (length > MessagePrefs.MaxLength.get()) { throw new IOException("Packet too big (" + length + "). Drop."); } try { QueryResponseMsg message = (QueryResponseMsg) MessageProcessor.parseMessage(header, inStream, peer.getSecurityService()); // prevent further routing of query response message... message.getHeader().setTTL((byte) 0); // Unfortunately we don't have a host instance.. peer.getMessageService().dispatchMessage(message, null); results.processResponse(message); } catch (InvalidMessageException exp) { NLogger.debug(BrowseHostConnection.class, exp, exp); throw new IOException("Invalid message returned: " + exp.getMessage()); } } } else { throw new BrowseHostException("Not supported content-type. " + typeHeader.getValue()); } }
From source file:phex.download.DownloadEngine.java
public void exchangeHTTPHandshake(SWDownloadSegment aSegment) throws IOException, UnusableHostException, HTTPMessageException { NetworkManager networkMgr = NetworkManager.getInstance(); isDownloadSuccessful = false;//from w ww. j a v a2s .c om segment = aSegment; long downloadOffset = segment.getTransferStartPosition(); OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); // reset to default input stream inStream = connection.getInputStream(); String requestUrl = candidate.getDownloadRequestUrl(); HTTPRequest request = new HTTPRequest("GET", requestUrl, true); request.addHeader(new HTTPHeader(HTTPHeaderNames.HOST, candidate.getHostAddress().getFullHostName())); request.addHeader( new HTTPHeader(GnutellaHeaderNames.LISTEN_IP, networkMgr.getLocalAddress().getFullHostName())); long segmentEndOffset = segment.getEnd(); if (segmentEndOffset == -1) {// create header with open end request.addHeader(new HTTPHeader(HTTPHeaderNames.RANGE, "bytes=" + downloadOffset + "-")); } else { request.addHeader( new HTTPHeader(HTTPHeaderNames.RANGE, "bytes=" + downloadOffset + "-" + segmentEndOffset)); } request.addHeader(new HTTPHeader(GnutellaHeaderNames.X_QUEUE, "0.1")); // request a HTTP keep alive connection, needed for queuing to work. request.addHeader(new HTTPHeader(HTTPHeaderNames.CONNECTION, "Keep-Alive")); if (candidate.isG2FeatureAdded()) { request.addHeader(new HTTPHeader("X-Features", "g2/1.0")); } buildAltLocRequestHeader(request); if (ServiceManager.sCfg.isChatEnabled) { DestAddress ha = networkMgr.getLocalAddress(); IpAddress myIp = ha.getIpAddress(); if (myIp == null || !myIp.isSiteLocalIP()) { request.addHeader(new HTTPHeader("Chat", ha.getFullHostName())); } } String httpRequestStr = request.buildHTTPRequestString(); NLogger.debug(NLoggerNames.Download_Engine, "HTTP Request to: " + candidate.getHostAddress() + "\n" + httpRequestStr); candidate.addToCandidateLog("HTTP Request:\n" + httpRequestStr); // write request... writer.write(httpRequestStr); writer.flush(); HTTPResponse response = HTTPProcessor.parseHTTPResponse(connection); if (NLogger.isDebugEnabled(NLoggerNames.Download_Engine)) { NLogger.debug(NLoggerNames.Download_Engine, "HTTP Response from: " + candidate.getHostAddress() + "\n" + response.buildHTTPResponseString()); } if (ServiceManager.sCfg.downloadCandidateLogBufferSize > 0) { candidate.addToCandidateLog("HTTP Response:\n" + response.buildHTTPResponseString()); } HTTPHeader header = response.getHeader(HTTPHeaderNames.SERVER); if (header != null) { candidate.setVendor(header.getValue()); } header = response.getHeader(HTTPHeaderNames.TRANSFER_ENCODING); if (header != null) { if (header.getValue().equals("chunked")) { inStream = new ChunkedInputStream(connection.getInputStream()); } } replyContentRange = null; header = response.getHeader(HTTPHeaderNames.CONTENT_RANGE); if (header != null) { replyContentRange = parseContentRange(header.getValue()); // startPos of -1 indicates '*' (free to choose) if (replyContentRange.startPos != -1 && replyContentRange.startPos != downloadOffset) { throw new IOException("Invalid 'CONTENT-RANGE' start offset."); } } replyContentLength = -1; header = response.getHeader(HTTPHeaderNames.CONTENT_LENGTH); if (header != null) { try { replyContentLength = header.longValue(); } catch (NumberFormatException exp) { //unknown } } URN downloadFileURN = downloadFile.getFileURN(); ArrayList contentURNHeaders = new ArrayList(); header = response.getHeader(GnutellaHeaderNames.X_GNUTELLA_CONTENT_URN); if (header != null) { contentURNHeaders.add(header); } // Shareaza 1.8.10.4 send also a bitprint urn in multiple X-Content-URN headers! HTTPHeader[] headers = response.getHeaders(GnutellaHeaderNames.X_CONTENT_URN); CollectionUtils.addAll(contentURNHeaders, headers); if (downloadFileURN != null) { Iterator contentURNIterator = contentURNHeaders.iterator(); while (contentURNIterator.hasNext()) { header = (HTTPHeader) contentURNIterator.next(); String contentURNStr = header.getValue(); // check if I can understand urn. if (URN.isValidURN(contentURNStr)) { URN contentURN = new URN(contentURNStr); if (!downloadFileURN.equals(contentURN)) { throw new IOException("Required URN and content URN do not match."); } } } } // check Limewire chat support header. header = response.getHeader(GnutellaHeaderNames.CHAT); if (header != null) { candidate.setChatSupported(true); } // read out REMOTE-IP header... to update my IP header = response.getHeader(GnutellaHeaderNames.REMOTE_IP); if (header != null) { byte[] remoteIP = AddressUtils.parseIP(header.getValue()); if (remoteIP != null) { IpAddress ip = new IpAddress(remoteIP); DestAddress address = PresentationManager.getInstance().createHostAddress(ip, -1); networkMgr.updateLocalAddress(address); } } int httpCode = response.getStatusCode(); // read available ranges header = response.getHeader(GnutellaHeaderNames.X_AVAILABLE_RANGES); if (header != null) { HTTPRangeSet availableRanges = HTTPRangeSet.parseHTTPRangeSet(header.getValue()); if (availableRanges == null) {// failed to parse... give more detailed error report NLogger.error(NLoggerNames.Download_Engine, "Failed to parse X-Available-Ranges in " + candidate.getVendor() + " request: " + response.buildHTTPResponseString()); } candidate.setAvailableRangeSet(availableRanges); } else if (httpCode >= 200 && httpCode < 300 && downloadFile.getTotalDataSize() != SWDownloadConstants.UNKNOWN_FILE_SIZE) {// OK header and no available range header.. we assume candidate // shares the whole file candidate.setAvailableRangeSet(new HTTPRangeSet(0, downloadFile.getTotalDataSize() - 1)); } // collect alternate locations... List altLocList = new ArrayList(); headers = response.getHeaders(GnutellaHeaderNames.ALT_LOC); List altLocTmpList = AlternateLocationContainer.parseUriResAltLocFromHTTPHeaders(headers); altLocList.addAll(altLocTmpList); headers = response.getHeaders(GnutellaHeaderNames.X_ALT_LOC); altLocTmpList = AlternateLocationContainer.parseUriResAltLocFromHTTPHeaders(headers); altLocList.addAll(altLocTmpList); headers = response.getHeaders(GnutellaHeaderNames.X_ALT); altLocTmpList = AlternateLocationContainer.parseCompactIpAltLocFromHTTPHeaders(headers, downloadFileURN); altLocList.addAll(altLocTmpList); // TODO1 huh?? dont we pare X-NALT???? Iterator iterator = altLocList.iterator(); while (iterator.hasNext()) { downloadFile.addDownloadCandidate((AlternateLocation) iterator.next()); } // collect push proxies. // first the old headers.. headers = response.getHeaders("X-Pushproxies"); handlePushProxyHeaders(headers); headers = response.getHeaders("X-Push-Proxies"); handlePushProxyHeaders(headers); // now the standard header headers = response.getHeaders(GnutellaHeaderNames.X_PUSH_PROXY); handlePushProxyHeaders(headers); updateKeepAliveSupport(response); if (httpCode >= 200 && httpCode < 300) {// code accepted // check if we can accept the urn... if (contentURNHeaders.size() == 0 && requestUrl.startsWith(GnutellaRequest.GNUTELLA_URI_RES_PREFIX)) {// we requested a download via /uri-res resource urn. // we expect that the result contains a x-gnutella-content-urn // or Shareaza X-Content-URN header. throw new IOException("Response to uri-res request without valid Content-URN header."); } // check if we need and can update our file and segment size. if (downloadFile.getTotalDataSize() == SWDownloadConstants.UNKNOWN_FILE_SIZE) { // we have a file with an unknown data size. For aditional check assert // certain parameters assert (segment.getTotalDataSize() == -1); // Now verify if we have the great chance to update our file data! if (replyContentRange != null && replyContentRange.totalLength != SWDownloadConstants.UNKNOWN_FILE_SIZE) { downloadFile.setFileSize(replyContentRange.totalLength); // we learned the file size. To allow normal segment use // interrupt the download! stopDownload(); throw new ReconnectException(); } } // connection successfully finished NLogger.debug(NLoggerNames.Download_Engine, "HTTP Handshake successfull."); return; } // check error type else if (httpCode == 503) {// 503 -> host is busy (this can also be returned when remotly queued) header = response.getHeader(GnutellaHeaderNames.X_QUEUE); XQueueParameters xQueueParameters = null; if (header != null) { xQueueParameters = XQueueParameters.parseHTTPRangeSet(header.getValue()); } // check for persistent connection (gtk-gnutella uses queuing with 'Connection: close') if (xQueueParameters != null && isKeepAliveSupported) { throw new RemotelyQueuedException(xQueueParameters); } else { header = response.getHeader(HTTPHeaderNames.RETRY_AFTER); if (header != null) { int delta = HTTPRetryAfter.parseDeltaInSeconds(header); if (delta > 0) { throw new HostBusyException(delta); } } throw new HostBusyException(); } } else if (httpCode == HTTPCodes.HTTP_401_UNAUTHORIZED || httpCode == HTTPCodes.HTTP_403_FORBIDDEN) { if ("Network Disabled".equals(response.getStatusReason())) { if (candidate.isG2FeatureAdded()) { // already tried G2 but no success.. better give up and dont hammer.. throw new UnusableHostException("Request Forbidden"); } else { // we have not tried G2 but we could.. candidate.setG2FeatureAdded(true); throw new HostBusyException(60 * 5); } } else { throw new UnusableHostException("Request Forbidden"); } } else if (httpCode == 408) { // 408 -> Time out. Try later? throw new HostBusyException(); } else if (httpCode == 404 || httpCode == 410) {// 404: File not found / 410: Host not sharing throw new FileNotAvailableException(); } else if (httpCode == 416) {// 416: Requested Range Unavailable header = response.getHeader(HTTPHeaderNames.RETRY_AFTER); if (header != null) { int delta = HTTPRetryAfter.parseDeltaInSeconds(header); if (delta > 0) { throw new RangeUnavailableException(delta); } } throw new RangeUnavailableException(); } else { throw new IOException("Unknown HTTP code: " + httpCode); } }
From source file:phex.download.handler.HttpFileDownload.java
public void processHandshake() throws IOException, UnusableHostException, HTTPMessageException { isDownloadSuccessful = false;//from w w w .j a v a2s . c o m Connection connection = downloadEngine.getConnection(); SWDownloadSet downloadSet = downloadEngine.getDownloadSet(); Peer peer = downloadSet.peer; PhexSecurityManager securityService = peer.getSecurityService(); SWDownloadCandidate candidate = downloadSet.downloadCandidate; SWDownloadFile downloadFile = downloadSet.downloadFile; SWDownloadSegment segment = downloadSet.getDownloadSegment(); long downloadOffset = segment.getTransferStartPosition(); OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); // reset to default input stream inStream = connection.getInputStream(); String requestUrl = candidate.getDownloadRequestUrl(); HTTPRequest request = new HTTPRequest("GET", requestUrl, true); request.addHeader(new HTTPHeader(HTTPHeaderNames.HOST, candidate.getHostAddress().getFullHostName())); long segmentEndOffset = segment.getEnd(); if (segmentEndOffset == -1) {// create header with open end request.addHeader(new HTTPHeader(HTTPHeaderNames.RANGE, "bytes=" + downloadOffset + '-')); } else { request.addHeader( new HTTPHeader(HTTPHeaderNames.RANGE, "bytes=" + downloadOffset + '-' + segmentEndOffset)); } request.addHeader(new HTTPHeader(GnutellaHeaderNames.X_QUEUE, "0.1")); // request a HTTP keep alive connection, needed for queuing to work. request.addHeader(new HTTPHeader(HTTPHeaderNames.CONNECTION, "Keep-Alive")); if (candidate.isG2FeatureAdded()) { request.addHeader(new HTTPHeader("X-Features", "g2/1.0")); } buildAltLocRequestHeader(downloadFile, candidate, request, peer.getLocalAddress(), peer.isFirewalled()); DestAddress localAdress = peer.getLocalAddress(); IpAddress myIp = localAdress.getIpAddress(); if (!peer.isFirewalled() && (myIp == null || !myIp.isSiteLocalIP())) { request.addHeader(new HTTPHeader(GnutellaHeaderNames.X_NODE, localAdress.getFullHostName())); if (peer.netPrefs.AllowChatConnection.get().booleanValue()) { request.addHeader(new HTTPHeader("Chat", localAdress.getFullHostName())); } } String httpRequestStr = request.buildHTTPRequestString(); logger.debug("HTTP Request to: {}\n{}", candidate.getHostAddress(), httpRequestStr); candidate.addToCandidateLog("HTTP Request:\n" + httpRequestStr); // write request... writer.write(httpRequestStr); writer.flush(); HTTPResponse response = HTTPProcessor.parseHTTPResponse(connection); if (logger.isDebugEnabled()) { logger.debug("HTTP Response from: {}\n{}", candidate.getHostAddress(), response.buildHTTPResponseString()); } if (DownloadPrefs.CandidateLogBufferSize.get().intValue() > 0) { candidate.addToCandidateLog("HTTP Response:\n" + response.buildHTTPResponseString()); } updateServerHeader(response); HTTPHeader header; header = response.getHeader(HTTPHeaderNames.TRANSFER_ENCODING); if (header != null) { if (header.getValue().equals("chunked")) { inStream = new ChunkedInputStream(connection.getInputStream()); } } replyContentRange = null; header = response.getHeader(HTTPHeaderNames.CONTENT_RANGE); if (header != null) { replyContentRange = parseContentRange(header.getValue()); // startPos of -1 indicates '*' (free to choose) if (replyContentRange.startPos != -1 && replyContentRange.startPos != downloadOffset) { throw new IOException("Invalid 'CONTENT-RANGE' start offset."); } } replyContentLength = -1; header = response.getHeader(HTTPHeaderNames.CONTENT_LENGTH); if (header != null) { try { replyContentLength = header.longValue(); } catch (NumberFormatException exp) { //unknown } } header = response.getHeader(GnutellaHeaderNames.X_THEX_URI); handleThexUriHeader(downloadFile, candidate, header); List<HTTPHeader> contentURNHeaders = new ArrayList<HTTPHeader>(); header = response.getHeader(GnutellaHeaderNames.X_GNUTELLA_CONTENT_URN); if (header != null) { contentURNHeaders.add(header); } // Shareaza 1.8.10.4 send also a bitprint urn in multiple X-Content-URN headers! HTTPHeader[] headers = response.getHeaders(GnutellaHeaderNames.X_CONTENT_URN); CollectionUtils.addAll(contentURNHeaders, headers); handleContentUrnHeaders(downloadFile, contentURNHeaders); if (contentURNHeaders.size() == 0) { // no content URN headers received. Use content URN headers we // received before. contentURNHeaders = candidate.getContentURNHeaders(); } else { candidate.getContentURNHeaders().clear(); candidate.getContentURNHeaders().addAll(contentURNHeaders); } // check Limewire chat support header. header = response.getHeader(GnutellaHeaderNames.CHAT); if (header != null) { candidate.setChatSupported(true); } // read out REMOTE-IP header... to update my IP header = response.getHeader(GnutellaHeaderNames.REMOTE_IP); if (header != null) { byte[] remoteIP = AddressUtils.parseIP(header.getValue()); if (remoteIP != null) { IpAddress ip = new IpAddress(remoteIP); DestAddress address = PresentationManager.getInstance().createHostAddress(ip, -1); peer.updateLocalAddress(address); } } handleAvailableRangesHeader(candidate, downloadFile, response); URN downloadFileURN = downloadFile.getFileURN(); // collect alternate locations... List<AlternateLocation> altLocList = new ArrayList<AlternateLocation>(); headers = response.getHeaders(GnutellaHeaderNames.ALT_LOC); List<AlternateLocation> altLocTmpList = AltLocContainer.parseUriResAltLocFromHeaders(headers, securityService); altLocList.addAll(altLocTmpList); headers = response.getHeaders(GnutellaHeaderNames.X_ALT_LOC); altLocTmpList = AltLocContainer.parseUriResAltLocFromHeaders(headers, securityService); altLocList.addAll(altLocTmpList); headers = response.getHeaders(GnutellaHeaderNames.X_ALT); altLocTmpList = AltLocContainer.parseCompactIpAltLocFromHeaders(headers, downloadFileURN, securityService); altLocList.addAll(altLocTmpList); // TODO1 huh?? dont we pare X-NALT???? Iterator<AlternateLocation> iterator = altLocList.iterator(); while (iterator.hasNext()) { downloadFile.addDownloadCandidate(iterator.next()); } // collect push proxies. // first the old headers.. headers = response.getHeaders("X-Pushproxies"); handlePushProxyHeaders(candidate, headers, securityService); headers = response.getHeaders("X-Push-Proxies"); handlePushProxyHeaders(candidate, headers, securityService); // now the standard header headers = response.getHeaders(GnutellaHeaderNames.X_PUSH_PROXY); handlePushProxyHeaders(candidate, headers, securityService); updateKeepAliveSupport(response); int httpCode = response.getStatusCode(); if (httpCode >= 200 && httpCode < 300) {// code accepted // check if we can accept the urn... if (contentURNHeaders.size() == 0 && requestUrl.startsWith(GnutellaRequest.GNUTELLA_URI_RES_PREFIX)) {// we requested a download via /uri-res resource urn. // we expect that the result contains a x-gnutella-content-urn // or Shareaza X-Content-URN header. throw new IOException("Response to uri-res request without valid Content-URN header."); } // check if we need and can update our file and segment size. if (downloadFile.getTotalDataSize() == SWDownloadConstants.UNKNOWN_FILE_SIZE) { // we have a file with an unknown data size. For aditional check assert // certain parameters assert (segment.getTotalDataSize() == -1); // Now verify if we have the great chance to update our file data! if (replyContentRange != null && replyContentRange.totalLength != SWDownloadConstants.UNKNOWN_FILE_SIZE) { downloadFile.setFileSize(replyContentRange.totalLength); // we learned the file size. To allow normal segment use // interrupt the download! stopDownload(); throw new ReconnectException(); } } // connection successfully finished logger.debug("HTTP Handshake successfull."); return; } // check error type else if (httpCode == 503) {// 503 -> host is busy (this can also be returned when remotely queued) header = response.getHeader(GnutellaHeaderNames.X_QUEUE); XQueueParameters xQueueParameters = null; if (header != null) { xQueueParameters = XQueueParameters.parseXQueueParameters(header.getValue()); } // check for persistent connection (gtk-gnutella uses queuing with 'Connection: close') if (xQueueParameters != null && isKeepAliveSupported) { // Immediately release segment to give free for others... downloadSet.releaseDownloadSegment(); throw new RemotelyQueuedException(xQueueParameters); } else { header = response.getHeader(HTTPHeaderNames.RETRY_AFTER); if (header != null) { int delta = HTTPRetryAfter.parseDeltaInSeconds(header); if (delta > 0) { throw new HostBusyException(delta); } } throw new HostBusyException(); } } else if (httpCode == HTTPCodes.HTTP_401_UNAUTHORIZED || httpCode == HTTPCodes.HTTP_403_FORBIDDEN) { if ("Network Disabled".equals(response.getStatusReason())) { if (candidate.isG2FeatureAdded()) { // already tried G2 but no success.. better give up and don't hammer.. throw new UnusableHostException("Request Forbidden"); } else { // we have not tried G2 but we could.. candidate.setG2FeatureAdded(true); throw new HostBusyException(60 * 5); } } else { throw new UnusableHostException("Request Forbidden"); } } else if (httpCode == 408) { // 408 -> Time out. Try later? throw new HostBusyException(); } else if (httpCode == 404 || httpCode == 410) {// 404: File not found / 410: Host not sharing throw new FileNotAvailableException(); } else if (httpCode == 416) {// 416: Requested Range Unavailable // Immediately release segment to give free for others... downloadSet.releaseDownloadSegment(); header = response.getHeader(HTTPHeaderNames.RETRY_AFTER); if (header != null) { int delta = HTTPRetryAfter.parseDeltaInSeconds(header); if (delta > 0) { throw new RangeUnavailableException(delta); } } throw new RangeUnavailableException(); } else if (httpCode == 500) { throw new UnusableHostException("Internal Server Error"); } else { throw new IOException("Unknown HTTP code: " + httpCode); } }
From source file:phex.download.handler.HttpThexDownload.java
public void processHandshake() throws IOException, HTTPMessageException, UnusableHostException { isDownloadSuccessful = false;/*from w w w .ja v a 2 s. c o m*/ Connection connection = downloadEngine.getConnection(); SWDownloadCandidate candidate = downloadEngine.getDownloadSet().downloadCandidate; OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); // reset to default input stream inStream = connection.getInputStream(); String requestUrl = candidate.getThexUri(); HTTPRequest request = new HTTPRequest("GET", requestUrl, true); request.addHeader(new HTTPHeader(HTTPHeaderNames.HOST, candidate.getHostAddress().getFullHostName())); request.addHeader(new HTTPHeader(GnutellaHeaderNames.X_QUEUE, "0.1")); // request a HTTP keep alive connection, needed for queuing to work. request.addHeader(new HTTPHeader(HTTPHeaderNames.CONNECTION, "Keep-Alive")); String httpRequestStr = request.buildHTTPRequestString(); logger.debug("HTTP Request to: {}\n{}", candidate.getHostAddress(), httpRequestStr); candidate.addToCandidateLog("HTTP Request:\n" + httpRequestStr); // write request... writer.write(httpRequestStr); writer.flush(); HTTPResponse response = HTTPProcessor.parseHTTPResponse(connection); if (logger.isDebugEnabled()) { logger.debug("HTTP Response from: {}\n{}", candidate.getHostAddress(), response.buildHTTPResponseString()); } if (DownloadPrefs.CandidateLogBufferSize.get().intValue() > 0) { candidate.addToCandidateLog("HTTP Response:\n" + response.buildHTTPResponseString()); } updateServerHeader(response); HTTPHeader header; header = response.getHeader(HTTPHeaderNames.TRANSFER_ENCODING); if (header != null) { if (header.getValue().equals("chunked")) { inStream = new ChunkedInputStream(connection.getInputStream()); } } replyContentLength = -1; header = response.getHeader(HTTPHeaderNames.CONTENT_LENGTH); if (header != null) { try { replyContentLength = header.longValue(); } catch (NumberFormatException exp) { //unknown } } updateKeepAliveSupport(response); int httpCode = response.getStatusCode(); if (httpCode >= 200 && httpCode < 300) {// code accepted // connection successfully finished logger.debug("HTTP Handshake successfull."); return; } // check error type else if (httpCode == 503) {// 503 -> host is busy (this can also be returned when remotely queued) header = response.getHeader(GnutellaHeaderNames.X_QUEUE); XQueueParameters xQueueParameters = null; if (header != null) { xQueueParameters = XQueueParameters.parseXQueueParameters(header.getValue()); } // check for persistent connection (gtk-gnutella uses queuing with 'Connection: close') if (xQueueParameters != null && isKeepAliveSupported) { throw new RemotelyQueuedException(xQueueParameters); } else { header = response.getHeader(HTTPHeaderNames.RETRY_AFTER); if (header != null) { int delta = HTTPRetryAfter.parseDeltaInSeconds(header); if (delta > 0) { throw new HostBusyException(delta); } } throw new HostBusyException(); } } else { throw new IOException("Unknown HTTP code: " + httpCode); } }