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 */ 26 package gov.nist.javax.sip.parser; 27 28 import gov.nist.core.Token; 29 import gov.nist.javax.sip.header.*; 30 import 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 */ 42 public 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