protected String hvalue() throws ParseException { StringBuffer retval = new StringBuffer(); while (lexer.hasMoreChars()) { char la = lexer.lookAhead(0); // Look for a character that can terminate a URL. if (la == '+' || la == '?' || la == ':' || la == '[' || la == ']' || la == '/' || la == '$' || la == '_' || la == '-' || la == '"' || la == '!' || la == '~' || la == '*' || la == '.' || la == '(' || la == ')' || Lexer.isAlpha(la) || Lexer.isDigit(la)) { lexer.consume(1); retval.append(la); } else if (la == '%') { retval.append(escaped()); } else break; } return retval.toString(); }
/** * Get a dialog identifier. Generates a string that can be used as a dialog identifier. * * @param isServer is set to true if this is the UAS and set to false if this is the UAC */ public String getDialogId(boolean isServer) { CallID cid = (CallID) this.getCallId(); StringBuffer retval = new StringBuffer(cid.getCallId()); From from = (From) this.getFrom(); To to = (To) this.getTo(); if (!isServer) { // retval.append(COLON).append(from.getUserAtHostPort()); if (from.getTag() != null) { retval.append(COLON); retval.append(from.getTag()); } // retval.append(COLON).append(to.getUserAtHostPort()); if (to.getTag() != null) { retval.append(COLON); retval.append(to.getTag()); } } else { // retval.append(COLON).append(to.getUserAtHostPort()); if (to.getTag() != null) { retval.append(COLON); retval.append(to.getTag()); } // retval.append(COLON).append(from.getUserAtHostPort()); if (from.getTag() != null) { retval.append(COLON); retval.append(from.getTag()); } } return retval.toString().toLowerCase(); }
/** Parser for the local phone #. */ private String local_number() throws ParseException { StringBuffer s = new StringBuffer(); if (debug) dbg_enter("local_number"); try { int lc = 0; while (lexer.hasMoreChars()) { char la = lexer.lookAhead(0); if (la == '*' || la == '#' || la == '-' || la == '.' || la == '(' || la == ')' || Lexer.isDigit(la)) { lexer.consume(1); s.append(la); lc++; } else if (lc > 0) break; else throw createParseException("unexepcted " + la); } return s.toString(); } finally { if (debug) dbg_leave("local_number"); } }
protected String uricString() { StringBuffer retval = new StringBuffer(); while (true) { String next = uric(); if (next == null) break; retval.append(next); } return retval.toString(); }
/** Encode the body of this header (the stuff that follows headerName). A.K.A headerValue. */ protected String encodeBody() { StringBuffer encoding = new StringBuffer(); encoding.append(sentProtocol.encode()).append(SP).append(sentBy.encode()); if (!parameters.isEmpty()) { encoding.append(SEMICOLON).append(parameters.encode()); } if (comment != null) { encoding.append(SP).append(LPAREN).append(comment).append(RPAREN); } return encoding.toString(); }
/** * Scan forward until you hit a terminating character for a URL. We do not handle non sip urls in * this implementation. * * @return the string that takes us to the end of this URL (i.e. to the next delimiter). */ protected String urlString() throws ParseException { StringBuffer retval = new StringBuffer(); lexer.selectLexer("charLexer"); while (lexer.hasMoreChars()) { char la = lexer.lookAhead(0); // Look for a character that can terminate a URL. if (la == ' ' || la == '\t' || la == '\n' || la == '>' || la == '<') break; lexer.consume(0); retval.append(la); } return retval.toString(); }
protected String password() throws ParseException { StringBuffer retval = new StringBuffer(); while (true) { char la = lexer.lookAhead(0); if (isUnreserved(la) || la == '&' || la == '=' || la == '+' || la == '$' || la == ',') { retval.append(la); lexer.consume(1); } else if (isEscaped()) { String esc = lexer.charAsString(3); retval.append(esc); lexer.consume(3); // bug reported by // Jeff Haynie } else break; } return retval.toString(); }
protected String escaped() throws ParseException { if (debug) dbg_enter("escaped"); try { StringBuffer retval = new StringBuffer(); char next = lexer.lookAhead(0); char next1 = lexer.lookAhead(1); char next2 = lexer.lookAhead(2); if (next == '%' && Lexer.isHexDigit(next1) && Lexer.isHexDigit(next2)) { lexer.consume(3); retval.append(next); retval.append(next1); retval.append(next2); } else throw createParseException("escaped"); return retval.toString(); } finally { if (debug) dbg_leave("escaped"); } }
/** * read a line of input (I cannot use buffered reader because we may need to switch encodings * mid-stream! */ private String readLine(InputStream inputStream) throws IOException { StringBuffer retval = new StringBuffer(""); while (true) { char ch; int i = inputStream.read(); if (i == -1) { throw new IOException("End of stream"); } else ch = (char) i; // reduce the available read size by 1 ("size" of a char). if (this.maxMessageSize > 0) { this.sizeCounter--; if (this.sizeCounter <= 0) throw new IOException("Max size exceeded!"); } if (ch != '\r') retval.append(ch); if (ch == '\n') { break; } } return retval.toString(); }
/** Parser for the base phone number. */ private String base_phone_number() throws ParseException { StringBuffer s = new StringBuffer(); if (debug) dbg_enter("base_phone_number"); try { int lc = 0; while (lexer.hasMoreChars()) { char w = lexer.lookAhead(0); if (Lexer.isDigit(w) || w == '-' || w == '.' || w == '(' || w == ')') { lexer.consume(1); s.append(w); lc++; } else if (lc > 0) break; else throw createParseException("unexpected " + w); } return s.toString(); } finally { if (debug) dbg_leave("base_phone_number"); } }
protected String user() throws ParseException { if (debug) dbg_enter("user"); try { StringBuffer retval = new StringBuffer(); while (lexer.hasMoreChars()) { char la = lexer.lookAhead(0); // if (la == '=') break; if (isUnreserved(la) || isUserUnreserved(la)) { retval.append(la); lexer.consume(1); } else if (isEscaped()) { String esc = lexer.charAsString(3); lexer.consume(3); retval.append(esc); } else break; } return retval.toString(); } finally { if (debug) dbg_leave("user"); } }
/** Name or value of a parameter. */ protected String paramNameOrValue() throws ParseException { StringBuffer retval = new StringBuffer(); while (lexer.hasMoreChars()) { char next = lexer.lookAhead(0); if (next == '[' || next == '[' || next == '/' || next == ':' || next == '&' || next == '+' || next == '$' || isUnreserved(next)) { retval.append(next); lexer.consume(1); } else if (isEscaped()) { String esc = lexer.charAsString(3); lexer.consume(3); retval.append(esc); } else break; } return retval.toString(); }
/** * This is input reading thread for the pipelined parser. You feed it input through the input * stream (see the constructor) and it calls back an event listener interface for message * processing or error. It cleans up the input - dealing with things like line continuation */ public void run() { Pipeline inputStream = this.rawInputStream; // inputStream = new MyFilterInputStream(this.rawInputStream); // I cannot use buffered reader here because we may need to switch // encodings to read the message body. try { while (true) { this.sizeCounter = this.maxMessageSize; // this.messageSize = 0; StringBuffer inputBuffer = new StringBuffer(); if (Debug.parserDebug) Debug.println("Starting parse!"); String line1; String line2 = null; while (true) { try { line1 = readLine(inputStream); // ignore blank lines. if (line1.equals("\n")) { if (Debug.parserDebug) Debug.println("Discarding " + line1); continue; } else break; } catch (IOException ex) { Debug.printStackTrace(ex); this.rawInputStream.stopTimer(); return; } } inputBuffer.append(line1); // Guard against bad guys. this.rawInputStream.startTimer(); while (true) { try { line2 = readLine(inputStream); inputBuffer.append(line2); if (line2.trim().equals("")) break; } catch (IOException ex) { this.rawInputStream.stopTimer(); Debug.printStackTrace(ex); return; } } // Stop the timer that will kill the read. this.rawInputStream.stopTimer(); inputBuffer.append(line2); StringMsgParser smp = new StringMsgParser(sipMessageListener); smp.readBody = false; SIPMessage sipMessage = null; try { sipMessage = smp.parseSIPMessage(inputBuffer.toString()); if (sipMessage == null) { this.rawInputStream.stopTimer(); continue; } } catch (ParseException ex) { // Just ignore the parse exception. continue; } if (Debug.parserDebug) Debug.println("Completed parsing message"); ContentLength cl = (ContentLength) sipMessage.getContentLength(); int contentLength = 0; if (cl != null) { contentLength = cl.getContentLength(); } else { contentLength = 0; } if (Debug.parserDebug) { Debug.println("contentLength " + contentLength); Debug.println("sizeCounter " + this.sizeCounter); Debug.println("maxMessageSize " + this.maxMessageSize); } if (contentLength == 0) { sipMessage.removeContent(); } else if (maxMessageSize == 0 || contentLength < this.sizeCounter) { byte[] message_body = new byte[contentLength]; int nread = 0; while (nread < contentLength) { // Start my starvation timer. // This ensures that the other end // writes at least some data in // or we will close the pipe from // him. This prevents DOS attack // that takes up all our connections. this.rawInputStream.startTimer(); try { int readlength = inputStream.read(message_body, nread, contentLength - nread); if (readlength > 0) { nread += readlength; } else { break; } } catch (IOException ex) { ex.printStackTrace(); break; } finally { // Stop my starvation timer. this.rawInputStream.stopTimer(); } } sipMessage.setMessageContent(message_body); } // Content length too large - process the message and // return error from there. if (sipMessageListener != null) { try { sipMessageListener.processMessage(sipMessage); } catch (Exception ex) { // fatal error in processing - close the // connection. break; } } } } finally { try { inputStream.close(); } catch (IOException e) { InternalErrorHandler.handleException(e); } } }