Introduction to the Readresponse process in okhttp interview--httpengine

Source: Internet
Author: User

The previous section mainly looked at the SendRequest process, this section to see when the request is sent out, if you read the data in the request body, the specific code is in the Httpengine.readresponse method, the code is as follows:

 Public void Readresponse()throwsIOException {if(Userresponse! =NULL) {return;//already ready.}if(Networkrequest = =NULL&& Cacheresponse = =NULL) {Throw NewIllegalStateException ("Call SendRequest () first!"); }if(Networkrequest = =NULL) {return;//No network response to read.} Response Networkresponse;if(Forwebsocket)      {httpstream.writerequestheaders (networkrequest);    Networkresponse = Readnetworkresponse (); }Else if(!callerwritesrequestbody) {Networkresponse =NewNetworkinterceptorchain (0, networkrequest). Proceed (Networkrequest); }Else{//Emit The request body ' s buffer so this everything is in requestbodyout.      if(Bufferedrequestbody! =NULL&& Bufferedrequestbody.buffer (). Size () >0) {bufferedrequestbody.emit (); }//Emit The request headers if we haven ' t yet. We might have just learned the content-length.      if(Sentrequestmillis = =-1) {if(Okheaders.contentlength (networkrequest) = =-1&& RequestbodyoutinstanceofRetryablesink) {LongContentLength = ((Retryablesink) requestbodyout). ContentLength (); Networkrequest = Networkrequest.newbuilder (). Header ("Content-length", Long.tostring (ContentLength)). Build ();      } httpstream.writerequestheaders (Networkrequest); }//Write the request body to the socket.      if(Requestbodyout! =NULL) {if(Bufferedrequestbody! =NULL) {//This also closes the wrapped requestbodyout.Bufferedrequestbody.close (); }Else{Requestbodyout.close (); }if(RequestbodyoutinstanceofRetryablesink) {httpstream.writerequestbody (retryablesink) requestbodyout);    }} networkresponse = Readnetworkresponse (); } receiveheaders (Networkresponse.headers ());//If We have a cache response too and then we ' re doing a conditional get.    if(Cacheresponse! =NULL) {if(Validate (Cacheresponse, Networkresponse)) {userresponse = Cacheresponse.newbuilder (). Request (Userrequest). Priorresponse (Stripbody (pr Iorresponse). Headers (Combine (Cacheresponse.headers (), Networkresponse.headers ())). Cacheresponse (S        Tripbody (Cacheresponse)). Networkresponse (Stripbody (Networkresponse)). Build ();        Networkresponse.body (). Close (); Releasestreamallocation ();//Update the cache after combining headers but before stripping the        //Content-encoding header (as performed by Initcontentstream ()).Internalcache Responsecache = Internal.instance.internalCache (client);        Responsecache.trackconditionalcachehit ();        Responsecache.update (Cacheresponse, Stripbody (Userresponse)); Userresponse = unzip (userresponse);return; }Else{closequietly (Cacheresponse.body ()); }} userresponse = Networkresponse.newbuilder (). Request (Userrequest). Priorresponse (Stripbody (Priorre Sponse). Cacheresponse (Stripbody (Cacheresponse)). Networkresponse (Stripbody (Networkresponse)). Build ();if(Hasbody (Userresponse))      {Maybecache ();    Userresponse = Unzip (Cachewritingresponse (Storerequest, userresponse)); }  }

Analyze from the start

The userresponse here is null on the first visit and therefore does not enter this block of code, and will actually enter the following block of judgment statements

Can see here and call a connection interceptor, the request results are intercepted, Networkinterceptorchain is also implemented Intercept.chain, the specific code

 class networkinterceptorchain implements interceptor. Chain {    Private Final int Index;Private FinalRequest request;Private intCalls Networkinterceptorchain (int Index, request request) { This.Index=Index; This. request = Request; } @Override PublicConnection Connection () {returnStreamallocation.connection (); } @Override PublicRequest Request () {returnRequest } @Override PublicResponse Proceed (Request request) throws IOException {calls++;if(Index>0) {Interceptor caller =Client. Networkinterceptors (). Get (Index-1); Address address = connection (). Route (). address ();//Confirm that the interceptor uses the connection we ' ve already prepared.        if(!request.url (). Host (). Equals (Address.url (). Host ()) | | Request.url (). Port ()! = Address.url (). Port ()) {Throw NewIllegalStateException ("Network Interceptor"+ caller +"must retain the same host and port"); }//Confirm that's the interceptor ' s first call to Chain.proceed ().        if(Calls >1) {Throw NewIllegalStateException ("Network Interceptor"+ caller +"must call proceed () exactly once"); }      }if(Index<Client. networkinterceptors (). Size ()) {//There ' s another interceptor in the chain. call that.Networkinterceptorchain chain =NewNetworkinterceptorchain (Index+1, request); Interceptor Interceptor =Client. Networkinterceptors (). Get (Index); Response interceptedresponse = interceptor.intercept (chain);//Confirm that the interceptor made the required call to Chain.proceed ().        if(Chain.calls! =1) {Throw NewIllegalStateException ("Network Interceptor"+ Interceptor +"must call proceed () exactly once"); }if(Interceptedresponse = =NULL) {Throw NewNullPointerException ("Network Interceptor"+ Interceptor +"returned null"); }returnInterceptedresponse; } httpstream.writerequestheaders (Request);//update The Networkrequest with the possibly updated interceptor request.Networkrequest = Request;if(Permitsrequestbody (Request) && request.body ()! =NULL{Sink requestbodyout = httpstream.createrequestbody (Request, Request.body (). ContentLength ());        Bufferedsink bufferedrequestbody = Okio.buffer (requestbodyout);        Request.body (). WriteTo (Bufferedrequestbody);      Bufferedrequestbody.close (); } Response Response = Readnetworkresponse ();intCode = Response.code ();if(Code = =204|| Code = =205) && Response.body (). ContentLength () >0) {Throw NewProtocolexception ("HTTP"+ code +"had Non-zero content-length:"+ Response.body (). ContentLength ()); }returnResponse }  }

The main point of view is the proceed method

It's also a cyclic recursive call, so the code actually calls the code at the last level.

The function of each line of code has been briefly introduced in the picture. Let's focus on the most important method of reading the result of the request –readnetworkresponse, the code is as follows:

Here we have completed the process from sending the network request to the result of the read request, briefly summarizing the work of the two methods in Httpengine
sendrequest– finding the right socket object and encapsulating it in Httpstream
Readresponse– sends a request via Httpstream, and the read result is encapsulated into the response object to return

Introduction to the Readresponse process in okhttp interview--httpengine

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.