http.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * http.c
  3. * HTTP parsers.
  4. *
  5. * Matej Pfajfar <mp292@cam.ac.uk>
  6. */
  7. /*
  8. * Changes :
  9. * $Log$
  10. * Revision 1.3 2002/09/09 04:10:58 arma
  11. * port to actual BSD
  12. *
  13. * (hey nick, does this break the os x build?)
  14. *
  15. * you still need to add some stuff to the ./configure commandline...
  16. * anybody know a better solution?
  17. *
  18. * Revision 1.2 2002/08/24 07:56:22 arma
  19. * proxies send port in host order as ascii string
  20. *
  21. * Revision 1.1.1.1 2002/06/26 22:45:50 arma
  22. * initial commit: current code
  23. *
  24. * Revision 1.2 2002/04/02 14:27:33 badbytes
  25. * Final finishes.
  26. *
  27. * Revision 1.1 2002/03/12 23:46:14 mp292
  28. * HTTP-related routines.
  29. *
  30. */
  31. #include <sys/types.h>
  32. #include <sys/socket.h>
  33. #include <sys/time.h>
  34. #include <netinet/in.h>
  35. #include <netdb.h>
  36. #include <arpa/inet.h>
  37. #include <errno.h>
  38. #include <ctype.h>
  39. #include <stdio.h>
  40. #include <unistd.h>
  41. #include <limits.h>
  42. #include <string.h>
  43. #include <stdlib.h>
  44. #include <time.h>
  45. #include "../common/log.h"
  46. #include "../common/utils.h"
  47. #include "http.h"
  48. int http_get_line(int s, unsigned char **line, size_t *len, struct timeval *conn_tout)
  49. {
  50. int retval =0; /* function return value */
  51. unsigned char buf[HTTPAP_MAXLEN]; /* line buffer */
  52. unsigned int buflen = 0; /* length of the received data */
  53. char got_cr = 0; /* received a CR character and hence expecting a LF */
  54. unsigned char c; /* input character */
  55. if (!line || !len) /* invalid parameters */
  56. return -1;
  57. while(1)
  58. {
  59. retval = read_tout(s, &c, 1, MSG_WAITALL, conn_tout);
  60. if (retval < 1)
  61. return -1;
  62. if (buflen >= HTTPAP_MAXLEN)
  63. return -1;
  64. buf[buflen++] = c;
  65. if (got_cr)
  66. {
  67. if (c != HTTPAP_LF)
  68. return -1;
  69. else
  70. break;
  71. }
  72. else
  73. {
  74. if (c == HTTPAP_CR)
  75. got_cr = 1;
  76. }
  77. }
  78. *len = buflen;
  79. if (buflen)
  80. {
  81. *line = (unsigned char *)malloc(buflen+1);
  82. if (!*line)
  83. return -1;
  84. else
  85. {
  86. memcpy((void *)*line,(void *)buf,buflen);
  87. (*line)[buflen] = 0; /* add the terminating null character */
  88. }
  89. }
  90. else
  91. *line = NULL;
  92. return 0;
  93. }
  94. int http_get_version(unsigned char *rl, unsigned char **http_ver)
  95. {
  96. unsigned char *start;
  97. unsigned char *end;
  98. if (!rl || !http_ver) /* invalid parameters */
  99. return -1;
  100. start = strrchr(rl, ' ');
  101. if (!start)
  102. return -1;
  103. end = strrchr(rl, HTTPAP_CR);
  104. if (!end)
  105. return -1;
  106. start++;
  107. *http_ver = (unsigned char *)malloc(end-start+1);
  108. if (!*http_ver)
  109. return -1;
  110. strncpy(*http_ver, start, end-start);
  111. (*http_ver)[end-start] = 0; /* terminating NULL character */
  112. return 0;
  113. }
  114. int http_get_dest(unsigned char *rl, unsigned char **addr, unsigned char **port)
  115. {
  116. unsigned char *start;
  117. unsigned char *end;
  118. unsigned char *colon;
  119. if (!rl || !addr || !port) /* invalid parameters */
  120. return -1;
  121. start = strchr(rl, ' ');
  122. if (!start)
  123. return -1;
  124. start++;
  125. /* make sure this is really an http:// address */
  126. if (strncmp(start,"http://",7))
  127. return -1;
  128. start += 7;
  129. end = strchr(start,'/');
  130. if (!end)
  131. return -1;
  132. /* check for a :port in the address */
  133. /* BUG: if there's a : later in the url, eg in google's cache pages,
  134. * this gets confused and fails
  135. */
  136. colon = strchr(start,':');
  137. if (colon)
  138. {
  139. colon++;
  140. *port = (unsigned char *)malloc(end-colon+1);
  141. if (!*port)
  142. return -1;
  143. strncpy(*port,colon, end-colon);
  144. (*port)[end-colon] = 0; /* terminating NULL character */
  145. end = colon-1;
  146. }
  147. else
  148. *port = NULL;
  149. /* extract the server address */
  150. *addr = (unsigned char *)malloc(end-start+1);
  151. if (!*addr)
  152. {
  153. if (*port)
  154. free((void *)*port);
  155. return -1;
  156. }
  157. strncpy(*addr,start, end-start);
  158. (*addr)[end-start] = 0; /* terminating NULL character */
  159. return 0;
  160. }
  161. int http_get_header_name(unsigned char *rl, unsigned char **hname)
  162. {
  163. unsigned char *end;
  164. if (!rl || !hname) /* invalid parameters */
  165. return -1;
  166. end = strchr(rl, ':');
  167. if (!end)
  168. return -1;
  169. *hname = (unsigned char *)malloc(end-rl+1);
  170. if (!*hname)
  171. return -1;
  172. strncpy(*hname,rl,end-rl);
  173. (*hname)[end-rl] = 0;
  174. return 0;
  175. }