Index: pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c
===================================================================
--- pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c	(revision 1388)
+++ pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c	(revision 1389)
@@ -96,4 +96,6 @@
 #endif
 pj_status_t app_destroy(void);
+
+extern pj_bool_t pjsip_use_compact_form;
 
 /*****************************************************************************
@@ -2885,4 +2887,6 @@
     pj_status_t status;
 
+    //pjsip_use_compact_form = PJ_TRUE;
+
     /* Create pjsua */
     status = pjsua_create();
Index: pjproject/trunk/pjsip/include/pjsip/print_util.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/print_util.h	(revision 1388)
+++ pjproject/trunk/pjsip/include/pjsip/print_util.h	(revision 1389)
@@ -102,5 +102,12 @@
 typedef int   (*pjsip_hdr_print_fptr)(void *hdr, char *buf, pj_size_t len);
 
-extern const pj_str_t pjsip_hdr_names[];
+typedef struct pjsip_hdr_name_info_t
+{
+    char	*name;
+    unsigned	 name_len;
+    char	*sname;
+} pjsip_hdr_name_info_t;
+
+extern const pjsip_hdr_name_info_t pjsip_hdr_names[];
 
 PJ_INLINE(void) init_hdr(void *hptr, pjsip_hdr_e htype, void *vptr)
@@ -108,5 +115,12 @@
     pjsip_hdr *hdr = (pjsip_hdr*) hptr;
     hdr->type = htype;
-    hdr->name = hdr->sname = pjsip_hdr_names[htype];
+    hdr->name.ptr = pjsip_hdr_names[htype].name;
+    hdr->name.slen = pjsip_hdr_names[htype].name_len;
+    if (pjsip_hdr_names[htype].sname) {
+	hdr->sname.ptr = pjsip_hdr_names[htype].sname;
+	hdr->sname.slen = 1;
+    } else {
+	hdr->sname = hdr->name;
+    }
     hdr->vptr = (pjsip_hdr_vptr*) vptr;
     pj_list_init(hdr);
Index: pjproject/trunk/pjsip/include/pjsip/sip_config.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_config.h	(revision 1388)
+++ pjproject/trunk/pjsip/include/pjsip/sip_config.h	(revision 1389)
@@ -130,4 +130,33 @@
 
 /**
+ * Encode SIP headers in their short forms to reduce size. By default,
+ * SIP headers in outgoing messages will be encoded in their full names. 
+ * If this option is enabled, then SIP headers for outgoing messages
+ * will be encoded in their short forms, to reduce message size. 
+ * Note that this does not affect the ability of PJSIP to parse incoming
+ * SIP messages, as the parser always supports parsing both the long
+ * and short version of the headers.
+ *
+ * Note that there is also an undocumented variable defined in sip_msg.c
+ * to control whether compact form should be used for encoding SIP
+ * headers. The default value of this variable is PJSIP_ENCODE_SHORT_HNAME.
+ * To change PJSIP behavior during run-time, application can use the 
+ * following construct:
+ *
+ \verbatim
+   extern pj_bool_t pjsip_use_compact_form;
+ 
+   // enable compact form
+   pjsip_use_compact_form = PJ_TRUE;
+ \endverbatim
+ *
+ * Default is 0 (no)
+ */
+#ifndef PJSIP_ENCODE_SHORT_HNAME
+#   define PJSIP_ENCODE_SHORT_HNAME	0
+#endif
+
+
+/**
  * Allow SIP modules removal or insertions during operation?
  * If yes, then locking will be employed when endpoint need to
Index: pjproject/trunk/pjsip/src/pjsip/sip_msg.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_msg.c	(revision 1388)
+++ pjproject/trunk/pjsip/src/pjsip/sip_msg.c	(revision 1389)
@@ -43,53 +43,55 @@
 };
 
-const pj_str_t pjsip_hdr_names[] = 
-{
-    { "Accept",		     6 },   // PJSIP_H_ACCEPT,
-    { "Accept-Encoding",    15 },   // PJSIP_H_ACCEPT_ENCODING,
-    { "Accept-Language",    15 },   // PJSIP_H_ACCEPT_LANGUAGE,
-    { "Alert-Info",	    10 },   // PJSIP_H_ALERT_INFO,
-    { "Allow",		     5 },   // PJSIP_H_ALLOW,
-    { "Authentication-Info",19 },   // PJSIP_H_AUTHENTICATION_INFO,
-    { "Authorization",	    13 },   // PJSIP_H_AUTHORIZATION,
-    { "Call-ID",	     7 },   // PJSIP_H_CALL_ID,
-    { "Call-Info",	     9 },   // PJSIP_H_CALL_INFO,
-    { "Contact",	     7 },   // PJSIP_H_CONTACT,
-    { "Content-Disposition",19 },   // PJSIP_H_CONTENT_DISPOSITION,
-    { "Content-Encoding",   16 },   // PJSIP_H_CONTENT_ENCODING,
-    { "Content-Language",   16 },   // PJSIP_H_CONTENT_LANGUAGE,
-    { "Content-Length",	    14 },   // PJSIP_H_CONTENT_LENGTH,
-    { "Content-Type",	    12 },   // PJSIP_H_CONTENT_TYPE,
-    { "CSeq",		     4 },   // PJSIP_H_CSEQ,
-    { "Date",		     4 },   // PJSIP_H_DATE,
-    { "Error-Info",	    10 },   // PJSIP_H_ERROR_INFO,
-    { "Expires",	     7 },   // PJSIP_H_EXPIRES,
-    { "From",		     4 },   // PJSIP_H_FROM,
-    { "In-Reply-To",	    11 },   // PJSIP_H_IN_REPLY_TO,
-    { "Max-Forwards",	    12 },   // PJSIP_H_MAX_FORWARDS,
-    { "MIME-Version",	    12 },   // PJSIP_H_MIME_VERSION,
-    { "Min-Expires",	    11 },   // PJSIP_H_MIN_EXPIRES,
-    { "Organization",	    12 },   // PJSIP_H_ORGANIZATION,
-    { "Priority",	     8 },   // PJSIP_H_PRIORITY,
-    { "Proxy-Authenticate", 18 },   // PJSIP_H_PROXY_AUTHENTICATE,
-    { "Proxy-Authorization",19 },   // PJSIP_H_PROXY_AUTHORIZATION,
-    { "Proxy-Require",	    13 },   // PJSIP_H_PROXY_REQUIRE,
-    { "Record-Route",	    12 },   // PJSIP_H_RECORD_ROUTE,
-    { "Reply-To",	     8 },   // PJSIP_H_REPLY_TO,
-    { "Require",	     7 },   // PJSIP_H_REQUIRE,
-    { "Retry-After",	    11 },   // PJSIP_H_RETRY_AFTER,
-    { "Route",		     5 },   // PJSIP_H_ROUTE,
-    { "Server",		     6 },   // PJSIP_H_SERVER,
-    { "Subject",	     7 },   // PJSIP_H_SUBJECT,
-    { "Supported",	     9 },   // PJSIP_H_SUPPORTED,
-    { "Timestamp",	     9 },   // PJSIP_H_TIMESTAMP,
-    { "To",		     2 },   // PJSIP_H_TO,
-    { "Unsupported",	    11 },   // PJSIP_H_UNSUPPORTED,
-    { "User-Agent",	    10 },   // PJSIP_H_USER_AGENT,
-    { "Via",		     3 },   // PJSIP_H_VIA,
-    { "Warning",	     7 },   // PJSIP_H_WARNING,
-    { "WWW-Authenticate",   16 },   // PJSIP_H_WWW_AUTHENTICATE,
-
-    { "_Unknown-Header",    15 },   // PJSIP_H_OTHER,
+const pjsip_hdr_name_info_t pjsip_hdr_names[] = 
+{
+    { "Accept",		    6,  NULL },   // PJSIP_H_ACCEPT,
+    { "Accept-Encoding",    15, NULL },   // PJSIP_H_ACCEPT_ENCODING,
+    { "Accept-Language",    15, NULL },   // PJSIP_H_ACCEPT_LANGUAGE,
+    { "Alert-Info",	    10, NULL },   // PJSIP_H_ALERT_INFO,
+    { "Allow",		    5,  NULL },   // PJSIP_H_ALLOW,
+    { "Authentication-Info",19, NULL },   // PJSIP_H_AUTHENTICATION_INFO,
+    { "Authorization",	    13, NULL },   // PJSIP_H_AUTHORIZATION,
+    { "Call-ID",	    7,  "i" },    // PJSIP_H_CALL_ID,
+    { "Call-Info",	    9,  NULL },   // PJSIP_H_CALL_INFO,
+    { "Contact",	    7,  "m" },    // PJSIP_H_CONTACT,
+    { "Content-Disposition",19, NULL },   // PJSIP_H_CONTENT_DISPOSITION,
+    { "Content-Encoding",   16, "e" },    // PJSIP_H_CONTENT_ENCODING,
+    { "Content-Language",   16, NULL },   // PJSIP_H_CONTENT_LANGUAGE,
+    { "Content-Length",	    14, "l" },    // PJSIP_H_CONTENT_LENGTH,
+    { "Content-Type",	    12, "c" },    // PJSIP_H_CONTENT_TYPE,
+    { "CSeq",		     4, NULL },   // PJSIP_H_CSEQ,
+    { "Date",		     4, NULL },   // PJSIP_H_DATE,
+    { "Error-Info",	    10, NULL },   // PJSIP_H_ERROR_INFO,
+    { "Expires",	     7, NULL },   // PJSIP_H_EXPIRES,
+    { "From",		     4, "f" },    // PJSIP_H_FROM,
+    { "In-Reply-To",	    11, NULL },   // PJSIP_H_IN_REPLY_TO,
+    { "Max-Forwards",	    12, NULL },   // PJSIP_H_MAX_FORWARDS,
+    { "MIME-Version",	    12, NULL },   // PJSIP_H_MIME_VERSION,
+    { "Min-Expires",	    11, NULL },   // PJSIP_H_MIN_EXPIRES,
+    { "Organization",	    12, NULL },   // PJSIP_H_ORGANIZATION,
+    { "Priority",	     8, NULL },   // PJSIP_H_PRIORITY,
+    { "Proxy-Authenticate", 18, NULL },   // PJSIP_H_PROXY_AUTHENTICATE,
+    { "Proxy-Authorization",19, NULL },   // PJSIP_H_PROXY_AUTHORIZATION,
+    { "Proxy-Require",	    13, NULL },   // PJSIP_H_PROXY_REQUIRE,
+    { "Record-Route",	    12, NULL },   // PJSIP_H_RECORD_ROUTE,
+    { "Reply-To",	     8, NULL },   // PJSIP_H_REPLY_TO,
+    { "Require",	     7, NULL },   // PJSIP_H_REQUIRE,
+    { "Retry-After",	    11, NULL },   // PJSIP_H_RETRY_AFTER,
+    { "Route",		     5, NULL },   // PJSIP_H_ROUTE,
+    { "Server",		     6, NULL },   // PJSIP_H_SERVER,
+    { "Subject",	     7, "s" },    // PJSIP_H_SUBJECT,
+    { "Supported",	     9, "k" },    // PJSIP_H_SUPPORTED,
+    { "Timestamp",	     9, NULL },   // PJSIP_H_TIMESTAMP,
+    { "To",		     2, "t" },    // PJSIP_H_TO,
+    { "Unsupported",	    11, NULL },   // PJSIP_H_UNSUPPORTED,
+    { "User-Agent",	    10, NULL },   // PJSIP_H_USER_AGENT,
+    { "Via",		     3, "v" },    // PJSIP_H_VIA,
+    { "Warning",	     7, NULL },   // PJSIP_H_WARNING,
+    { "WWW-Authenticate",   16, NULL },   // PJSIP_H_WWW_AUTHENTICATE,
+
+    { "_Unknown-Header",    15, NULL },   // PJSIP_H_OTHER,
 };
+
+pj_bool_t pjsip_use_compact_form = PJSIP_ENCODE_SHORT_HNAME;
 
 static pj_str_t status_phrase[710];
@@ -306,11 +308,6 @@
     }
     for (; hdr!=end; hdr = hdr->next) {
-	if (hdr->type < PJSIP_H_OTHER) {
-	    if (pj_stricmp(&pjsip_hdr_names[hdr->type], name) == 0)
-		return (void*)hdr;
-	} else {
-	    if (pj_stricmp(&hdr->name, name) == 0)
-		return (void*)hdr;
-	}
+	if (pj_stricmp(&hdr->name, name) == 0)
+	    return (void*)hdr;
     }
     return NULL;
@@ -334,4 +331,9 @@
     pjsip_hdr *hdr;
     pj_str_t clen_hdr =  { "Content-Length: ", 16};
+
+    if (pjsip_use_compact_form) {
+	clen_hdr.ptr = "l: ";
+	clen_hdr.slen = 3;
+    }
 
     /* Get a wild guess on how many bytes are typically needed.
@@ -410,4 +412,9 @@
 	    pj_str_t ctype_hdr = { "Content-Type: ", 14};
 	    const pjsip_media_type *media = &msg->body->content_type;
+
+	    if (pjsip_use_compact_form) {
+		ctype_hdr.ptr = "c: ";
+		ctype_hdr.slen = 3;
+	    }
 
 	    /* Add Content-Type header. */
@@ -597,10 +604,11 @@
 {
     char *p = buf;
+    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;
     
-    if ((pj_ssize_t)size < hdr->name.slen + hdr->hvalue.slen + 5)
+    if ((pj_ssize_t)size < hname->slen + hdr->hvalue.slen + 5)
 	return -1;
 
-    pj_memcpy(p, hdr->name.ptr, hdr->name.slen);
-    p += hdr->name.slen;
+    pj_memcpy(p, hname->ptr, hname->slen);
+    p += hname->slen;
     *p++ = ':';
     *p++ = ' ';
@@ -620,5 +628,5 @@
 
     hdr->type = rhs->type;
-    hdr->sname = hdr->name;
+    pj_strdup(pool, &hdr->sname, &rhs->sname);
     return hdr;
 }
@@ -679,10 +687,11 @@
 {
     char *p = buf;
-
-    if ((pj_ssize_t)size < hdr->name.slen + 15)
+    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;
+
+    if ((pj_ssize_t)size < hname->slen + 15)
 	return -1;
 
-    pj_memcpy(p, hdr->name.ptr, hdr->name.slen);
-    p += hdr->name.slen;
+    pj_memcpy(p, hname->ptr, hname->slen);
+    p += hname->slen;
     *p++ = ':';
     *p++ = ' ';
@@ -754,6 +763,7 @@
 {
     char *p = buf, *endbuf = buf+size;
-
-    copy_advance(p, hdr->name);
+    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;
+
+    copy_advance(p, (*hname));
     *p++ = ':';
     *p++ = ' ';
@@ -902,10 +912,11 @@
     char *p = buf;
     int len;
-
-    if ((pj_ssize_t)size < hdr->name.slen + 14)
+    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;
+
+    if ((pj_ssize_t)size < hname->slen + 14)
 	return -1;
 
-    pj_memcpy(p, hdr->name.ptr, hdr->name.slen);
-    p += hdr->name.slen;
+    pj_memcpy(p, hname->ptr, hname->slen);
+    p += hname->slen;
     *p++ = ':';
     *p++ = ' ';
@@ -966,4 +977,5 @@
     char *p = buf;
     int len;
+    /* CSeq doesn't have compact form */
 
     if ((pj_ssize_t)size < hdr->name.slen + hdr->method.name.slen + 15)
@@ -1043,10 +1055,12 @@
 				    pj_size_t size)
 {
+    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;
+
     if (hdr->star) {
 	char *p = buf;
-	if ((pj_ssize_t)size < hdr->name.slen + 6)
+	if ((pj_ssize_t)size < hname->slen + 6)
 	    return -1;
-	pj_memcpy(p, hdr->name.ptr, hdr->name.slen);
-	p += hdr->name.slen;
+	pj_memcpy(p, hname->ptr, hname->slen);
+	p += hname->slen;
 	*p++ = ':';
 	*p++ = ' ';
@@ -1059,5 +1073,5 @@
 	char *endbuf = buf + size;
 
-	copy_advance(buf, hdr->name);
+	copy_advance(buf, (*hname));
 	*buf++ = ':';
 	*buf++ = ' ';
@@ -1191,6 +1205,7 @@
     char *p = buf;
     int len;
-
-    if ((pj_ssize_t)size < hdr->name.slen + 
+    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;
+
+    if ((pj_ssize_t)size < hname->slen + 
 			   hdr->media.type.slen + hdr->media.subtype.slen + 
 			   hdr->media.param.slen + 8)
@@ -1199,6 +1214,6 @@
     }
 
-    pj_memcpy(p, hdr->name.ptr, hdr->name.slen);
-    p += hdr->name.slen;
+    pj_memcpy(p, hname->ptr, hname->slen);
+    p += hname->slen;
     *p++ = ':';
     *p++ = ' ';
@@ -1308,5 +1323,8 @@
 {
     hdr->type = PJSIP_H_FROM;
-    hdr->name = hdr->sname = pjsip_hdr_names[PJSIP_H_FROM];
+    hdr->name.ptr = pjsip_hdr_names[PJSIP_H_FROM].name;
+    hdr->name.slen = pjsip_hdr_names[PJSIP_H_FROM].name_len;
+    hdr->sname.ptr = pjsip_hdr_names[PJSIP_H_FROM].sname;
+    hdr->sname.slen = 1;
     return hdr;
 }
@@ -1315,5 +1333,8 @@
 {
     hdr->type = PJSIP_H_TO;
-    hdr->name = hdr->sname = pjsip_hdr_names[PJSIP_H_TO];
+    hdr->name.ptr = pjsip_hdr_names[PJSIP_H_TO].name;
+    hdr->name.slen = pjsip_hdr_names[PJSIP_H_TO].name_len;
+    hdr->sname.ptr = pjsip_hdr_names[PJSIP_H_TO].sname;
+    hdr->sname.slen = 1;
     return hdr;
 }
@@ -1325,6 +1346,7 @@
     char *startbuf = buf;
     char *endbuf = buf + size;
-
-    copy_advance(buf, hdr->name);
+    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;
+
+    copy_advance(buf, (*hname));
     *buf++ = ':';
     *buf++ = ' ';
@@ -1482,5 +1504,7 @@
 {
     hdr->type = PJSIP_H_RECORD_ROUTE;
-    hdr->name = hdr->sname = pjsip_hdr_names[PJSIP_H_RECORD_ROUTE];
+    hdr->name.ptr = pjsip_hdr_names[PJSIP_H_RECORD_ROUTE].name;
+    hdr->name.slen = pjsip_hdr_names[PJSIP_H_RECORD_ROUTE].name_len;
+    hdr->sname = hdr->name;
     return hdr;
 }
@@ -1489,5 +1513,7 @@
 {
     hdr->type = PJSIP_H_ROUTE;
-    hdr->name = hdr->sname = pjsip_hdr_names[PJSIP_H_ROUTE];
+    hdr->name.ptr = pjsip_hdr_names[PJSIP_H_ROUTE].name;
+    hdr->name.slen = pjsip_hdr_names[PJSIP_H_ROUTE].name_len;
+    hdr->sname = hdr->name;
     return hdr;
 }
@@ -1499,4 +1525,5 @@
     char *startbuf = buf;
     char *endbuf = buf + size;
+    /* Route and Record-Route don't compact forms */
 
     copy_advance(buf, hdr->name);
@@ -1677,6 +1704,7 @@
     char *endbuf = buf + size;
     pj_str_t sip_ver = { "SIP/2.0/", 8 };
-
-    if ((pj_ssize_t)size < hdr->name.slen + sip_ver.slen + 
+    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;
+
+    if ((pj_ssize_t)size < hname->slen + sip_ver.slen + 
 			   hdr->transport.slen + hdr->sent_by.host.slen + 12)
     {
@@ -1685,5 +1713,5 @@
 
     /* pjsip_hdr_names */
-    copy_advance(buf, hdr->name);
+    copy_advance(buf, (*hname));
     *buf++ = ':';
     *buf++ = ' ';
