1 /***** 2 * HTTP.h : Public header file for HTTP.c, a simple HTTP/1.0 implementation. 3 * 4 * This file Version $Revision: 1.1 $ 5 * 6 * Creation date: Tue Oct 21 01:56:19 GMT+0100 1997 7 * Last modification: $Date: 1997/10/23 00:28:26 $ 8 * By: $Author: newt $ 9 * Current State: $State: Exp $ 10 * 11 * Author: Richard Offer 12 * 13 * Copyright (C) 1994-1997 by Richard Offer <offer@sgi.com> 14 * All Rights Reserved 15 * 16 * This library is free software; you can redistribute it and/or 17 * modify it under the terms of the GNU Library General Public 18 * License as published by the Free Software Foundation; either 19 * version 2 of the License, or (at your option) any later version. 20 * 21 * This library is distributed in the hope that it will be useful, 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 * Library General Public License for more details. 25 * 26 * You should have received a copy of the GNU Library General Public 27 * License along with this library; if not, write to the Free 28 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 29 * 30 *****/ 31 /***** 32 * $Source: /usr/local/rcs/Newt/XmHTML/RCS/HTTP.h,v $ 33 *****/ 34 /***** 35 * ChangeLog 36 * $Log: HTTP.h,v $ 37 * Revision 1.1 1997/10/23 00:28:26 newt 38 * Initial Revision 39 * 40 *****/ 41 42 #ifndef _HTTP_h_ 43 #define _HTTP_h_ 44 45 #define HTTPVERSION 0 46 #define HTTPREVISION 1 47 #define HTTPUPDATE_LEVEL 1 48 #define HTTPVersion \ 49 (HTTPVERSION * 1000 + HTTPREVISION * 100 + HTTPUPDATE_LEVEL) 50 51 /* used by Imake to get Shared library version numbering */ 52 #ifndef _LIBRARY 53 54 #define LIBHTTPVERSION_STRING \ 55 "Client/HTTP Version 0.1.1 (C)Richard Offer and Ripley Software Development" 56 57 /***** 58 * Feel free to re-define the following, this is passed to every web-server 59 * during all requests. 60 * If you do change this, be careful (bad editing may lead to failed requests) 61 * the format is 62 * User-Agent: <space> (manditory) 63 * <client identifier,most significant parts first> / <version number> 64 * <space> 65 * <extra fields, for development software, a point of contact is reccommended 66 * \r\n terminator 67 * 68 * wrapped in a #ifdef so an application can define it before #include'ing 69 * this file 70 *****/ 71 #ifndef USER_AGENT 72 #define USER_AGENT "User-Agent: XmHTML-HTTP/0.1.x ripley@xs4all.nl\r\n" 73 #endif /* USER_AGENT */ 74 75 typedef enum { 76 HTTPLoadToFile, 77 HTTPLoadToString 78 } HTTPLoadType; 79 80 typedef enum { 81 HTTPGET, 82 HTTPPOST, 83 HTTPHEAD 84 } HTTPLoadMethod; 85 86 /* possible HTTP return values */ 87 typedef enum { 88 /* our own error values */ 89 HTTPInvalid = 0, 90 HTTPBadProtocol = 1, 91 HTTPBadHost = 2, 92 HTTPBadURL = 3, 93 HTTPBadLoadType = 4, 94 HTTPMethodUnsupported = 5, 95 HTTPNoSocket = 6, 96 HTTPNoConnection = 7, 97 HTTPBadHttp10 = 8, 98 HTTPCannotCreateFile = 9, 99 HTTPConnectTimeout = 10, 100 HTTPTimeout = 11, 101 102 /* Now 'Real' HTTP return codes */ 103 HTTPContinue = 100, 104 HTTPSwitchProtocols = 101, 105 106 HTTPSuccess = 200, 107 HTTPCreated = 201, 108 HTTPAccepted = 202, 109 HTTPNonAuthoritativeInfo = 203, 110 HTTPNoContent = 204, 111 HTTPResetContent = 205, 112 HTTPPartialContent = 206, 113 114 HTTPMultipleChoices = 300, 115 HTTPPermMoved = 301, 116 HTTPTempMoved = 302, 117 HTTPSeeOther = 303, 118 HTTPNotModified = 304, 119 HTTPUseProxy = 305, 120 121 HTTPBadRequest = 400, 122 HTTPUnauthorised = 401, 123 HTTPPaymentReq = 402, 124 HTTPForbidden = 403, 125 HTTPNotFound = 404, 126 HTTPMethodNotAllowed = 405, 127 HTTPNotAcceptable = 406, 128 HTTPProxyAuthReq = 407, 129 HTTPRequestTimeOut = 408, 130 HTTPConflict = 409, 131 HTTPGone = 410, 132 HTTPLengthReq = 411, 133 HTTPPreCondFailed = 412, 134 HTTPReqEntityTooBig = 413, 135 HTTPURITooBig = 414, 136 HTTPUnsupportedMediaType = 415, 137 138 HTTPInternalServerError = 500, 139 HTTPNotImplemented = 501, 140 HTTPBadGateway = 502, 141 HTTPServiceUnavailable = 503, 142 HTTPGatewayTimeOut = 504, 143 HTTPHTTPVersionNotSupported = 505 144 145 } HTTPRequestReturn; 146 147 /* flags for parseURL */ 148 typedef enum { 149 PARSE_SCHEME = 1, 150 PARSE_USER = 2, 151 PARSE_PASSWORD = 4, 152 PARSE_HOSTNAME = 8, 153 PARSE_PORT = 16, 154 PARSE_FILENAME = 32 155 }HTTPParseURL; 156 157 #define PARSE_URL (PARSE_SCHEME|PARSE_HOSTNAME|PARSE_PORT|PARSE_FILENAME) 158 159 /***** 160 * Used internally for HTTP headers and externally for the form data 161 * name/value pairs 162 *****/ 163 typedef struct _HTTPNamedValues { 164 char *name; 165 char *value; 166 } HTTPNamedValues; 167 168 /***** 169 * Definition of a requestor. 170 * *never* store static data in the ptr fields as deleteHTTPRequest explicitly 171 * frees any non-NULL fields. 172 *****/ 173 typedef struct _HTTPRequest { 174 HTTPLoadType type; /* load to string or file */ 175 char *in_data; /* filename for LoadToFile */ 176 HTTPNamedValues *form_data; /* data for form processing */ 177 unsigned char *out_data; /* response string */ 178 size_t length; /* length of out_data, from 179 * Content-Length or strlen 180 */ 181 HTTPLoadMethod method; /* get, post etc */ 182 char *url; /* fully qualified location */ 183 184 int timeout; /* select() timeout in seconds */ 185 int retry; /* retry count, zero based */ 186 187 HTTPNamedValues *headers; /* array of returned headers */ 188 int num_headers; /* no of headers */ 189 190 HTTPRequestReturn ret; /* Server return value */ 191 }HTTPRequest; 192 193 /* type of cookies 194 * Not a lot an application can do here, it all depends on what the 195 * server sends. 196 * 197 * SetCookie implies the server is using Netscape style cookies. 198 * SetCookie means the server is using RFC2109 style cookies. 199 */ 200 enum { SetCookie, SetCookie2 }; 201 202 /* type of cookie file 203 * For safety I am only going to support the writting of CookieJar files 204 * however, I will allow an application to read cookie files generated by 205 * netscape. 206 * 207 * CookieJar (a name I've just invented) files are much richer than Netscape 208 * ones, they have to be they store the full SetCookie2 response. 209 */ 210 enum { NetscapeCookieFile = 1, CookieJar = 2 } ; 211 212 typedef struct _HTTPCookie { 213 214 HTTPNamedValues cookie; 215 char type; 216 char *comment; /* this and the url are not preserved between sessions*/ 217 char *commentURL; 218 int discard; 219 char *domain; 220 int exactHostMatch; 221 int secure; /* not supported in HTTP.c */ 222 char *path; 223 int expires; 224 char *port; 225 int version; 226 227 } HTTPCookie; 228 229 typedef struct _HTTPCookieList { 230 231 HTTPCookie *cookie; 232 struct _HTTPCookieList *next; 233 234 } HTTPCookieList; 235 236 typedef struct _HTTPCookieRequest { 237 238 HTTPCookieList *cookieList; 239 HTTPCookieList *setCookie; 240 241 int sendCookie; 242 243 } HTTPCookieRequest; 244 245 246 typedef struct _HTTPCookieCache { 247 248 HTTPCookie **cookies; 249 int ncookies; 250 251 char *filename; 252 char fileType; 253 254 } HTTPCookieCache ; 255 256 257 /***** 258 * Create a new, empty, request instance. This is the only safe way to create 259 * a request. 260 *****/ 261 extern HTTPRequest *newHTTPRequest(void); 262 263 /* make a request for some URI */ 264 extern void loadHTTPURL(void *unused, HTTPRequest * request, HTTPCookieRequest *cookieReq); 265 266 /***** 267 * Clear a no longer needed request instance. Deletes any field that have 268 * been allocated. 269 *****/ 270 extern void deleteHTTPRequest(HTTPRequest * req); 271 272 /* split a full URI into separate fields */ 273 extern void parseURL(char *url, long parseflag, char **scheme, 274 char **username, char **password, char **hostname, int *port, 275 char **filename); 276 277 /* free fields allocated by parseURL */ 278 extern void freeURL(long parseflag, char *scheme, char *username, 279 char *password, char *hostname, int port, char *filename); 280 281 /* Determine whether or not the given url should be retrieved via HTTP. */ 282 extern int HTTPAbsoluteURL(char *url); 283 284 /***** 285 * Compose a full URI from a (possibly local) url and the base url for this 286 * document. Return value should be freed by caller unless the return value 287 * is stored in a HTTPRequest in which case it will be freed when 288 * deleteHTTPRequest is called. 289 *****/ 290 extern char *HTTPFindAbsoluteURL(char *url, char *baseUrl); 291 292 /* display an error message for the given error code */ 293 extern void HTTPError(char *msg, HTTPRequestReturn error); 294 295 extern const char *HTTPErrorString(HTTPRequestReturn error); 296 297 /* unescape a HTTP escaped string */ 298 void HTTPUnescapeResponse(char *buf); 299 300 /* load the cookie file into memory, a cookieCache is self-contained so 301 * multiple files can be read within an app. 302 */ 303 extern HTTPCookieCache * loadCookieFileToCache(char * filename, char fileType); 304 305 /* The procedure for using cookies 306 * 307 * 1) load the cookie cache. 308 * 2) for a given URL, call getCookieFromCache(), this returns a 309 * CookieRequest, req->cookieList is a list of all the cookies that apply 310 * to the the URL (it will be NULL if no cookies are wanted by the server). 311 * 3) at this point the application can step in and inform the user that a 312 * cookie is wanted by the server, if the user doesn't want to send the 313 * cookie, it should set cookieRequest->sendCookie to false _before_ calling 314 * loadHTTPUrl() (this is better than simply passing NULL into 315 * loadHTTPUrl() since it gives tha application chnace to recieve any new 316 * cookies. 317 * 4) on return from loadHTTPUrl() cookieRequest->setCookie will be non-null 318 * if the server sent a save cookie response. The application can then 319 * decide to save this cookie for the rest of the session by calling 320 * addCookieListToCache (passing in cookieRequest->setCookie). 321 * 5) for permanant saving of the cookies the application needs to call 322 * writeCookieCache(); 323 */ 324 325 /* 326 * Notes. 327 * 328 * url must be fully qualified, CookieList is a linked-list of Cookies, all 329 * that apply to the url. 330 * 331 * To save the cookies between sessions, use writeCookieCache(). This writes 332 * cache back out (including any new cookies set during the session). Note that 333 * for safety, I'm not going to allow for the writing of Netscape cookie files 334 * (but using mergeCookieCache() we can read the existing Netscape cookie file 335 * and merge it with a custom cookie file (makes it easier moving to a new 336 * browser from netscape. 337 * ---if pushed, this may change later. 338 */ 339 340 extern HTTPCookieRequest *getCookieFromCache(HTTPCookieCache *, char * url); 341 342 extern void addCookieListToCache(HTTPCookieCache *, HTTPCookieList *); 343 344 extern void writeCookieCache(HTTPCookieCache *cache); 345 346 /* take the cookies from cache c2 and add them into c1. 347 * The reason for this is so that you can open an empty CookieJar file _and_ 348 * a Netscape cookie file (in that order), then take the cookies from the 349 * Netscape file and save them into the CookieJar file (since I don't 350 * support the writing of Netscape cookie files 351 * 352 * Do not free c2 353 */ 354 extern void mergeCookieCache(HTTPCookieCache *c1, HTTPCookieCache *c2); 355 356 void freeCookieCache(HTTPCookieCache * , int /* free cookies ? */); 357 void freeCookieRequest(HTTPCookieRequest *); 358 359 /* convenience macros */ 360 #define NewNString(STR,len) \ 361 ((STR) != NULL ? (strncpy(calloc(len+1,sizeof(char)), STR,(len))) : NULL) 362 363 #define NewString(STR) \ 364 ((STR) != NULL ? (strcpy(malloc(strlen(STR)+1),STR)) : NULL) 365 366 #define stringToBoolean(str) \ 367 ((str) != NULL && *(str) ? ( *(str) == 'T' || *(str) == 't' || *(str) == 'y' ? 1: 0 ) : 0) 368 369 #endif /* _LIBRARY */ 370 371 /* Don't add anything after this endif! */ 372 #endif /* _HTTP_h_ */ 373