187 lines
3.4 KiB
C++
187 lines
3.4 KiB
C++
#include <sys/types.h>
|
|
|
|
#include "./def.h"
|
|
#include "./httpencode.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
|
|
#include "./config.h"
|
|
|
|
#ifndef HAVE_STRNSTR
|
|
|
|
/* FUNCTION PROGRAMER: Siberiaic Sang */
|
|
static char* strnstr(const char *haystack,const char *needle,size_t haystacklen)
|
|
{
|
|
char *p;
|
|
ssize_t plen;
|
|
ssize_t len = strlen(needle);
|
|
|
|
if (*needle == '\0')
|
|
return (char*) haystack;
|
|
|
|
plen = haystacklen;
|
|
for (p = (char*) haystack; p != (char*) 0; p = (char*)memchr(p + 1, *needle, plen-1)) {
|
|
plen = haystacklen - (p - haystack);
|
|
|
|
if (plen < len) return (char*) 0;
|
|
|
|
if (strncmp(p, needle, len) == 0)
|
|
return (p);
|
|
}
|
|
return (char*) 0;
|
|
}
|
|
#endif
|
|
/* ************************************************** */
|
|
|
|
static void url_encode_char(char *b,char c)
|
|
{
|
|
char HEX_TABLE[] = "0123456789ABCDEF";
|
|
b[0] = '%';
|
|
b[1] = HEX_TABLE[(c >> 4) & 0x0F];
|
|
b[2] = HEX_TABLE[c & 0x0F];
|
|
}
|
|
|
|
char* Http_url_encode(char *s,char *b,size_t n)
|
|
{
|
|
size_t r,i;
|
|
for(r = 0,i = 0 ; i < n; i++){
|
|
if( isalpha(b[i]) || isdigit(b[i]) ){
|
|
s[r] = b[i];
|
|
r++;
|
|
}else{
|
|
url_encode_char(s + r, b[i]);
|
|
r += 3;
|
|
}
|
|
}
|
|
s[r] = '\0';
|
|
return s;
|
|
}
|
|
|
|
|
|
//ipv6 support available
|
|
int Http_url_analyse(char *url,char *host,int *port,char *path)
|
|
{
|
|
char *p;
|
|
int r;
|
|
*port = 80; /* default port 80 */
|
|
p = strstr(url,"://");
|
|
if( !p )
|
|
p = url;
|
|
else
|
|
p += 3;
|
|
/* host */
|
|
if(*p == '[') {
|
|
// tracker's ipv6 address
|
|
p++;
|
|
for(; *p && (isalnum(*p) || *p == ':' ); p++, host++)
|
|
*host = *p;
|
|
if( *p != ']') return -1;
|
|
p++;
|
|
}
|
|
else {
|
|
// hostname in dns
|
|
for(; *p && (isalnum(*p) || *p == '.' || *p == '-'); p++, host++)
|
|
*host = *p;
|
|
}
|
|
*host = '\0';
|
|
|
|
if( *p == ':' ){
|
|
/* port */
|
|
p++;
|
|
for( r = 0; p[r] >= '0' && p[r] <= '9' && r < 6; r++) ;
|
|
|
|
if( !r ) return -1;
|
|
*port = atoi(p);
|
|
if(*port > 65536) return -1;
|
|
p += r;
|
|
}
|
|
|
|
/* path */
|
|
if( *p != '/' ) return -1;
|
|
for( ; *p && *p != '?'; p++,path++) *path = *p;
|
|
*path = '\0';
|
|
return 0;
|
|
}
|
|
|
|
size_t Http_split(char *b,size_t n,char **pd,size_t *dlen)
|
|
{
|
|
char *p;
|
|
size_t addtion, hlen;
|
|
|
|
addtion = 2; hlen = 0;
|
|
|
|
if( n < 16 ) return 0;
|
|
|
|
if(strncasecmp(b,"HTTP/",5) != 0){
|
|
return 0;
|
|
/* message without http header */
|
|
//*pd = b;
|
|
//*dlen = n;
|
|
}else{
|
|
p = strnstr(b,"\n\n",n);
|
|
if( !p ){ p = strnstr(b,"\r\n\r\n",n); if(p) addtion = 4;}
|
|
|
|
if( p ){
|
|
hlen = p - b;
|
|
*pd = ( p + addtion );
|
|
*dlen = n - hlen - addtion;
|
|
}else{
|
|
hlen = n;
|
|
*pd = (char*) 0;
|
|
*dlen = 0;
|
|
}
|
|
}
|
|
return hlen;
|
|
}
|
|
|
|
int Http_reponse_code(char *b,size_t n)
|
|
{
|
|
int r = -1;
|
|
|
|
for(; n && *b != ' ' && *b != '\n'; b++,n--) ;
|
|
if( !n || *b != ' ') r = -1;
|
|
else{
|
|
r = atoi(b);
|
|
if( r < 100 || r > 600 ) r = -1;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
int Http_get_header(char *b,int n,char *header,char *v)
|
|
{
|
|
char *e,h[64];
|
|
int r,header_len;
|
|
|
|
strcpy(h,header);
|
|
strcat(h,": ");
|
|
header_len = strlen(h);
|
|
|
|
/* remove status line. */
|
|
e = strchr(b,'\n');
|
|
if( !e ) return -1;
|
|
e++;
|
|
n -= (e - b);
|
|
b = e;
|
|
|
|
for(; n >= 0; ){
|
|
e = strchr(b,'\n');
|
|
if( !e ) r = n; /* last line */
|
|
else{r = e - b ; r++;}
|
|
|
|
if( r > header_len ){
|
|
if( strncasecmp(b, h, header_len) == 0){
|
|
/* header founded */
|
|
b += header_len;
|
|
for(; *b != '\n'; v++,b++) *v = *b;
|
|
*v = '\0';
|
|
return 0;
|
|
}
|
|
}
|
|
b += r;
|
|
n -= r;
|
|
} /* end for */
|
|
return -1;
|
|
}
|