1/* 2* Conditions Of Use 3* 4* This software was developed by employees of the National Institute of 5* Standards and Technology (NIST), an agency of the Federal Government. 6* Pursuant to title 15 Untied States Code Section 105, works of NIST 7* employees are not subject to copyright protection in the United States 8* and are considered to be in the public domain. As a result, a formal 9* license is not needed to use the software. 10* 11* This software is provided by NIST as a service and is expressly 12* provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED 13* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF 14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 15* AND DATA ACCURACY. NIST does not warrant or make any representations 16* regarding the use of the software or the results thereof, including but 17* not limited to the correctness, accuracy, reliability or usefulness of 18* the software. 19* 20* Permission to use this software is contingent upon your acceptance 21* of the terms of this agreement 22* 23* . 24* 25*/ 26package gov.nist.javax.sip.parser; 27 28import gov.nist.core.Token; 29import gov.nist.javax.sip.header.*; 30import java.text.ParseException; 31 32/** 33 * Parser for UserAgent header. 34 * 35 * @version 1.2 $Revision: 1.15 $ $Date: 2009/07/17 18:58:07 $ 36 * 37 * @author Olivier Deruelle <br/> 38 * @author M. Ranganathan <br/> 39 * 40 * 41 */ 42public class UserAgentParser extends HeaderParser { 43 44 /** 45 * Constructor 46 * 47 * @param userAgent - 48 * UserAgent header to parse 49 */ 50 public UserAgentParser(String userAgent) { 51 super(userAgent); 52 } 53 54 /** 55 * Constructor 56 * 57 * @param lexer - 58 * the lexer to use. 59 */ 60 protected UserAgentParser(Lexer lexer) { 61 super(lexer); 62 } 63 64 /** 65 * parse the message. Note that we have losened up on the parsing quite a bit because 66 * user agents tend to be very bad about specifying the user agent according to RFC. 67 * 68 * @return SIPHeader (UserAgent object) 69 * @throws SIPParseException 70 * if the message does not respect the spec. 71 */ 72 public SIPHeader parse() throws ParseException { 73 if (debug) 74 dbg_enter("UserAgentParser.parse"); 75 UserAgent userAgent = new UserAgent(); 76 try { 77 headerName(TokenTypes.USER_AGENT); 78 if (this.lexer.lookAhead(0) == '\n') 79 throw createParseException("empty header"); 80 81 /* 82 * BNF User-Agent = "User-Agent" HCOLON server-val *(LWS server-val) 83 * server-val = product / comment product = token [SLASH 84 * product-version] product-version = token 85 */ 86 while (this.lexer.lookAhead(0) != '\n' 87 && this.lexer.lookAhead(0) != '\0') { 88 89 if (this.lexer.lookAhead(0) == '(') { 90 String comment = this.lexer.comment(); 91 userAgent.addProductToken('(' + comment + ')'); 92 } else { 93 // product = token [SLASHproduct-version] 94 // product-version = token 95 // The RFC Does NOT allow this space but we are generous in what we accept 96 97 this.getLexer().SPorHT(); 98 99 100 String product = this.lexer.byteStringNoSlash(); 101 if ( product == null ) throw createParseException("Expected product string"); 102 103 StringBuffer productSb = new StringBuffer(product); 104 // do we possibily have the optional product-version? 105 if (this.lexer.peekNextToken().getTokenType() == TokenTypes.SLASH) { 106 // yes 107 this.lexer.match(TokenTypes.SLASH); 108 // product-version 109 // The RFC Does NOT allow this space but we are generous in what we accept 110 this.getLexer().SPorHT(); 111 112 String productVersion = this.lexer.byteStringNoSlash(); 113 114 if ( productVersion == null ) throw createParseException("Expected product version"); 115 116 productSb.append("/"); 117 118 productSb.append(productVersion); 119 } 120 121 userAgent.addProductToken(productSb.toString()); 122 } 123 // LWS 124 this.lexer.SPorHT(); 125 } 126 } finally { 127 if (debug) 128 dbg_leave("UserAgentParser.parse"); 129 } 130 131 return userAgent; 132 } 133 134 135 public static void main(String args[]) throws ParseException { String 136 userAgent[] = { "User-Agent: Softphone/Beta1.5 \n", "User-Agent:Nist/Beta1 (beta version) \n", "User-Agent: Nist UA (beta version)\n", 137 "User-Agent: Nist1.0/Beta2 Ubi/vers.1.0 (very cool) \n" , 138 "User-Agent: SJphone/1.60.299a/L (SJ Labs)\n", 139 "User-Agent: sipXecs/3.5.11 sipXecs/sipxbridge (Linux)\n"}; 140 141 for (int i = 0; i < userAgent.length; i++ ) { UserAgentParser parser = 142 new UserAgentParser(userAgent[i]); UserAgent ua= (UserAgent) 143 parser.parse(); System.out.println("encoded = " + ua.encode()); } 144 } 145 146} 147