OkHttp 분석 시리즈-방향 변경 및 오류 재 시도
Http
요청 을 보 내 는 과정 에서 의 재 설정 과 오류 재 시도 에 대해 연 구 했 습 니 다.주로 관련 된 소스 파일 은 Call.java``HttpEngine.java
입 니 다. 우 리 는 오늘 Call
의 Response getResponse(Request request, boolean forWebSocket) throws IOException
함 수 를 연구 합 니 다.이것 은 Call.execute()
을 Response
으로 호출 한 핵심 함수 입 니 다.주요 기능 은 HttpEngine
을 새로 만 들 고 Request
을 보 낸 다음 에 오류 재 시도 와 재 설정 문 제 를 처리 하 는 것 입 니 다.헤더 설정
// Copy body metadata to the appropriate request headers.
RequestBody body = request.body();
if (body != null) {
Request.Builder requestBuilder = request.newBuilder();//
MediaType contentType = body.contentType();
if (contentType != null) {
requestBuilder.header("Content-Type", contentType.toString());
}
long contentLength = body.contentLength();
if (contentLength != -1) {
requestBuilder.header("Content-Length", Long.toString(contentLength));
requestBuilder.removeHeader("Transfer-Encoding");
} else {
requestBuilder.header("Transfer-Encoding", "chunked");
requestBuilder.removeHeader("Content-Length");
}
request = requestBuilder.build();
}
이것 은 함수 의 첫 번 째 부분 으로 주로
RequestBody
의 일부 메타 데 이 터 를 Header
의 첫 번 째 부분 에 복사 한 것 으로 주로 Content-Type
과 Transfer-Encoding
이다.Content-Type
은 모두 가 알 고 있 을 것 이 라 고 믿 습 니 다.RequestBody
을 표시 하 는 Mime-Type
의 형식 은 /
이 고 예 를 들 어 text/xml
입 니 다.한편,Transfer-Encoding
은 인터넷 전송 방식 을 나타 내 는데 구체 적 으로 알 고 싶 은 학생 들 은 이 링크 점 을 볼 수 있 습 니 다.오류 가 발생 했 습 니 다.다시 시도 하 십시오.
// Create the initial HTTP engine. Retries and redirects need new engine for each attempt.
// http ,
engine = new HttpEngine(client, request, false, false, forWebSocket, null, null, null, null);
int followUpCount = 0; //
while (true) {
if (canceled) { //
engine.releaseConnection();
throw new IOException("Canceled");
}
try {
engine.sendRequest();
engine.readResponse();
} catch (RequestException e) {
// The attempt to interpret the request failed. Give up.
throw e.getCause();
} catch (RouteException e) {
// The attempt to connect via a route failed. The request will not have been sent.
HttpEngine retryEngine = engine.recover(e); //
if (retryEngine != null) {
engine = retryEngine;
continue;
}
// Give up; recovery is not possible.
throw e.getLastConnectException();
} catch (IOException e) {
// An attempt to communicate with a server failed. The request may have been sent.
HttpEngine retryEngine = engine.recover(e, null);
if (retryEngine != null) {
engine = retryEngine;
continue;
}
// Give up; recovery is not possible.
throw e;
}
.......
이 코드 에서
OkHttp
은 HttpEngine
대상 을 구축 하여 Http
등급 의 요청 의 발송 과 답장 의 수신 을 책임 지고 HttpEngine
은 이후 의 박문 에서 상세 하 게 설명 할 것 이다.그 다음 에 while
순환 에 들 어 갔 는데 이 순환 은 주로 방향 을 바 꾸 는 문 제 를 처리 하 는 것 이다.우 리 는 이 절 에서 주로 catch
의 논 리 를 주목 하 는데 이것 은 오류 재 시 를 처리 하 는 논리 이다.외층 에 while
순환 이 있 기 때문에 catch
에서 retryEngine
을 얻 으 려 고 시 도 했 고 있 으 면 continue
,없 으 면 이상 을 던 졌 다.재 정립 처리
Response response = engine.getResponse();
// followUp http connection ?
Request followUp = engine.followUpRequest();
if (followUp == null) {
if (!forWebSocket) { // followup websocket
engine.releaseConnection();//
}
return response;
}
if (++followUpCount > MAX_FOLLOW_UPS) {
throw new ProtocolException("Too many follow-up requests: " + followUpCount);
}
if (!engine.sameConnection(followUp.httpUrl())) { // followup httpUrl ,
//schema,host or port
engine.releaseConnection();
}
// connection !!!!
Connection connection = engine.close();
request = followUp;
// ,
engine = new HttpEngine(client, request, false, false, forWebSocket, connection, null, null,
response);
여기 서 우 리 는
Http
의 방향 을 바 꾸 는 체 제 를 볼 수 있다.Request request = engine.followUpRequest()
으로 방향 을 바 꾸 려 면 보 내야 할 Request
을 얻 을 수 있 습 니 다.없 거나 방향 을 바 꾸 는 횟수 가 MAX_FOLLOW_UPS
보다 많 으 면 방향 변경 요 구 를 다시 보 내지 않 습 니 다.그리고 리 셋 요청 과 원래 요청 한 HttpUrl 이 같은 지 판단 합 니 다.그렇지 않 으 면 리 셋 요청 을 보 내지 않 습 니 다.그 다음 에 Connection connection = engine.close()
은 자원 을 방출 하고 지난번 연결 을 재 활용 한 다음 에 HttpEngine
을 새로 만 든 다음 에 While
순환 으로 요청 을 보 냅 니 다.리 셋 상태 코드 분석
public Request followUpRequest() throws IOException {
if (userResponse == null) throw new IllegalStateException();
Proxy selectedProxy = getRoute() != null
? getRoute().getProxy()
: client.getProxy();
int responseCode = userResponse.code();
switch (responseCode) {
case HTTP_PROXY_AUTH: //407 Proxy authentication required
if (selectedProxy.type() != Proxy.Type.HTTP) {
throw new ProtocolException("Received HTTP_PROXY_AUTH (407) code while not using proxy");
}
// fall-through
case HTTP_UNAUTHORIZED: //401
return OkHeaders.processAuthHeader(client.getAuthenticator(), userResponse, selectedProxy);
case HTTP_PERM_REDIRECT:// 308
case HTTP_TEMP_REDIRECT: //307
// "If the 307 or 308 status code is received in response to a request other than GET
// or HEAD, the user agent MUST NOT automatically redirect the request"
if (!userRequest.method().equals("GET") && !userRequest.method().equals("HEAD")) {
return null;
} // get head
// fall-through
case HTTP_MULT_CHOICE: //300
case HTTP_MOVED_PERM:// 301
case HTTP_MOVED_TEMP://302
case HTTP_SEE_OTHER: //303
// Does the client allow redirects?
if (!client.getFollowRedirects()) return null;//
String location = userResponse.header("Location");// response location
if (location == null) return null;
HttpUrl url = userRequest.httpUrl().resolve(location);// request location
// Don't follow redirects to unsupported protocols.
if (url == null) return null;
// If configured, don't follow redirects between SSL and non-SSL.
boolean sameScheme = url.scheme().equals(userRequest.httpUrl().scheme());
if (!sameScheme && !client.getFollowSslRedirects()) return null;
// Redirects don't include a request body.
Request.Builder requestBuilder = userRequest.newBuilder();
if (HttpMethod.permitsRequestBody(userRequest.method())) {
requestBuilder.method("GET", null);
requestBuilder.removeHeader("Transfer-Encoding");
requestBuilder.removeHeader("Content-Length");
requestBuilder.removeHeader("Content-Type");
}
// When redirecting across hosts, drop all authentication headers. This
// is potentially annoying to the application layer since they have no
// way to retain them.
if (!sameConnection(url)) {
requestBuilder.removeHeader("Authorization");
}
return requestBuilder.url(url).build();
default:
return null;
}
『8195』이 부분 은 답장 의 상태 코드 에 따라 재 설정 요청 코드 논 리 를 생 성 하 는 것 입 니 다.
method
이 GET
과 HEAD
이 아 닐 때 만 방향 을 바 꾸 지 않 으 며,그렇지 않 으 면 아래 열 상태 코드 로 Response
중 Location
첫 번 째 부분의 값 을 획득 한 뒤 HttpUrl
으로 해석 하고,host
이 다르다 면 모든 인증 첫 번 째 부분 을 제거 하 는 것 은 안전 을 위 한 것 이다.결어
오늘 총 결 된 것 은
Http
의 재 정립 부분 과 OkHttp
중의 재 정립 에 관 한 논리 부분 일 뿐이다.그 후에 Http
에 관 한 지식 을 계속 정리 할 것 이다.『8195』본문 도 나의 독립 박문 에서 동시에 나 를 발표 했다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.