List of usage examples for io.netty.buffer ByteBuf readableBytes
public abstract int readableBytes();
From source file:com.chiorichan.http.HttpHandler.java
License:Mozilla Public License
/** * Handles the HTTP request. Each HTTP subsystem will be explicitly activated until a resolve is determined. * * @throws IOException/*from www. j a va2s. c o m*/ * Universal exception for all Input/Output errors * @throws HttpError * for HTTP Errors * @throws PermissionException * for permission problems, like access denied * @throws MultipleException * for multiple Scripting Factory Evaluation Exceptions * @throws ScriptingException * for Scripting Factory Evaluation Exception * @throws SessionException * for problems initializing a new or used session */ private void handleHttp() throws Exception // IOException, HttpError, SiteException, PermissionException, MultipleException, ScriptingException, SessionException { log.log(Level.INFO, request.methodString() + " " + request.getFullUrl()); Session sess = request.startSession(); log.log(Level.FINE, "Session {id=%s,timeout=%s,new=%s}", sess.getSessId(), sess.getTimeout(), sess.isNew()); if (response.getStage() == HttpResponseStage.CLOSED) throw new IOException("Connection reset by peer"); // This is not the only place 'Connection reset by peer' is thrown RequestEvent requestEvent = new RequestEvent(request); try { EventBus.instance().callEventWithException(requestEvent); } catch (EventException ex) { throw new IOException( "Exception encountered during request event call, most likely the fault of a plugin.", ex); } response.setStatus(requestEvent.getStatus()); if (requestEvent.isCancelled()) { int status = requestEvent.getStatus(); String reason = requestEvent.getReason(); if (status == 200) { status = 502; reason = "Navigation Cancelled by Plugin Event"; } NetworkManager.getLogger().warning("Navigation was cancelled by a Plugin Event"); throw new HttpError(status, reason); } if (response.isCommitted()) return; // Throws IOException and HttpError fi = new WebInterpreter(request); response.annotations.putAll(fi.getAnnotations()); currentSite = request.getLocation(); sess.setSite(currentSite); if (request.getSubdomain().length() > 0 && !currentSite.getSubdomain(request.getSubdomain()).isMaped(request.getDomain())) { if ("www".equalsIgnoreCase(request.getSubdomain()) || AppConfig.get().getBoolean("sites.redirectMissingSubDomains")) { log.log(Level.SEVERE, "Redirecting non-existent subdomain '%s' to root domain '%s'", request.getSubdomain(), request.getFullUrl("")); response.sendRedirect(request.getFullUrl("")); } else { log.log(Level.SEVERE, "The requested subdomain '%s' is non-existent.", request.getSubdomain(), request.getFullDomain("")); response.sendError(HttpResponseStatus.NOT_FOUND, "Subdomain not found"); } return; } File docRoot = currentSite.getSubdomain(request.getSubdomain()).directory(); Validate.notNull(docRoot); if (sess.isLoginPresent()) log.log(Level.FINE, "Account {id=%s,displayName=%s}", sess.getId(), sess.getDisplayName()); /* * Start: SSL enforcer * * Acts on the value of annotation 'SSL'. * REQUIRED means a forbidden error will be thrown is it can not be accomplished * * Options include: * Preferred: If SSL is available, we preferred to be switched to it * PostOnly: SSL is REQUIRED is this is a POST request * GetOnly: SSL is REQUIRED if this is a GET request * Required: SSL is REQUIRED, no exceptions! * Deny: SSL is DENIED, no exceptions! * Ignore: We don't care one way or other, do nothing! DEFAULT */ SslLevel sslLevel = SslLevel.parse(fi.get("ssl")); boolean required = false; switch (sslLevel) { case Preferred: if (NetworkManager.isHttpsRunning()) required = true; break; case PostOnly: if (request.method() == HttpMethod.POST) required = true; break; case GetOnly: if (request.method() == HttpMethod.GET) required = true; break; case Required: required = true; break; case Deny: if (ssl) { if (!response.switchToUnsecure()) response.sendError(HttpCode.HTTP_FORBIDDEN, "This page requires an unsecure connection."); return; } break; case Ignore: break; } if (required && !ssl) { if (!response.switchToSecure()) response.sendError(HttpCode.HTTP_FORBIDDEN, "This page requires a secure connection."); return; } /* * End: SSL enforcer */ if (fi.getStatus() != HttpResponseStatus.OK) throw new HttpError(fi.getStatus()); /* * Start: Apache Configuration Section * * Loads a Apache configuration and .htaccess files into a common handler, then parsed for directives like access restrictions and basic auth * TODO Load server-wide Apache Configuration then merge with Site Configuration */ ApacheHandler htaccess = new ApacheHandler(); response.setApacheParser(htaccess); try { boolean result = htaccess.handleDirectives(currentSite.getApacheConfig(), this); if (htaccess.overrideNone() || htaccess.overrideListNone()) // Ignore .htaccess files { if (fi.hasFile()) if (!htaccess.handleDirectives(new ApacheConfiguration(fi.getFile().getParentFile()), this)) result = false; if (!htaccess.handleDirectives(new ApacheConfiguration(docRoot), this)) result = false; } if (!result) { if (!response.isCommitted()) response.sendError(500, "Your request was blocked by an internal configuration directive, exact details are unknown."); return; } } catch (ApacheDirectiveException e) { log.log(Level.SEVERE, "Caught Apache directive exception: " + e.getMessage()); // TODO Throw 500 unless told not to } /* * End: Apache Configuration Section */ if (!fi.hasFile() && !fi.hasHTML()) response.setStatus(HttpResponseStatus.NO_CONTENT); sess.setGlobal("__FILE__", fi.getFile()); request.putRewriteParams(fi.getRewriteParams()); response.setContentType(fi.getContentType()); response.setEncoding(fi.getEncoding()); request.getServer().put(ServerVars.DOCUMENT_ROOT, docRoot); request.setGlobal("_SERVER", request.getServer()); request.setGlobal("_POST", request.getPostMap()); request.setGlobal("_GET", request.getGetMap()); request.setGlobal("_REWRITE", request.getRewriteMap()); request.setGlobal("_FILES", request.getUploadedFiles()); // TODO Implement NONCE requirement for login page NonceLevel level = NonceLevel.parse(fi.get("nonce")); boolean nonceProvided = sess.nonce() == null ? false : request.getRequestMap().get(sess.nonce().key()) != null; boolean processNonce = false; switch (level) { case Required: processNonce = true; break; case GetOnly: processNonce = request.method() == HttpMethod.GET || nonceProvided; break; case PostOnly: processNonce = request.method() == HttpMethod.POST || nonceProvided; break; case Flexible: processNonce = nonceProvided; break; case Disabled: default: // Do Nothing } Map<String, String> nonceMap = Maps.newHashMap(); if (processNonce) { if (!nonceProvided) { log.log(Level.SEVERE, "The request has failed NONCE validation, because the nonce key was not present!"); response.sendError(HttpResponseStatus.FORBIDDEN, "Your request has failed NONCE validation!"); return; } Nonce nonce = sess.nonce(); if (level == NonceLevel.Required) // Required NonceLevels are of the highest protected state sess.destroyNonce(); try { if (!(request.getRequestMap().get(nonce.key()) instanceof String)) throw new NonceException("Nonce token is not a string"); nonce.validateWithException((String) request.getRequestMap().get(nonce.key())); } catch (NonceException e) { log.log(Level.SEVERE, "The request has failed NONCE validation, because " + e.getMessage().toLowerCase() + "!"); response.sendError(HttpResponseStatus.FORBIDDEN, "Your request has failed NONCE validation!"); sess.destroyNonce(); return; } finally { log.log(Level.INFO, "The request has passed the NONCE validation!"); request.nonceProcessed(true); nonceMap = nonce.mapValues(); } } if (request.validateLogins()) return; if (level != NonceLevel.Disabled) request.setGlobal("_NONCE", nonceMap); try { if (request.getUploadedFiles().size() > 0) log.log(Level.INFO, "Uploads {" + StringFunc.limitLength( Joiner.on(",").skipNulls().join(request.getUploadedFiles().values()), 255) + "}"); if (request.getGetMap().size() > 0) log.log(Level.INFO, "Params GET {" + StringFunc.limitLength( Joiner.on(",").withKeyValueSeparator("=").useForNull("null").join(request.getGetMap()), 255) + "}"); if (request.getPostMap().size() > 0) log.log(Level.INFO, "Params POST {" + StringFunc.limitLength( Joiner.on(",").withKeyValueSeparator("=").useForNull("null").join(request.getPostMap()), 255) + "}"); if (request.getRewriteMap().size() > 0) log.log(Level.INFO, "Params REWRITE {" + StringFunc.limitLength( Joiner.on(",").withKeyValueSeparator("=").useForNull("null").join(request.getRewriteMap()), 255) + "}"); if (fi.getAnnotations().size() > 0) log.log(Level.INFO, "Params ANNOTATIONS {" + StringFunc.limitLength( Joiner.on(",").withKeyValueSeparator("=").useForNull("null").join(fi.getAnnotations()), 255) + "}"); } catch (Throwable t) { t.printStackTrace(); } if (AppConfig.get().getBoolean("advanced.security.requestMapEnabled", true)) request.setGlobal("_REQUEST", request.getRequestMap()); ByteBuf rendered = Unpooled.buffer(); ScriptingFactory factory = request.getEvalFactory(); factory.setEncoding(fi.getEncoding()); NetworkSecurity.isForbidden(htaccess, currentSite, fi); String req = fi.get("reqperm"); if (req == null) req = "-1"; sess.requirePermission(req, currentSite.getId()); // Enhancement: Allow HTML to be ran under different shells. Default is embedded. if (fi.hasHTML()) { ScriptingResult result = factory.eval( ScriptingContext.fromSource(fi.getHTML(), "<embedded>").request(request).site(currentSite)); if (result.hasExceptions()) // TODO Print notices to output like PHP does for (ScriptingException e : result.getExceptions()) { ExceptionReport.throwExceptions(e); log.exceptions(e); if (e.reportingLevel().isEnabled()) rendered.writeBytes(e.getMessage().getBytes()); } if (result.isSuccessful()) { rendered.writeBytes(result.content()); if (result.getObject() != null && !(result.getObject() instanceof NullObject)) try { rendered.writeBytes(ObjectFunc.castToStringWithException(result.getObject()).getBytes()); } catch (Exception e) { log.log(Level.SEVERE, "Exception Excountered: %s", e.getMessage()); if (Versioning.isDevelopment()) log.log(Level.SEVERE, e.getStackTrace()[0].toString()); } } log.log(Level.INFO, "EvalHtml {timing=%sms,success=%s}", Timings.mark(this), result.isSuccessful()); } if (fi.hasFile()) { if (fi.isDirectoryRequest()) { processDirectoryListing(); return; } ScriptingResult result = factory.eval(ScriptingContext.fromFile(fi).request(request).site(currentSite)); if (result.hasExceptions()) // TODO Print notices to output like PHP does for (ScriptingException e : result.getExceptions()) { ExceptionReport.throwExceptions(e); log.exceptions(e); if (e.reportingLevel().isEnabled() && e.getMessage() != null) rendered.writeBytes(e.getMessage().getBytes()); } if (result.isSuccessful()) { rendered.writeBytes(result.content()); if (result.getObject() != null && !(result.getObject() instanceof NullObject)) try { rendered.writeBytes(ObjectFunc.castToStringWithException(result.getObject()).getBytes()); } catch (Exception e) { rendered.writeBytes(result.getObject().toString().getBytes()); log.log(Level.SEVERE, "Exception encountered while writing returned object to output. %s", e.getMessage()); if (Versioning.isDevelopment()) log.log(Level.SEVERE, e.getStackTrace()[0].toString()); } } log.log(Level.INFO, "EvalFile {file=%s,timing=%sms,success=%s}", fi.getFilePath(), Timings.mark(this), result.isSuccessful()); } // if the connection was in a MultiPart mode, wait for the mode to change then return gracefully. if (response.stage == HttpResponseStage.MULTIPART) { while (response.stage == HttpResponseStage.MULTIPART) // I wonder if there is a better way to handle multipart responses. try { Thread.sleep(100); } catch (InterruptedException e) { throw new HttpError(500, "Internal Server Error encountered during multipart execution."); } return; } // If the connection was closed from page redirect, return gracefully. else if (response.stage == HttpResponseStage.CLOSED || response.stage == HttpResponseStage.WRITTEN) return; // Allows scripts to directly override interpreter values. For example: Themes, Views, Titles for (Entry<String, String> kv : response.annotations.entrySet()) fi.put(kv.getKey(), kv.getValue()); RenderEvent renderEvent = new RenderEvent(this, rendered, fi.getEncoding(), fi.getAnnotations()); try { EventBus.instance().callEventWithException(renderEvent); if (renderEvent.getSource() != null) rendered = renderEvent.getSource(); } catch (EventException ex) { throw new ScriptingException(ReportingLevel.E_ERROR, "Caught EventException while trying to fire the RenderEvent", ex.getCause()); } log.log(Level.INFO, "Written {bytes=%s,total_timing=%sms}", rendered.readableBytes(), Timings.finish(this)); try { response.write(rendered); } catch (IllegalReferenceCountException e) { log.log(Level.SEVERE, "Exception encountered while writting script object to output, %s", e.getMessage()); } }
From source file:com.chiorichan.http.ssl.SniNegotiator.java
License:Mozilla Public License
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { if (!handshaken && in.readableBytes() >= 5) { String hostname = sniHostNameFromHandshakeInfo(in); if (hostname != null) hostname = IDN.toASCII(hostname, IDN.ALLOW_UNASSIGNED).toLowerCase(Locale.US); this.hostname = hostname; selectedContext = SslManager.instance().map(hostname); if (handshaken) { SSLEngine engine = selectedContext.newEngine(ctx.alloc()); List<String> supportedCipherSuites = Arrays.asList(engine.getSupportedCipherSuites()); if (!supportedCipherSuites.containsAll(enabledCipherSuites)) for (String cipher : enabledCipherSuites) if (!supportedCipherSuites.contains(cipher)) { NetworkManager.getLogger() .severe(String.format( "The SSL/TLS cipher suite '%s' is not supported by SSL Provider %s", cipher, SslContext.defaultServerProvider().name())); enabledCipherSuites.remove(cipher); }/*from w ww . j a va 2 s . c om*/ engine.setUseClientMode(false); engine.setEnabledCipherSuites(enabledCipherSuites.toArray(new String[0])); ctx.pipeline().replace(this, ctx.name(), new SslExceptionHandler(engine)); } } }
From source file:com.chiorichan.http.ssl.SniNegotiator.java
License:Mozilla Public License
private String sniHostNameFromHandshakeInfo(ByteBuf in) { int readerIndex = in.readerIndex(); try {/* w w w .j a v a2s . c o m*/ int command = in.getUnsignedByte(readerIndex); // tls, but not handshake command switch (command) { case SslConstants.SSL_CONTENT_TYPE_CHANGE_CIPHER_SPEC: case SslConstants.SSL_CONTENT_TYPE_ALERT: case SslConstants.SSL_CONTENT_TYPE_APPLICATION_DATA: return null; case SslConstants.SSL_CONTENT_TYPE_HANDSHAKE: break; default: //not tls or sslv3, do not try sni handshaken = true; return null; } int majorVersion = in.getUnsignedByte(readerIndex + 1); // SSLv3 or TLS if (majorVersion == 3) { int packetLength = in.getUnsignedShort(readerIndex + 3) + 5; if (in.readableBytes() >= packetLength) { // decode the ssl client hello packet // we have to skip some var-length fields int offset = readerIndex + 43; int sessionIdLength = in.getUnsignedByte(offset); offset += sessionIdLength + 1; int cipherSuitesLength = in.getUnsignedShort(offset); offset += cipherSuitesLength + 2; int compressionMethodLength = in.getUnsignedByte(offset); offset += compressionMethodLength + 1; int extensionsLength = in.getUnsignedShort(offset); offset += 2; int extensionsLimit = offset + extensionsLength; while (offset < extensionsLimit) { int extensionType = in.getUnsignedShort(offset); offset += 2; int extensionLength = in.getUnsignedShort(offset); offset += 2; // SNI if (extensionType == 0) { handshaken = true; int serverNameType = in.getUnsignedByte(offset + 2); if (serverNameType == 0) { int serverNameLength = in.getUnsignedShort(offset + 3); return in.toString(offset + 5, serverNameLength, CharsetUtil.UTF_8); } else // invalid enum value return null; } offset += extensionLength; } handshaken = true; return null; } else // client hello incomplete return null; } else { handshaken = true; return null; } } catch (Throwable e) { // unexpected encoding, ignore sni and use default if (logger.isDebugEnabled()) logger.debug("Unexpected client hello packet: " + ByteBufUtil.hexDump(in), e); handshaken = true; return null; } }
From source file:com.chiorichan.util.ServerFunc.java
License:Mozilla Public License
public static byte[] byteBuf2Bytes(ByteBuf buf) { byte[] bytes = new byte[buf.readableBytes()]; int readerIndex = buf.readerIndex(); buf.getBytes(readerIndex, bytes);//from www .j a va 2s . c o m return bytes; }
From source file:com.chuck.netty4.websocket.WebSocketIndexPageHandler.java
License:Apache License
@Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception { // Handle a bad request. if (!req.decoderResult().isSuccess()) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST)); return;/* w w w . j av a2 s . co m*/ } // Allow only GET methods. if (req.method() != GET) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN)); return; } // Send the index page if ("/".equals(req.uri()) || "/index.html".equals(req.uri())) { String webSocketLocation = getWebSocketLocation(ctx.pipeline(), req, websocketPath); ByteBuf content = WebSocketServerIndexPage.getContent(webSocketLocation); FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, OK, content); res.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8"); HttpUtil.setContentLength(res, content.readableBytes()); sendHttpResponse(ctx, req, res); } else { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND)); } }
From source file:com.cloudera.livy.client.local.rpc.KryoMessageCodec.java
License:Apache License
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { if (in.readableBytes() < 4) { return;//from w ww . jav a 2 s . com } in.markReaderIndex(); int msgSize = in.readInt(); checkSize(msgSize); if (in.readableBytes() < msgSize) { // Incomplete message in buffer. in.resetReaderIndex(); return; } try { ByteBuffer nioBuffer = maybeDecrypt(in.nioBuffer(in.readerIndex(), msgSize)); Object msg = serializer.deserialize(nioBuffer); LOG.debug("Decoded message of type {} ({} bytes)", msg != null ? msg.getClass().getName() : msg, msgSize); out.add(msg); } finally { in.skipBytes(msgSize); } }
From source file:com.cloudhopper.smpp.pdu.BaseBind.java
License:Apache License
@Override public void readBody(ByteBuf buffer) throws UnrecoverablePduException, RecoverablePduException { this.systemId = ChannelBufferUtil.readNullTerminatedString(buffer); this.password = ChannelBufferUtil.readNullTerminatedString(buffer); this.systemType = ChannelBufferUtil.readNullTerminatedString(buffer); // at this point, we should have at least 3 bytes left if (buffer.readableBytes() < 3) { throw new NotEnoughDataInBufferException("After parsing systemId, password, and systemType", buffer.readableBytes(), 3); }/* w w w. jav a2 s . c o m*/ this.interfaceVersion = buffer.readByte(); this.addressRange = ChannelBufferUtil.readAddress(buffer); }
From source file:com.cloudhopper.smpp.pdu.BufferHelper.java
License:Apache License
static public byte[] createByteArray(ByteBuf buffer) throws Exception { byte[] bytes = new byte[buffer.readableBytes()]; // temporarily read bytes from the buffer buffer.getBytes(buffer.readerIndex(), bytes); return bytes; }
From source file:com.cloudhopper.smpp.pdu.Pdu.java
License:Apache License
public void readOptionalParameters(ByteBuf buffer, PduTranscoderContext context) throws UnrecoverablePduException, RecoverablePduException { // if there is any data left, it's part of an optional parameter while (buffer.readableBytes() > 0) { Tlv tlv = ChannelBufferUtil.readTlv(buffer); if (tlv.getTagName() == null) { tlv.setTagName(context.lookupTlvTagName(tlv.getTag())); }//from w w w . j a v a 2 s . c o m this.addOptionalParameter(tlv); } }
From source file:com.cloudhopper.smpp.simulator.SmppSimulatorSessionHandler.java
License:Apache License
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception { // ignore requests with zero bytes if (buffer.readableBytes() <= 0) { return;/*w w w.ja v a2 s. com*/ } // decode the buffer into a pdu Pdu pdu = transcoder.decode(buffer); // if the pdu was null, we don't have enough data yet if (pdu == null) { logger.info("Received data on channel {}, but not enough to parse PDU fully yet", channel.toString()); logger.info("Bytes in buffer: [{}]", ByteBufUtil.hexDump(buffer)); return; } logger.info("Decoded buffer on channel {} into PDU: {}", channel.toString(), pdu); // if we have a pdu procesor registered, let's see if it handles it boolean processed = false; if (this.pduProcessor != null) { processed = this.pduProcessor.process(this, channel, pdu); } if (processed) { logger.info("This PDU was processed by the registered PduProcessor"); } else { this.pduQueue.add(pdu); } // is there a PDU someone wants us to write in response? if (this.writePduQueue.size() > 0) { Pdu pduToWrite = this.writePduQueue.remove(); logger.info("Automatically writing back on channel {} the PDU: {}", channel.toString(), pduToWrite); ByteBuf writeBuffer = this.transcoder.encode(pduToWrite); channel.writeAndFlush(writeBuffer); } out.add(pdu); }