SipParser { public static Object[] consumeVia(final Buffer buffer) throws SipParseException, IOException { final Object[] result = new Object[4]; int count = 0; int indexOfSemi = 0; int countOfColons = 0; int indexOfLastColon = 0; int readerIndexOfLastColon = 0; consumeSWS(buffer); result[0] = consumeSentProtocol(buffer); if(consumeLWS(buffer) == 0){ throw new SipParseException(buffer.getReaderIndex(), "Expected at least 1 WSP"); } final int index = buffer.getReaderIndex(); while (indexOfSemi == 0 && buffer.hasReadableBytes() && ++count < MAX_LOOK_AHEAD) { final byte b = buffer.readByte(); if (b == SipParser.SEMI) { indexOfSemi = count; } else if (b == SipParser.COLON) { ++countOfColons; indexOfLastColon = count; readerIndexOfLastColon = buffer.getReaderIndex(); } } if (count == 0) { return null; } if (count == MAX_LOOK_AHEAD) { throw new SipParseException(buffer.getReaderIndex(), "Unable to find the parameters part of the Via-header " + "even after searching for " + MAX_LOOK_AHEAD + " bytes."); } if (indexOfSemi == 0) { throw new SipParseException(buffer.getReaderIndex(), "No via-parameters found. The Via-header MUST contain at least the branch parameter."); } buffer.setReaderIndex(index); if (countOfColons == 0 || countOfColons == 7) { result[1] = buffer.readBytes(indexOfSemi - 1); } else if (indexOfLastColon != 0 && (countOfColons == 1 || countOfColons == 8)) { result[1] = buffer.readBytes(indexOfLastColon - 1); buffer.readByte(); result[2] = buffer.readBytes(indexOfSemi - indexOfLastColon - 1); if (result[2] == null || ((Buffer) result[2]).isEmpty()) { throw new SipParseException(readerIndexOfLastColon + 1, "Expected port after colon"); } } else { throw new SipParseException(indexOfLastColon, "Found " + countOfColons + " which seems odd." + " Expecting 0, 1, 7 or 8 colons in the Via-host:port portion. Please check your traffic"); } final List<Buffer[]> params = consumeGenericParams(buffer); result[3] = params; return result; }  static Function<SipHeader, ? extends SipHeader> getFramer(final Buffer b); static void expectSIP2_0(final Buffer buffer); static Buffer expectMethod(final Buffer buffer); static boolean isUDP(final Buffer t); static boolean isTCP(final Buffer t); static boolean isTLS(final Buffer t); static boolean isWS(final Buffer t); static boolean isWSS(final Buffer t); static boolean isSCTP(final Buffer t); static boolean isUDPLower(final Buffer t); static boolean isTCPLower(final Buffer t); static boolean isTLSLower(final Buffer t); static boolean isWSLower(final Buffer t); static boolean isWSSLower(final Buffer t); static boolean isSCTPLower(final Buffer t); static void expectTel(final Buffer buffer); static boolean isSips(final Buffer buffer); static List<Buffer[]> consumeGenericParams(final Buffer buffer); static Buffer[] consumeGenericParam(final Buffer buffer); static boolean isNext(final Buffer buffer, final byte b); static boolean isNextDigit(final Buffer buffer); static Buffer expectDigit(final Buffer buffer); static int expectHCOLON(final Buffer buffer); static int expectHCOLONStreamFriendly(final Buffer buffer); static int consumeSWSAfterHColon(final Buffer buffer); static void expectSLASH(final Buffer buffer); static int consumeSLASH(final Buffer buffer); static int expectWS(final Buffer buffer); static int consumeSWS(final Buffer buffer); static int consumeSTAR(final Buffer buffer); static int consumeEQUAL(final Buffer buffer); static int consumeLPAREN(final Buffer buffer); static int consumeRPAREN(final Buffer buffer); static int consumeRAQUOT(final Buffer buffer); static int consumeLAQUOT(final Buffer buffer); static int consumeCOMMA(final Buffer buffer); static int consumeSEMI(final Buffer buffer); static int consumeCOLON(final Buffer buffer); static int consumeLDQUOT(final Buffer buffer); static int consumeRDQUOT(final Buffer buffer); static Buffer expectToken(final Buffer buffer); static Buffer consumeQuotedString(final Buffer buffer); static Buffer consumeDisplayName(final Buffer buffer); static Buffer consumeDisplayName(final boolean quoted, final Buffer buffer); static Buffer consumeAddressSpec(final Buffer buffer); static Buffer consumeAddressSpec(final boolean isProtected, final Buffer buffer); static SipUserHostInfo consumeUserInfoHostPort(final Buffer buffer); static Buffer consumeSentProtocol(final Buffer buffer); static Buffer consumeToken(final Buffer buffer); static Buffer consumeAlphaNum(final Buffer buffer); static Object[] consumeVia(final Buffer buffer); static Buffer[] consumeSentBye(final Buffer buffer); static Buffer consumePort(final Buffer buffer); static Buffer consumeHostname(final Buffer buffer); static Buffer consumeMType(final Buffer buffer); static Buffer consumeMSubtype(final Buffer buffer); static int getTokenCount(final Buffer buffer); static int getAlphaNumCount(final Buffer buffer); static boolean isNextAlphaNum(final Buffer buffer); static boolean isHostPortCharacter(final char ch); static boolean isHostPortCharacter(final byte b); static boolean isAlphaNum(final char ch); static boolean isAlphaNum(final byte b); static boolean isDigit(final char ch); static boolean isDigit(final byte b); static boolean isAlpha(final char ch); static boolean isAlpha(final byte b); static int consumeLWS(final Buffer buffer); static int consumeCRLF(final Buffer buffer); static void expect(final Buffer buffer, final byte expected); static int consumeWS(final Buffer buffer); static void expect(final Buffer buffer, final char ch); static Buffer nextHeaderNameDontCheckHColon(final Buffer buffer); static Buffer nextHeaderName(final Buffer buffer); static List<SipHeader> nextHeaders(final Buffer buffer); static HeaderValueState readHeaderValues(final HeaderValueState state, final Buffer headerName, final Buffer buffer); static HeaderValueState readHeaderValues(final Buffer headerName, final Buffer buffer); static SipHeader nextHeader(final Buffer buffer); static SipMessage frame(final Buffer buffer); static boolean couldBeSipMessage(final Buffer data); static boolean couldBeSipMessage(final byte a, final byte b, final byte c); static final int MAX_LOOK_AHEAD; static final Buffer INVITE; static final Buffer ACK; static final Buffer CANCEL; static final Buffer BYE; static final Buffer SUBSCRIBE; static final Buffer NOTIFY; static final Buffer PUBLISH; static final Buffer INFO; static final Buffer OPTIONS; static final Buffer REGISTER; static final Buffer PRACK; static final Buffer REFER; static final Buffer MESSAGE; static final Buffer UPDATE; static final Buffer TAG; static final Buffer USER; static final Buffer TTL; static final Buffer MADDR; static final Buffer METHOD; static final Buffer TRANSPORT; static final Buffer TRANSPORT_EQ; static final Buffer SIP2_0; static final Buffer SIP2_0_SLASH; static final Buffer SCHEME_SIP; static final Buffer SCHEME_SIP_COLON; static final Buffer SCHEME_SIPS; static final Buffer SCHEME_SIPS_COLON; static final Buffer SCHEME_TEL; static final Buffer SCHEME_TEL_COLON; static final byte AT; static final byte COLON; static final byte SEMI; static final byte DOUBLE_QOUTE; static final byte CR; static final byte LF; static final byte SP; static final byte HTAB; static final byte DASH; static final byte PERIOD; static final byte COMMA; static final byte EXCLAMATIONPOINT; static final byte PERCENT; static final byte STAR; static final byte UNDERSCORE; static final byte QUESTIONMARK; static final byte PLUS; static final byte BACKTICK; static final byte TICK; static final byte TILDE; static final byte EQ; static final byte SLASH; static final byte BACK_SLASH; static final byte LPAREN; static final byte RPAREN; static final byte RAQUOT; static final byte LAQUOT; static final byte DQUOT; static final Buffer UDP; static final Buffer TCP; static final Buffer TLS; static final Buffer SCTP; static final Buffer WS; static final Buffer WSS; static final Map<Buffer, Function<SipHeader, ? extends SipHeader>> framers; }
@Test public void testConsumeVia() throws Exception { assertVia("SIP/2.0/UDP 127.0.0.1:5088;branch=asdf", "UDP", "127.0.0.1", "5088", null, "branch", "asdf"); assertVia("SIP/2.0/UDP 127.0.0.1;branch=asdf", "UDP", "127.0.0.1", null, null, "branch", "asdf"); assertVia("SIP/2.0/UDP 127.0.0.1;branch=asdf;rport", "UDP", "127.0.0.1", null, null, "branch", "asdf", "rport", null); assertVia("SIP/2.0/TCP 127.0.0.1;branch=asdf;apa=monkey", "TCP", "127.0.0.1", null, null, "branch", "asdf", "apa", "monkey"); assertVia("SIP/2.0/TLS test.aboutsip.com;ttl=45;branch=asdf;apa=monkey", "TLS", "test.aboutsip.com", null, null, "ttl", "45", "branch", "asdf", "apa", "monkey"); final String ipv6 = "2001:0db8:85a3:0042:1000:8a2e:0370:7334"; assertVia("SIP/2.0/UDP " + ipv6 + ";branch=asdf", "UDP", ipv6, null, null, "branch", "asdf"); assertVia("SIP/2.0/UDP " + ipv6 + ":9090;branch=asdf", "UDP", ipv6, "9090", null, "branch", "asdf"); assertVia("SIP/2.0/TLS " + ipv6 + ":9090;rport;branch=asdf", "TLS", ipv6, "9090", null, "rport", null, "branch", "asdf"); }