1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
/* $Id: http.c 394 2007-03-29 20:27:50Z bortz $ */
#include "echoping.h"
#ifdef HTTP
#include "HTParse.h"
char big_recvline[MAXTOREAD];
char *
make_http_sendline(char *url, char *host, int port, int nocache)
{
short sport = (short) port;
int size = 350; /* Enough? RFC 2616, section 3.2.1 says 255
* should be enough, although there is no
* hard limit. We reserve more because there
* * are the protocol elements, the HTTP
* headers, etc */
char *sendline = (char *) malloc(size);
char *hostname = (char *) malloc(size);
char *cache_directive = "";
int result;
#ifdef HTTP10
if (nocache)
cache_directive = "Pragma: no-cache\r\n"; /* RFC 1945,
* "Hypertext
* Transfer Protocol
* * -- HTTP/1.0" */
result = snprintf(sendline, size,
"GET %s HTTP/1.0\r\nUser-Agent: Echoping/%s\r\n%s\r\n",
url, VERSION, cache_directive);
#else
if (nocache) {
if (nocache == 1)
cache_directive = "Cache-control: max-age=0\r\n"; /* Simply
* force
* a
* recheck
* with
* the
* server
*/
else
cache_directive = "Cache-control: no-cache\r\n"; /* RFC
* 2616
* "Hypertext
* Transfer
* Protocol --
* HTTP/1.1" */
}
strncpy(hostname, HTParse(url, "", PARSE_HOST), size); /* See bug #1688940
* to see why we use
* * strNcpy. */
hostname[size] = '\0'; /* Not added automatically */
if (!strcmp(hostname, ""))
snprintf(hostname, size, "%s:%d", host, sport);
result = snprintf(sendline, size,
"GET %s HTTP/1.1\r\nUser-Agent: Echoping/%s\r\nHost: %s\r\nConnection: close\r\n%s\r\n",
url, VERSION, hostname, cache_directive);
free(hostname);
#endif
if (result >= size)
err_quit("URL and/or hostname too long(s)");
return sendline;
}
int
read_from_server(CHANNEL fs, short ssl, boolean accept_redirects)
{
int nr = 0;
int total = 0;
char reply_code;
int first_line = TRUE;
short body = FALSE;
#ifdef OPENSSL
int sslcode;
#endif
while (!body && !timeout_flag) {
if (!ssl)
nr = readline(fs.fs, big_recvline, MAXTOREAD, TRUE);
#ifdef OPENSSL
else {
nr = SSL_readline(fs.ssl, big_recvline, MAXTOREAD, TRUE);
if (nr == -1) {
sslcode = ERR_get_error();
err_ret("SSL_readline error: %s",
ERR_error_string(sslcode, NULL));
}
}
#endif
#ifdef GNUTLS
else
{
nr = TLS_readline(fs.tls, big_recvline, MAXTOREAD, TRUE);
if (nr == -1) {
err_ret("TLS_readline error: %s",
gnutls_strerror(nr));
}
}
#endif
/*
* printf ("DEBUG: reading \"%s\"\n (%d chars)\n",
* big_recvline, nr);
*/
/*
* HTTP replies should be separated by CR-LF. Unfortunately,
* some servers send only CR :-(
*/
body = ((nr == 2) || (nr == 1)); /* Empty line CR-LF seen */
if ((nr < 1) && (timeout_flag)) /* Probably a timeout */
return -1;
if (nr < 1)
/* SourceForge bug #109385 */
/* err_sys ("Error reading HTTP header"); */
return -1;
/*
* if ((int) big_recvline[nr-1] == 10) nr--;
*/
if (first_line) {
reply_code = big_recvline[9]; /* 9 because "HTTP/1.x
* 200..." */
if (reply_code != '2'
&& !(reply_code == '3' && accept_redirects))
/*
* Status codes beginning with 3 are not
* errors See bug #850674 and RFC 2616,
* section 10.3
*/
err_quit("HTTP error \"%s\"", big_recvline);
}
total = total + nr;
first_line = FALSE;
}
/* Read the body */
if (!ssl)
nr = readline(fs.fs, big_recvline, MAXTOREAD, FALSE);
#ifdef OPENSSL
else
nr = SSL_readline(fs.ssl, big_recvline, MAXTOREAD, FALSE);
#endif
#ifdef GNUTLS
else
nr = TLS_readline(fs.tls, big_recvline, MAXTOREAD, FALSE);
#endif
/*
* printf ("DEBUG: reading body \"%s\"\n (%d chars)\n", big_recvline,
* nr);
*/
if ((nr < 2) && (timeout_flag)) /* Probably a timeout */
return -1;
if (nr < 2) /* Hmm, if the body is empty, we'll get a * * * * *
* * meaningless error message */
err_sys("Error reading HTTP body");
total = total + nr;
return total; /* How to do if we want only the body's size? */
}
#endif /* HTTP */
|