Depth Tomcat source code analysis Session in the end is Gesha?

Session in the end is Gesha?

Article first appeared in the public micro-channel number "Tomcat those things," welcome attention.

As we all know, HTTP protocol itself is stateless (Stateless), which for some simple page display, the functional enough, are not affected. As for the increasingly complex dynamic pages, applications, and other scenes login authentication needs, it powerless. Imagine a user has logged in still prompted to log in again and again, what would it feel?

Therefore, most applications need to maintain state, it is necessary to ensure consistent client and server interaction state. For the browser to initiate multiple requests, based only on the HTTP protocol, it is unable to identify whether the same user requests. In order to keep the client and server interaction mode, you can take a series of strategies, such as:

 

  • Cookie

  • Hidden form fields form

  • Session

  • URL

  • SSL

 

This article Tomcat source code through in-depth analysis of how the most common internal Servlet container to use Session to maintain a consistent client and server status.

 

As a Web application developer, we must have heard about, or even find out about Session concepts of the word, as well as behind it represents.

 

The Session, Chinese call session , for holding the interaction between two state devices. Thus, the session must have at least one of the need to save the state of the session.

 

In Servlet specification, session object HttpSession This interface is represented by, a concise description of the interface which summarizes the major role

 

Provides a way to identify a user across more than one page request or

visit to a Web site and to store information about that user.

 

The servlet container uses this interface to create a session between an HTTP

client and an HTTP server. The session persists for a specified time period,

across more than one connection or page request from the user. A session

usually corresponds to one user.

 

The internal Tomcat is achieved through the HttpSession StandardSession this interface, unified internal use StandardSession to deal with.

 

In the initial application request, if the need to use Session, it will create it. General Servlet and will not be used directly. If a request for a JSP file, since the default JSP implicit object comprising

session , which is generated when the Servlet file, containing the equivalent of the interior

 

HttpServletRequest.getSession(true)

 

Therefore, the object will directly create session request.

 

Session creation process, roughly like the following:

 

protected Session doGetSession(boolean create) {

// There cannot be a session if no context has been assigned yet

Context context = getContext();

if (context == null) {

return (null);

}

// Return the current session if it exists and is valid

if ((session != null) && !session.isValid()) {

session = null;

}

if (session != null) {

return (session);

}

 

// Return the requested session if it exists and is valid

Manager manager = context.getManager();

if (manager == null) {

return (null); // Sessions are not supported

}

if (requestedSessionId != null) {

try {

session = manager.findSession(requestedSessionId);

} catch (IOException e) {

session = null;

}

if ((session != null) && !session.isValid()) {

session = null;

}

if (session != null) {

session.access();

return (session);

}

}

 

// Create a new session if requested and the response is not committed

if (!create) {

return (null);

}

if (response != null

&& context.getServletContext()

.getEffectiveSessionTrackingModes()

.contains(SessionTrackingMode.COOKIE)

&& response.getResponse().isCommitted()) {

throw new IllegalStateException(

sm.getString("coyoteRequest.sessionCreateCommitted"));

}

 

// Attempt to reuse session id if one was submitted in a cookie

// Do not reuse the session id if it is from a URL, to prevent possible

// phishing attacks

// Use the SSL session ID if one is present.

if (("/".equals(context.getSessionCookiePath())

&& isRequestedSessionIdFromCookie()) || requestedSessionSSL ) {

session = manager.createSession(getRequestedSessionId());

} else {

session = manager.createSession(null);

}

 

// Creating a new session cookie based on that session

if (session != null

&& context.getServletContext()

.getEffectiveSessionTrackingModes()

.contains(SessionTrackingMode.COOKIE)) {

Cookie cookie =

ApplicationSessionCookieConfig.createSessionCookie(

context, session.getIdInternal(), isSecure());

response.addSessionCookieInternal(cookie);

}

if (session == null) {

return null;

}

session.access();

return session;

}

 

The basic overall process is to determine whether the existing session, if not then created. If so, then used directly.

 

At this point, we need to pay attention to two issues:

  1. Initial request, session how to generate and deliver to the client

  2. Other subsequent request, if the request of the client and server to associate an existing session

 

The above code, and create a process to determine session does not exist, this method is called directly createSession, and depending on whether sessionId is empty, it is determined to create a totally new session, or restore an existing session.

 

public Session createSession(String sessionId) {

if ((maxActiveSessions >= 0) &&

(getActiveSessions() >= maxActiveSessions)) {

rejectedSessions++;

throw new TooManyActiveSessionsException(

sm.getString("managerBase.createSession.ise"),

maxActiveSessions); // note that here is a strategy

}

// Recycle or create a Session instance

Session session = createEmptySession();

// Initialize the properties of the new session and return it

session.setNew(true);

session.setValid(true);

session.setCreationTime(System.currentTimeMillis());

sessionsetMaxInactiveInterval (thismaxInactiveInterval);

String id = sessionId;

if (id == null) {

id = generateSessionId();

}

session.setId(id);

sessionCounter++;

SessionTiming timing = new SessionTiming(session.getCreationTime(), 0);

synchronized (sessionCreationTiming) {

sessionCreationTiming.add(timing);

sessionCreationTiming.poll();

}

return (session);

}

 

 

Here is a Session timeout, ie the maximum idle time

Note that the value here maxInactiveInterval, namely session timeout default web.xml we provided (background replies keyword 004 for more) for 30 minutes.

 

After creating Session, Tomcat provided by this MimeHeader Set-Cookie header value in response to data returned to the client session. The data returned is this:

JSESSIONID=CC4D83F3A61823AA8F980C89890A19D7; Path=/manager/; HttpOnly

 

Set Header is as follows:

public void addSessionCookieInternal(final Cookie cookie) {

if (isCommitted ()) {// Here judgment, if the response has been submitted, can no longer provided

return;

}

String name = cookie.getName();

final String headername = "Set-Cookie";

final String startsWith = name + "=";

GenerateCookieString header = String (cookie);  // here generate a corresponding sequence according to the specific content of the cookie, the cookie will determine the internal version expiration time

 

if (!set) {

addHeader(headername, header);

} }

 

 

We see that the initial request, the response header contains the data highlighted.

 

That request it again, we see the response header no data sessionId, but transferred to the request header, and in the form of Cookie provides:

At this time, spread to the server, the server parsing Cookie corresponding JSESSIOONID, and extracts values ​​corresponding to sessionId, the session data corresponding to the server Correlative.

 

We see the implementation code

 

When the request again, get SessionCookie from Request in place here:

CoyoteAdapter.postParseRequset()

 

Internally, it calls parseSessionCookiesId (request), the cookie data resolution request header.

public void parseCookieHeader(MimeHeaders headers, ServerCookies serverCookies) {

// process each "cookie" header

int pos = headers.findHeader("Cookie", 0);

}

}

 

SessionCookie name to note here is that it allows configuration, so this is not necessarily the name has been JSESSIONID.

 

After parsing Cookie obtain SessionId, we get only a string, not immediately and Session associate request at this time will be the value assigned to its internal named

requestSessionId properties.

When the request again later session, on the top of the code and we can see, there will be a process of findSession,

 

This, we have a basic understanding between the client browser and server Tomcat, if agreed to maintain interaction state in an implementation that SessionCookie .

 

The essence, this process is a process conventionally Socket interaction, we can write the code own analog return response data, but the data has to be noted in response to a specific format header in the HTTP specification requirements, as follows, i.e., data of to separate room with a CRLF

 

Under summary, the initial client requests the server the Session is created, this time provided by the Set-Cookie sessionId delivered to the client in the response header. Subsequent client requests will be provided in a Cookie request header item sessionId belt in order to ensure consistent client and server interaction state.

Published 56 original articles · won praise 0 · Views 7764

Guess you like

Origin blog.csdn.net/chainhou/article/details/104929602