use of io.undertow.util.HeaderMap in project undertow by undertow-io.
the class DigestAuthenticationMechanism method sendChallenge.
@Override
public ChallengeResult sendChallenge(final HttpServerExchange exchange, final SecurityContext securityContext) {
DigestContext context = exchange.getAttachment(DigestContext.ATTACHMENT_KEY);
boolean stale = context == null ? false : context.isStale();
StringBuilder rb = new StringBuilder(DIGEST_PREFIX);
rb.append(Headers.REALM.toString()).append("=\"").append(realmName).append("\",");
rb.append(Headers.DOMAIN.toString()).append("=\"").append(domain).append("\",");
// based on security constraints.
rb.append(Headers.NONCE.toString()).append("=\"").append(nonceManager.nextNonce(null, exchange)).append("\",");
// Not currently using OPAQUE as it offers no integrity, used for session data leaves it vulnerable to
// session fixation type issues as well.
rb.append(Headers.OPAQUE.toString()).append("=\"00000000000000000000000000000000\"");
if (stale) {
rb.append(",stale=true");
}
if (supportedAlgorithms.size() > 0) {
// This header will need to be repeated once for each algorithm.
rb.append(",").append(Headers.ALGORITHM.toString()).append("=%s");
}
if (qopString != null) {
rb.append(",").append(Headers.QOP.toString()).append("=\"").append(qopString).append("\"");
}
String theChallenge = rb.toString();
HeaderMap responseHeader = exchange.getResponseHeaders();
if (supportedAlgorithms.isEmpty()) {
responseHeader.add(WWW_AUTHENTICATE, theChallenge);
} else {
for (DigestAlgorithm current : supportedAlgorithms) {
responseHeader.add(WWW_AUTHENTICATE, String.format(theChallenge, current.getToken()));
}
}
return new ChallengeResult(true, UNAUTHORIZED);
}
use of io.undertow.util.HeaderMap in project undertow by undertow-io.
the class SSLHeaderHandler method handleRequest.
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
HeaderMap requestHeaders = exchange.getRequestHeaders();
final String sessionId = requestHeaders.getFirst(SSL_SESSION_ID);
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');
//core certificate data
sb.append(clientCert.replace(' ', '\n').substring(28, clientCert.length() - 26));
sb.append('\n');
sb.append(Certificates.END_CERT);
clientCert = sb.toString();
}
if (clientCert != null || sessionId != null || cipher != null) {
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 | CertificateException e) {
UndertowLogger.REQUEST_LOGGER.debugf(e, "Could not create certificate from header %s", clientCert);
}
}
next.handleRequest(exchange);
}
use of io.undertow.util.HeaderMap in project undertow by undertow-io.
the class Http2ReceiveListener method handleInitialRequest.
/**
* Handles the initial request when the exchange was started by a HTTP ugprade.
*
*
* @param initial The initial upgrade request that started the HTTP2 connection
*/
void handleInitialRequest(HttpServerExchange initial, Http2Channel channel) {
//we have a request
Http2HeadersStreamSinkChannel sink = channel.createInitialUpgradeResponseStream();
final Http2ServerConnection connection = new Http2ServerConnection(channel, sink, undertowOptions, bufferSize, rootHandler);
HeaderMap requestHeaders = new HeaderMap();
for (HeaderValues hv : initial.getRequestHeaders()) {
requestHeaders.putAll(hv.getHeaderName(), hv);
}
final HttpServerExchange exchange = new HttpServerExchange(connection, requestHeaders, sink.getHeaders(), maxEntitySize);
connection.setExchange(exchange);
exchange.setRequestScheme(initial.getRequestScheme());
exchange.setProtocol(initial.getProtocol());
exchange.setRequestMethod(initial.getRequestMethod());
exchange.setQueryString(initial.getQueryString());
String uri = exchange.getQueryString().isEmpty() ? initial.getRequestURI() : initial.getRequestURI() + '?' + exchange.getQueryString();
try {
Connectors.setExchangeRequestPath(exchange, uri, encoding, decode, allowEncodingSlash, decodeBuffer, maxParameters);
} catch (ParameterLimitException e) {
exchange.setStatusCode(StatusCodes.BAD_REQUEST);
exchange.endExchange();
return;
}
SSLSession session = channel.getSslSession();
if (session != null) {
connection.setSslSessionInfo(new Http2SslSessionInfo(channel));
}
Connectors.terminateRequest(exchange);
sink.setCompletionListener(new ChannelListener<Http2DataStreamSinkChannel>() {
@Override
public void handleEvent(Http2DataStreamSinkChannel channel) {
Connectors.terminateResponse(exchange);
}
});
Connectors.executeRootHandler(rootHandler, exchange);
}
use of io.undertow.util.HeaderMap in project undertow by undertow-io.
the class Http2ServerConnection method pushResource.
@Override
public boolean pushResource(String path, HttpString method, HeaderMap requestHeaders, final HttpHandler handler) {
HeaderMap responseHeaders = new HeaderMap();
try {
requestHeaders.put(Http2ReceiveListener.METHOD, method.toString());
requestHeaders.put(Http2ReceiveListener.PATH, path.toString());
requestHeaders.put(Http2ReceiveListener.AUTHORITY, exchange.getHostAndPort());
requestHeaders.put(Http2ReceiveListener.SCHEME, exchange.getRequestScheme());
Http2HeadersStreamSinkChannel sink = channel.sendPushPromise(responseChannel.getStreamId(), requestHeaders, responseHeaders);
Http2ServerConnection newConnection = new Http2ServerConnection(channel, sink, getUndertowOptions(), getBufferSize(), rootHandler);
final HttpServerExchange exchange = new HttpServerExchange(newConnection, requestHeaders, responseHeaders, getUndertowOptions().get(UndertowOptions.MAX_ENTITY_SIZE, UndertowOptions.DEFAULT_MAX_ENTITY_SIZE));
newConnection.setExchange(exchange);
exchange.setRequestMethod(method);
exchange.setProtocol(Protocols.HTTP_1_1);
exchange.setRequestScheme(this.exchange.getRequestScheme());
try {
Connectors.setExchangeRequestPath(exchange, path, getUndertowOptions().get(UndertowOptions.URL_CHARSET, StandardCharsets.UTF_8.name()), getUndertowOptions().get(UndertowOptions.DECODE_URL, true), getUndertowOptions().get(UndertowOptions.ALLOW_ENCODED_SLASH, false), new StringBuilder(), getUndertowOptions().get(UndertowOptions.MAX_PARAMETERS, UndertowOptions.DEFAULT_MAX_HEADERS));
} catch (ParameterLimitException e) {
UndertowLogger.REQUEST_IO_LOGGER.debug("Too many parameters in HTTP/2 request", e);
exchange.setStatusCode(StatusCodes.BAD_REQUEST);
exchange.endExchange();
return false;
}
Connectors.terminateRequest(exchange);
getIoThread().execute(new Runnable() {
@Override
public void run() {
Connectors.executeRootHandler(handler, exchange);
}
});
return true;
} catch (IOException e) {
UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
return false;
}
}
use of io.undertow.util.HeaderMap in project undertow by undertow-io.
the class AjpServerResponseConduit method processAJPHeader.
/**
* Handles generating the header if required, and adding it to the frame queue.
*
* No attempt is made to actually flush this, so a gathering write can be used to actually flush the data
*/
private void processAJPHeader() {
int oldState = this.state;
if (anyAreSet(oldState, FLAG_START)) {
PooledByteBuffer[] byteBuffers = null;
//merge the cookies into the header map
Connectors.flattenCookies(exchange);
PooledByteBuffer pooled = pool.allocate();
ByteBuffer buffer = pooled.getBuffer();
buffer.put((byte) 'A');
buffer.put((byte) 'B');
//we fill the size in later
buffer.put((byte) 0);
buffer.put((byte) 0);
buffer.put((byte) 4);
putInt(buffer, exchange.getStatusCode());
String reason = exchange.getReasonPhrase();
if (reason == null) {
reason = StatusCodes.getReason(exchange.getStatusCode());
}
if (reason.length() + 4 > buffer.remaining()) {
pooled.close();
throw UndertowMessages.MESSAGES.reasonPhraseToLargeForBuffer(reason);
}
putString(buffer, reason);
int headers = 0;
//we need to count the headers
final HeaderMap responseHeaders = exchange.getResponseHeaders();
for (HttpString name : responseHeaders.getHeaderNames()) {
headers += responseHeaders.get(name).size();
}
putInt(buffer, headers);
for (final HttpString header : responseHeaders.getHeaderNames()) {
for (String headerValue : responseHeaders.get(header)) {
if (buffer.remaining() < header.length() + headerValue.length() + 6) {
//if there is not enough room in the buffer we need to allocate more
buffer.flip();
if (byteBuffers == null) {
byteBuffers = new PooledByteBuffer[2];
byteBuffers[0] = pooled;
} else {
PooledByteBuffer[] old = byteBuffers;
byteBuffers = new PooledByteBuffer[old.length + 1];
System.arraycopy(old, 0, byteBuffers, 0, old.length);
}
pooled = pool.allocate();
byteBuffers[byteBuffers.length - 1] = pooled;
buffer = pooled.getBuffer();
}
Integer headerCode = HEADER_MAP.get(header);
if (headerCode != null) {
putInt(buffer, headerCode);
} else {
putHttpString(buffer, header);
}
putString(buffer, headerValue);
}
}
if (byteBuffers == null) {
int dataLength = buffer.position() - 4;
buffer.put(2, (byte) ((dataLength >> 8) & 0xFF));
buffer.put(3, (byte) (dataLength & 0xFF));
buffer.flip();
queueFrame(new PooledBufferFrameCallback(pooled), buffer);
} else {
ByteBuffer[] bufs = new ByteBuffer[byteBuffers.length];
for (int i = 0; i < bufs.length; ++i) {
bufs[i] = byteBuffers[i].getBuffer();
}
int dataLength = (int) (Buffers.remaining(bufs) - 4);
bufs[0].put(2, (byte) ((dataLength >> 8) & 0xFF));
bufs[0].put(3, (byte) (dataLength & 0xFF));
buffer.flip();
queueFrame(new PooledBuffersFrameCallback(byteBuffers), bufs);
}
state &= ~FLAG_START;
}
}
Aggregations