12264Sjacobs /* 22264Sjacobs * "$Id: http.h 148 2006-04-25 16:54:17Z njacobs $" 32264Sjacobs * 42264Sjacobs * Hyper-Text Transport Protocol definitions for the Common UNIX Printing 52264Sjacobs * System (CUPS). 62264Sjacobs * 72264Sjacobs * Copyright 1997-2005 by Easy Software Products, all rights reserved. 82264Sjacobs * 92264Sjacobs * These coded instructions, statements, and computer programs are the 102264Sjacobs * property of Easy Software Products and are protected by Federal 112264Sjacobs * copyright law. Distribution and use rights are outlined in the file 122264Sjacobs * "LICENSE.txt" which should have been included with this file. If this 132264Sjacobs * file is missing or damaged please contact Easy Software Products 142264Sjacobs * at: 152264Sjacobs * 162264Sjacobs * Attn: CUPS Licensing Information 172264Sjacobs * Easy Software Products 182264Sjacobs * 44141 Airport View Drive, Suite 204 192264Sjacobs * Hollywood, Maryland 20636 USA 202264Sjacobs * 212264Sjacobs * Voice: (301) 373-9600 222264Sjacobs * EMail: cups-info@cups.org 232264Sjacobs * WWW: http://www.cups.org 242264Sjacobs * 252264Sjacobs * This file is subject to the Apple OS-Developed Software exception. 262264Sjacobs */ 272264Sjacobs 282264Sjacobs #ifndef _CUPS_HTTP_H_ 292264Sjacobs #define _CUPS_HTTP_H_ 302264Sjacobs 312264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 322264Sjacobs 332264Sjacobs /* 342264Sjacobs * Include necessary headers... 352264Sjacobs */ 362264Sjacobs 372264Sjacobs # include <string.h> 382264Sjacobs # include <time.h> 392264Sjacobs # ifdef WIN32 402264Sjacobs # include <winsock.h> 412264Sjacobs # else 422264Sjacobs # include <unistd.h> 432264Sjacobs # include <sys/time.h> 442264Sjacobs # include <sys/types.h> 452264Sjacobs # include <sys/socket.h> 462264Sjacobs # include <netdb.h> 472264Sjacobs # include <netinet/in.h> 482264Sjacobs # include <arpa/inet.h> 492264Sjacobs # include <netinet/in_systm.h> 502264Sjacobs # include <netinet/ip.h> 512264Sjacobs # if !defined(__APPLE__) || !defined(TCP_NODELAY) 522264Sjacobs # include <netinet/tcp.h> 532264Sjacobs # endif /* !__APPLE__ || !TCP_NODELAY */ 542264Sjacobs # ifdef AF_LOCAL 552264Sjacobs # include <sys/un.h> 562264Sjacobs # endif /* AF_LOCAL */ 572264Sjacobs # endif /* WIN32 */ 582264Sjacobs 592264Sjacobs 602264Sjacobs /* 612264Sjacobs * C++ magic... 622264Sjacobs */ 632264Sjacobs 642264Sjacobs #ifdef __cplusplus 652264Sjacobs extern "C" { 662264Sjacobs #endif 672264Sjacobs 682264Sjacobs 692264Sjacobs /* 702264Sjacobs * Oh, the wonderful world of IPv6 compatibility. Apparently some 712264Sjacobs * implementations expose the (more logical) 32-bit address parts 722264Sjacobs * to everyone, while others only expose it to kernel code... To 732264Sjacobs * make supporting IPv6 even easier, each vendor chose different 742264Sjacobs * core structure and union names, so the same defines or code 752264Sjacobs * can't be used on all platforms. 762264Sjacobs * 772264Sjacobs * The following will likely need tweeking on new platforms that 782264Sjacobs * support IPv6 - the "s6_addr32" define maps to the 32-bit integer 792264Sjacobs * array in the in6_addr union, which is named differently on various 802264Sjacobs * platforms. 812264Sjacobs */ 822264Sjacobs 832264Sjacobs #if defined(AF_INET6) && !defined(s6_addr32) 842264Sjacobs # if defined(__sun) 852264Sjacobs # define s6_addr32 _S6_un._S6_u32 862264Sjacobs # elif defined(__FreeBSD__) || defined(__APPLE__) 872264Sjacobs # define s6_addr32 __u6_addr.__u6_addr32 882264Sjacobs # endif /* __sun */ 892264Sjacobs #endif /* AF_INET6 && !s6_addr32 */ 902264Sjacobs 912264Sjacobs 922264Sjacobs /* 932264Sjacobs * Limits... 942264Sjacobs */ 952264Sjacobs 962264Sjacobs # define HTTP_MAX_URI 1024 /* Max length of URI string */ 972264Sjacobs # define HTTP_MAX_HOST 256 /* Max length of hostname string */ 982264Sjacobs # define HTTP_MAX_BUFFER 2048 /* Max length of data buffer */ 992264Sjacobs # define HTTP_MAX_VALUE 256 /* Max header field value length */ 1002264Sjacobs 1012264Sjacobs 1022264Sjacobs /* 1032264Sjacobs * HTTP state values... 1042264Sjacobs */ 1052264Sjacobs 1062264Sjacobs typedef enum /* States are server-oriented */ 1072264Sjacobs { 1082264Sjacobs HTTP_WAITING, /* Waiting for command */ 1092264Sjacobs HTTP_OPTIONS, /* OPTIONS command, waiting for blank line */ 1102264Sjacobs HTTP_GET, /* GET command, waiting for blank line */ 1112264Sjacobs HTTP_GET_SEND, /* GET command, sending data */ 1122264Sjacobs HTTP_HEAD, /* HEAD command, waiting for blank line */ 1132264Sjacobs HTTP_POST, /* POST command, waiting for blank line */ 1142264Sjacobs HTTP_POST_RECV, /* POST command, receiving data */ 1152264Sjacobs HTTP_POST_SEND, /* POST command, sending data */ 1162264Sjacobs HTTP_PUT, /* PUT command, waiting for blank line */ 1172264Sjacobs HTTP_PUT_RECV, /* PUT command, receiving data */ 1182264Sjacobs HTTP_DELETE, /* DELETE command, waiting for blank line */ 1192264Sjacobs HTTP_TRACE, /* TRACE command, waiting for blank line */ 1202264Sjacobs HTTP_CLOSE, /* CLOSE command, waiting for blank line */ 1212264Sjacobs HTTP_STATUS /* Command complete, sending status */ 1222264Sjacobs } http_state_t; 1232264Sjacobs 1242264Sjacobs 1252264Sjacobs /* 1262264Sjacobs * HTTP version numbers... 1272264Sjacobs */ 1282264Sjacobs 1292264Sjacobs typedef enum 1302264Sjacobs { 1312264Sjacobs HTTP_0_9 = 9, /* HTTP/0.9 */ 1322264Sjacobs HTTP_1_0 = 100, /* HTTP/1.0 */ 1332264Sjacobs HTTP_1_1 = 101 /* HTTP/1.1 */ 1342264Sjacobs } http_version_t; 1352264Sjacobs 1362264Sjacobs 1372264Sjacobs /* 1382264Sjacobs * HTTP keep-alive values... 1392264Sjacobs */ 1402264Sjacobs 1412264Sjacobs typedef enum 1422264Sjacobs { 1432264Sjacobs HTTP_KEEPALIVE_OFF = 0, 1442264Sjacobs HTTP_KEEPALIVE_ON 1452264Sjacobs } http_keepalive_t; 1462264Sjacobs 1472264Sjacobs 1482264Sjacobs /* 1492264Sjacobs * HTTP transfer encoding values... 1502264Sjacobs */ 1512264Sjacobs 1522264Sjacobs typedef enum 1532264Sjacobs { 1542264Sjacobs HTTP_ENCODE_LENGTH, /* Data is sent with Content-Length */ 1552264Sjacobs HTTP_ENCODE_CHUNKED /* Data is chunked */ 1562264Sjacobs } http_encoding_t; 1572264Sjacobs 1582264Sjacobs 1592264Sjacobs /* 1602264Sjacobs * HTTP encryption values... 1612264Sjacobs */ 1622264Sjacobs 1632264Sjacobs typedef enum 1642264Sjacobs { 1652264Sjacobs HTTP_ENCRYPT_IF_REQUESTED, /* Encrypt if requested (TLS upgrade) */ 1662264Sjacobs HTTP_ENCRYPT_NEVER, /* Never encrypt */ 1672264Sjacobs HTTP_ENCRYPT_REQUIRED, /* Encryption is required (TLS upgrade) */ 1682264Sjacobs HTTP_ENCRYPT_ALWAYS /* Always encrypt (SSL) */ 1692264Sjacobs } http_encryption_t; 1702264Sjacobs 1712264Sjacobs 1722264Sjacobs /* 1732264Sjacobs * HTTP authentication types... 1742264Sjacobs */ 1752264Sjacobs 1762264Sjacobs typedef enum 1772264Sjacobs { 1782264Sjacobs HTTP_AUTH_NONE, /* No authentication in use */ 1792264Sjacobs HTTP_AUTH_BASIC, /* Basic authentication in use */ 1802264Sjacobs HTTP_AUTH_MD5, /* Digest authentication in use */ 1812264Sjacobs HTTP_AUTH_MD5_SESS, /* MD5-session authentication in use */ 1822264Sjacobs HTTP_AUTH_MD5_INT, /* Digest authentication in use for body */ 1832264Sjacobs HTTP_AUTH_MD5_SESS_INT /* MD5-session authentication in use for body */ 1842264Sjacobs } http_auth_t; 1852264Sjacobs 1862264Sjacobs 1872264Sjacobs /* 1882264Sjacobs * HTTP status codes... 1892264Sjacobs */ 1902264Sjacobs 1912264Sjacobs typedef enum 1922264Sjacobs { 1932264Sjacobs HTTP_ERROR = -1, /* An error response from httpXxxx() */ 1942264Sjacobs 1952264Sjacobs HTTP_CONTINUE = 100, /* Everything OK, keep going... */ 1962264Sjacobs HTTP_SWITCHING_PROTOCOLS, /* HTTP upgrade to TLS/SSL */ 1972264Sjacobs 1982264Sjacobs HTTP_OK = 200, /* OPTIONS/GET/HEAD/POST/TRACE command was successful */ 1992264Sjacobs HTTP_CREATED, /* PUT command was successful */ 2002264Sjacobs HTTP_ACCEPTED, /* DELETE command was successful */ 2012264Sjacobs HTTP_NOT_AUTHORITATIVE, /* Information isn't authoritative */ 2022264Sjacobs HTTP_NO_CONTENT, /* Successful command, no new data */ 2032264Sjacobs HTTP_RESET_CONTENT, /* Content was reset/recreated */ 2042264Sjacobs HTTP_PARTIAL_CONTENT, /* Only a partial file was recieved/sent */ 2052264Sjacobs 2062264Sjacobs HTTP_MULTIPLE_CHOICES = 300, /* Multiple files match request */ 2072264Sjacobs HTTP_MOVED_PERMANENTLY, /* Document has moved permanently */ 2082264Sjacobs HTTP_MOVED_TEMPORARILY, /* Document has moved temporarily */ 2092264Sjacobs HTTP_SEE_OTHER, /* See this other link... */ 2102264Sjacobs HTTP_NOT_MODIFIED, /* File not modified */ 2112264Sjacobs HTTP_USE_PROXY, /* Must use a proxy to access this URI */ 2122264Sjacobs 2132264Sjacobs HTTP_BAD_REQUEST = 400, /* Bad request */ 2142264Sjacobs HTTP_UNAUTHORIZED, /* Unauthorized to access host */ 2152264Sjacobs HTTP_PAYMENT_REQUIRED, /* Payment required */ 2162264Sjacobs HTTP_FORBIDDEN, /* Forbidden to access this URI */ 2172264Sjacobs HTTP_NOT_FOUND, /* URI was not found */ 2182264Sjacobs HTTP_METHOD_NOT_ALLOWED, /* Method is not allowed */ 2192264Sjacobs HTTP_NOT_ACCEPTABLE, /* Not Acceptable */ 2202264Sjacobs HTTP_PROXY_AUTHENTICATION, /* Proxy Authentication is Required */ 2212264Sjacobs HTTP_REQUEST_TIMEOUT, /* Request timed out */ 2222264Sjacobs HTTP_CONFLICT, /* Request is self-conflicting */ 2232264Sjacobs HTTP_GONE, /* Server has gone away */ 2242264Sjacobs HTTP_LENGTH_REQUIRED, /* A content length or encoding is required */ 2252264Sjacobs HTTP_PRECONDITION, /* Precondition failed */ 2262264Sjacobs HTTP_REQUEST_TOO_LARGE, /* Request entity too large */ 2272264Sjacobs HTTP_URI_TOO_LONG, /* URI too long */ 2282264Sjacobs HTTP_UNSUPPORTED_MEDIATYPE, /* The requested media type is unsupported */ 2292264Sjacobs HTTP_UPGRADE_REQUIRED = 426, /* Upgrade to SSL/TLS required */ 2302264Sjacobs 2312264Sjacobs HTTP_SERVER_ERROR = 500, /* Internal server error */ 2322264Sjacobs HTTP_NOT_IMPLEMENTED, /* Feature not implemented */ 2332264Sjacobs HTTP_BAD_GATEWAY, /* Bad gateway */ 2342264Sjacobs HTTP_SERVICE_UNAVAILABLE, /* Service is unavailable */ 2352264Sjacobs HTTP_GATEWAY_TIMEOUT, /* Gateway connection timed out */ 2362264Sjacobs HTTP_NOT_SUPPORTED /* HTTP version not supported */ 2372264Sjacobs } http_status_t; 2382264Sjacobs 2392264Sjacobs 2402264Sjacobs /* 2412264Sjacobs * HTTP field names... 2422264Sjacobs */ 2432264Sjacobs 2442264Sjacobs typedef enum 2452264Sjacobs { 2462264Sjacobs HTTP_FIELD_UNKNOWN = -1, 2472264Sjacobs HTTP_FIELD_ACCEPT_LANGUAGE, 2482264Sjacobs HTTP_FIELD_ACCEPT_RANGES, 2492264Sjacobs HTTP_FIELD_AUTHORIZATION, 2502264Sjacobs HTTP_FIELD_CONNECTION, 2512264Sjacobs HTTP_FIELD_CONTENT_ENCODING, 2522264Sjacobs HTTP_FIELD_CONTENT_LANGUAGE, 2532264Sjacobs HTTP_FIELD_CONTENT_LENGTH, 2542264Sjacobs HTTP_FIELD_CONTENT_LOCATION, 2552264Sjacobs HTTP_FIELD_CONTENT_MD5, 2562264Sjacobs HTTP_FIELD_CONTENT_RANGE, 2572264Sjacobs HTTP_FIELD_CONTENT_TYPE, 2582264Sjacobs HTTP_FIELD_CONTENT_VERSION, 2592264Sjacobs HTTP_FIELD_DATE, 2602264Sjacobs HTTP_FIELD_HOST, 2612264Sjacobs HTTP_FIELD_IF_MODIFIED_SINCE, 2622264Sjacobs HTTP_FIELD_IF_UNMODIFIED_SINCE, 2632264Sjacobs HTTP_FIELD_KEEP_ALIVE, 2642264Sjacobs HTTP_FIELD_LAST_MODIFIED, 2652264Sjacobs HTTP_FIELD_LINK, 2662264Sjacobs HTTP_FIELD_LOCATION, 2672264Sjacobs HTTP_FIELD_RANGE, 2682264Sjacobs HTTP_FIELD_REFERER, 2692264Sjacobs HTTP_FIELD_RETRY_AFTER, 2702264Sjacobs HTTP_FIELD_TRANSFER_ENCODING, 2712264Sjacobs HTTP_FIELD_UPGRADE, 2722264Sjacobs HTTP_FIELD_USER_AGENT, 2732264Sjacobs HTTP_FIELD_WWW_AUTHENTICATE, 2742264Sjacobs HTTP_FIELD_MAX 2752264Sjacobs } http_field_t; 2762264Sjacobs 2772264Sjacobs 2782264Sjacobs /* 2792264Sjacobs * HTTP address structure (makes using IPv6 a little easier and more portable.) 2802264Sjacobs */ 2812264Sjacobs 2822264Sjacobs typedef union 2832264Sjacobs { 2842264Sjacobs struct sockaddr addr; /* Base structure for family value */ 2852264Sjacobs struct sockaddr_in ipv4; /* IPv4 address */ 2862264Sjacobs #ifdef AF_INET6 2872264Sjacobs struct sockaddr_in6 ipv6; /* IPv6 address */ 2882264Sjacobs #endif /* AF_INET6 */ 2892264Sjacobs #ifdef AF_LOCAL 2902264Sjacobs struct sockaddr_un un; /* Domain socket file */ 2912264Sjacobs #endif /* AF_LOCAL */ 2922264Sjacobs char pad[128]; /* Pad to ensure binary compatibility */ 2932264Sjacobs } http_addr_t; 2942264Sjacobs 2952264Sjacobs /* 2962264Sjacobs * HTTP connection structure... 2972264Sjacobs */ 2982264Sjacobs 2992264Sjacobs typedef struct 3002264Sjacobs { 3012264Sjacobs int fd; /* File descriptor for this socket */ 3022264Sjacobs int blocking; /* To block or not to block */ 3032264Sjacobs int error; /* Last error on read */ 3042264Sjacobs time_t activity; /* Time since last read/write */ 3052264Sjacobs http_state_t state; /* State of client */ 3062264Sjacobs http_status_t status; /* Status of last request */ 3072264Sjacobs http_version_t version; /* Protocol version */ 3082264Sjacobs http_keepalive_t keep_alive; /* Keep-alive supported? */ 3092264Sjacobs struct sockaddr_in oldaddr; /* Address of connected host */ 3102264Sjacobs char hostname[HTTP_MAX_HOST], 3112264Sjacobs /* Name of connected host */ 3122264Sjacobs fields[HTTP_FIELD_MAX][HTTP_MAX_VALUE]; 3132264Sjacobs /* Field values */ 3142264Sjacobs char *data; /* Pointer to data buffer */ 3152264Sjacobs http_encoding_t data_encoding; /* Chunked or not */ 3162264Sjacobs int data_remaining; /* Number of bytes left */ 3172264Sjacobs int used; /* Number of bytes used in buffer */ 3182264Sjacobs char buffer[HTTP_MAX_BUFFER]; 3192264Sjacobs /* Buffer for messages */ 3202264Sjacobs int auth_type; /* Authentication in use */ 3212264Sjacobs char nonce[HTTP_MAX_VALUE]; 3222264Sjacobs /* Nonce value */ 3232264Sjacobs int nonce_count; /* Nonce count */ 3242264Sjacobs void *tls; /* TLS state information */ 3252264Sjacobs http_encryption_t encryption; /* Encryption requirements */ 3262264Sjacobs /**** New in CUPS 1.1.19 ****/ 3272264Sjacobs fd_set *input_set; /* select() set for httpWait() */ 3282264Sjacobs http_status_t expect; /* Expect: header */ 3292264Sjacobs char *cookie; /* Cookie value(s) */ 3302264Sjacobs /**** New in CUPS 1.1.20 ****/ 3312264Sjacobs char authstring[HTTP_MAX_VALUE], 3322264Sjacobs /* Current Authentication value */ 3332264Sjacobs userpass[HTTP_MAX_VALUE]; 3342264Sjacobs /* Username:password string */ 3352264Sjacobs int digest_tries; /* Number of tries for digest auth */ 3362264Sjacobs /**** New in CUPS 1.2 ****/ 3372264Sjacobs http_addr_t hostaddr; /* Host address and port */ 3382264Sjacobs } http_t; 3392264Sjacobs 3402264Sjacobs 3412264Sjacobs /* 3422264Sjacobs * Prototypes... 3432264Sjacobs */ 3442264Sjacobs 3452264Sjacobs # define httpBlocking(http,b) (http)->blocking = (b) 3462264Sjacobs extern int httpCheck(http_t *http); 3472264Sjacobs # define httpClearFields(http) memset((http)->fields, 0, sizeof((http)->fields)),\ 3482264Sjacobs httpSetField((http), HTTP_FIELD_HOST, (http)->hostname) 3492264Sjacobs extern void httpClose(http_t *http); 3502264Sjacobs extern http_t *httpConnect(const char *host, int port); 3512264Sjacobs extern http_t *httpConnectEncrypt(const char *host, int port, 3522264Sjacobs http_encryption_t encrypt); 3532264Sjacobs extern int httpDelete(http_t *http, const char *uri); 3542264Sjacobs extern int httpEncryption(http_t *http, http_encryption_t e); 3552264Sjacobs # define httpError(http) ((http)->error) 3562264Sjacobs extern void httpFlush(http_t *http); 3572264Sjacobs extern int httpGet(http_t *http, const char *uri); 3582264Sjacobs extern char *httpGets(char *line, int length, http_t *http); 3592264Sjacobs extern const char *httpGetDateString(time_t t); 3602264Sjacobs extern time_t httpGetDateTime(const char *s); 3612264Sjacobs # define httpGetField(http,field) (http)->fields[field] 3622264Sjacobs extern struct hostent *httpGetHostByName(const char *name); 3632264Sjacobs extern char *httpGetSubField(http_t *http, http_field_t field, 3642264Sjacobs const char *name, char *value); 3652264Sjacobs extern int httpHead(http_t *http, const char *uri); 3662264Sjacobs extern void httpInitialize(void); 3672264Sjacobs extern int httpOptions(http_t *http, const char *uri); 3682264Sjacobs extern int httpPost(http_t *http, const char *uri); 3692264Sjacobs extern int httpPrintf(http_t *http, const char *format, ...) 3702264Sjacobs # ifdef __GNUC__ 3712264Sjacobs __attribute__ ((__format__ (__printf__, 2, 3))) 3722264Sjacobs # endif /* __GNUC__ */ 3732264Sjacobs ; 3742264Sjacobs extern int httpPut(http_t *http, const char *uri); 3752264Sjacobs extern int httpRead(http_t *http, char *buffer, int length); 3762264Sjacobs extern int httpReconnect(http_t *http); 3772264Sjacobs extern void httpSeparate(const char *uri, char *method, 3782264Sjacobs char *username, char *host, int *port, 3792264Sjacobs char *resource); 3802264Sjacobs extern void httpSetField(http_t *http, http_field_t field, 3812264Sjacobs const char *value); 3822264Sjacobs extern const char *httpStatus(http_status_t status); 3832264Sjacobs extern int httpTrace(http_t *http, const char *uri); 3842264Sjacobs extern http_status_t httpUpdate(http_t *http); 3852264Sjacobs extern int httpWrite(http_t *http, const char *buffer, int length); 3862264Sjacobs extern char *httpEncode64(char *out, const char *in); 3872264Sjacobs extern char *httpDecode64(char *out, const char *in); 3882264Sjacobs extern int httpGetLength(http_t *http); 3892264Sjacobs extern char *httpMD5(const char *, const char *, const char *, 3902264Sjacobs char [33]); 3912264Sjacobs extern char *httpMD5Final(const char *, const char *, const char *, 3922264Sjacobs char [33]); 3932264Sjacobs extern char *httpMD5String(const unsigned char *, char [33]); 3942264Sjacobs 3952264Sjacobs /**** New in CUPS 1.1.19 ****/ 3962264Sjacobs extern void httpClearCookie(http_t *http); 3972264Sjacobs #define httpGetCookie(http) ((http)->cookie) 3982264Sjacobs extern void httpSetCookie(http_t *http, const char *cookie); 3992264Sjacobs extern int httpWait(http_t *http, int msec); 4002264Sjacobs 4012264Sjacobs /**** New in CUPS 1.1.21 ****/ 4022264Sjacobs extern char *httpDecode64_2(char *out, int *outlen, const char *in); 4032264Sjacobs extern char *httpEncode64_2(char *out, int outlen, const char *in, 4042264Sjacobs int inlen); 4052264Sjacobs extern void httpSeparate2(const char *uri, 4062264Sjacobs char *method, int methodlen, 4072264Sjacobs char *username, int usernamelen, 4082264Sjacobs char *host, int hostlen, int *port, 4092264Sjacobs char *resource, int resourcelen); 4102264Sjacobs 4112264Sjacobs /**** New in CUPS 1.2 ****/ 4122264Sjacobs extern int httpAddrAny(const http_addr_t *addr); 4132264Sjacobs extern int httpAddrEqual(const http_addr_t *addr1, 4142264Sjacobs const http_addr_t *addr2); 4152264Sjacobs extern void httpAddrLoad(const struct hostent *host, int port, 4162264Sjacobs int n, http_addr_t *addr); 4172264Sjacobs extern int httpAddrLocalhost(const http_addr_t *addr); 4182264Sjacobs extern char *httpAddrLookup(const http_addr_t *addr, 4192264Sjacobs char *name, int namelen); 4202264Sjacobs extern char *httpAddrString(const http_addr_t *addr, 4212264Sjacobs char *s, int slen); 4222264Sjacobs 423*3125Sjacobs #include <stdio.h> 424*3125Sjacobs extern void httpDumpData(FILE *, const char *, const char *, int); 425*3125Sjacobs 4262264Sjacobs 4272264Sjacobs /* 4282264Sjacobs * C++ magic... 4292264Sjacobs */ 4302264Sjacobs 4312264Sjacobs #ifdef __cplusplus 4322264Sjacobs } 4332264Sjacobs #endif 4342264Sjacobs 4352264Sjacobs #endif /* !_CUPS_HTTP_H_ */ 4362264Sjacobs 4372264Sjacobs /* 4382264Sjacobs * End of "$Id: http.h 148 2006-04-25 16:54:17Z njacobs $" 4392264Sjacobs */ 440