@Override public void handleRequest(final HttpServerExchange exchange) { final Deque<String> origin = exchange.getRequestHeaders().get(Headers.ORIGIN); if (origin == null) { if (requireOriginHeader) { // TODO: Is 403 (Forbidden) the best response code if (UndertowLogger.REQUEST_LOGGER.isDebugEnabled()) { UndertowLogger.REQUEST_LOGGER.debugf( "Refusing request for %s due to lack of Origin: header", exchange.getRequestPath()); } HttpHandlers.executeHandler(originFailedHandler, exchange); return; } } else { boolean found = false; final boolean requireAllOrigins = this.requireAllOrigins; for (final String header : origin) { if (allowedOrigins.contains(header)) { found = true; if (!requireAllOrigins) { break; } } else if (requireAllOrigins) { if (UndertowLogger.REQUEST_LOGGER.isDebugEnabled()) { UndertowLogger.REQUEST_LOGGER.debugf( "Refusing request for %s due to Origin %s not being in the allowed origins list", exchange.getRequestPath(), header); } HttpHandlers.executeHandler(originFailedHandler, exchange); return; } } if (!found) { if (UndertowLogger.REQUEST_LOGGER.isDebugEnabled()) { UndertowLogger.REQUEST_LOGGER.debugf( "Refusing request for %s as none of the specified origins %s were in the allowed origins list", exchange.getRequestPath(), origin); } HttpHandlers.executeHandler(originFailedHandler, exchange); return; } } HttpHandlers.executeHandler(next, exchange); }
@Override public void emitHeader(HttpString name, String value, boolean neverIndex) { headerMap.add(name, value); for (int i = 0; i < name.length(); ++i) { byte c = name.byteAt(i); if (c >= 'A' && c <= 'Z') { invalid = true; UndertowLogger.REQUEST_LOGGER.debugf( "Malformed request, header %s contains uppercase characters", name); } } }
@Override public void handleEvent(SpdyChannel channel) { try { SpdyStreamSourceChannel result = channel.receive(); if (result instanceof SpdySynReplyStreamSourceChannel) { final int streamId = ((SpdySynReplyStreamSourceChannel) result).getStreamId(); SpdyClientExchange request = currentExchanges.get(streamId); result.addCloseTask( new ChannelListener<SpdyStreamSourceChannel>() { @Override public void handleEvent(SpdyStreamSourceChannel channel) { currentExchanges.remove(streamId); } }); if (request == null) { // server side initiated stream, we can't deal with that at the moment // just fail // TODO: either handle this properly or at the very least send RST_STREAM channel.sendGoAway(SpdyChannel.CLOSE_PROTOCOL_ERROR); IoUtils.safeClose(SpdyClientConnection.this); return; } request.responseReady((SpdySynReplyStreamSourceChannel) result); } else if (result instanceof SpdyPingStreamSourceChannel) { handlePing((SpdyPingStreamSourceChannel) result); } else if (result instanceof SpdyRstStreamStreamSourceChannel) { int stream = ((SpdyRstStreamStreamSourceChannel) result).getStreamId(); UndertowLogger.REQUEST_LOGGER.debugf("Client received RST_STREAM for stream %s", stream); SpdyClientExchange exchange = currentExchanges.get(stream); if (exchange != null) { exchange.failed(UndertowMessages.MESSAGES.spdyStreamWasReset()); } } else if (!channel.isOpen()) { throw UndertowMessages.MESSAGES.channelIsClosed(); } } catch (IOException e) { UndertowLogger.REQUEST_IO_LOGGER.ioException(e); IoUtils.safeClose(SpdyClientConnection.this); for (Map.Entry<Integer, SpdyClientExchange> entry : currentExchanges.entrySet()) { try { entry.getValue().failed(e); } catch (Exception ex) { UndertowLogger.REQUEST_IO_LOGGER.ioException(new IOException(ex)); } } } }
@Override public void handleRequest(HttpServerExchange exchange) throws Exception { HeaderMap requestHeaders = exchange.getRequestHeaders(); final String sessionId = requestHeaders.getFirst(SSL_SESSION_ID); if (sessionId != null) { final String cipher = requestHeaders.getFirst(SSL_CIPHER); String clientCert = requestHeaders.getFirst(SSL_CLIENT_CERT); // the proxy client replaces \n with ' ' if (clientCert != null && clientCert.length() > 28) { StringBuilder sb = new StringBuilder(clientCert.length() + 1); sb.append(Certificates.BEGIN_CERT); sb.append('\n'); sb.append( clientCert .replace(' ', '\n') .substring(28, clientCert.length() - 26)); // core certificate data sb.append('\n'); sb.append(Certificates.END_CERT); clientCert = sb.toString(); } try { SSLSessionInfo info = new BasicSSLSessionInfo(sessionId, cipher, clientCert); exchange.setRequestScheme(HTTPS); exchange.getConnection().setSslSessionInfo(info); exchange.addExchangeCompleteListener(CLEAR_SSL_LISTENER); } catch (java.security.cert.CertificateException e) { UndertowLogger.REQUEST_LOGGER.debugf( e, "Could not create certificate from header %s", clientCert); } catch (CertificateException e) { UndertowLogger.REQUEST_LOGGER.debugf( e, "Could not create certificate from header %s", clientCert); } } next.handleRequest(exchange); }
@Override public Session createSession( final HttpServerExchange serverExchange, final SessionConfig config) { if (evictionQueue != null) { if (expireOldestUnusedSessionOnMax) { while (sessions.size() >= maxSize && !evictionQueue.isEmpty()) { String key = evictionQueue.poll(); UndertowLogger.REQUEST_LOGGER.debugf("Removing session %s as max size has been hit", key); SessionImpl toRemove = sessions.get(key); if (toRemove != null) { toRemove.invalidate( null, SessionListener.SessionDestroyedReason.TIMEOUT); // todo: better reason } } } else if (sessions.size() >= maxSize) { if (statisticsEnabled) { rejectedSessionCount.incrementAndGet(); } throw UndertowMessages.MESSAGES.tooManySessions(maxSize); } } if (config == null) { throw UndertowMessages.MESSAGES.couldNotFindSessionCookieConfig(); } String sessionID = config.findSessionId(serverExchange); int count = 0; while (sessionID == null) { sessionID = sessionIdGenerator.createSessionId(); if (sessions.containsKey(sessionID)) { sessionID = null; } if (count++ == 100) { // this should never happen // but we guard against pathalogical session id generators to prevent an infinite loop throw UndertowMessages.MESSAGES.couldNotGenerateUniqueSessionId(); } } Object evictionToken; if (evictionQueue != null) { evictionToken = evictionQueue.offerLastAndReturnToken(sessionID); } else { evictionToken = null; } if (statisticsEnabled) { createdSessionCount.incrementAndGet(); } final SessionImpl session = new SessionImpl( this, sessionID, config, serverExchange.getIoThread(), serverExchange.getConnection().getWorker(), evictionToken, defaultSessionTimeout); sessions.put(sessionID, session); config.setSessionId(serverExchange, session.getId()); session.lastAccessed = System.currentTimeMillis(); session.bumpTimeout(); sessionListeners.sessionCreated(session, serverExchange); serverExchange.putAttachment(NEW_SESSION, session); return session; }