Skip to content

Instantly share code, notes, and snippets.

@aont
Created February 25, 2012 16:29
Show Gist options
  • Select an option

  • Save aont/1909364 to your computer and use it in GitHub Desktop.

Select an option

Save aont/1909364 to your computer and use it in GitHub Desktop.
C++ http
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
static int tcp_open(const char* const address, const u_short port)
{
struct sockaddr_in dstAddr;
bzero((char*)&dstAddr, sizeof(dstAddr));
dstAddr.sin_family = AF_INET;
dstAddr.sin_port = htons(port);
const struct hostent * const hp = gethostbyname(address);
if(hp==NULL) return -h_errno;
bcopy(hp->h_addr, &dstAddr.sin_addr, hp->h_length);
const int dstSocket = socket(AF_INET, SOCK_STREAM, 0);
const int ret_connect = connect(dstSocket, (struct sockaddr*)&dstAddr, sizeof(dstAddr));
if(ret_connect<0) return ret_connect;
return dstSocket;
}
class http
{
private:
FILE* fp;
public:
http(const int fd) : fp(fdopen(fd, "r+")) { }
http(const char* const address, const u_short port)
{
struct sockaddr_in dstAddr;
bzero((char*)&dstAddr, sizeof(dstAddr));
dstAddr.sin_family = AF_INET;
dstAddr.sin_port = htons(port);
const struct hostent * const hp = gethostbyname(address);
if(hp==NULL) throw h_errno;
bcopy(hp->h_addr, &dstAddr.sin_addr, hp->h_length);
const int dstSocket = socket(AF_INET, SOCK_STREAM, 0);
const int ret_connect = connect(dstSocket, (struct sockaddr*)&dstAddr, sizeof(dstAddr));
if(ret_connect<0) throw ret_connect;
this->fp = fdopen(dstSocket, "r+");
}
int get(const char* const path) const
{
return fprintf(fp, "GET %s HTTP/1.1\r\n", path);
}
int header_host(const char* const hostname) const
{
return fprintf(fp, "HOST: %s\r\n", hostname);
}
int header_range(const int start, const int end) const
{
return fprintf(fp, "Range: bytes=%d-%d\r\n", start, end);
}
int header_connection(const bool alive) const
{
if(alive)
return fprintf(fp, "Connection: Keep-Alive\r\n");
else
return fprintf(fp, "Connection: close\r\n");
}
int request() const
{
const int ret_fprintf = fprintf(fp, "\r\n");
if(ret_fprintf<0) return ret_fprintf;
const int ret_fflush = fflush(fp);
return ret_fflush;
}
void read_get(FILE* const fp_out) const
{
{
char version_str[8];
int status_num;
char message_str[128];
const int ret_fscanf = fscanf(fp, "HTTP/%s %d %[^\r]\r\n", version_str, &status_num, message_str);
if(ret_fscanf!=3) throw ret_fscanf;
fprintf(stderr, "Status %d %s\n", status_num, message_str);
}
int content_length = -1;
while(true) {
char buf[1024];
const char* const ret_fgets = fgets(buf, sizeof(buf), fp);
if(ret_fgets==NULL) throw ret_fgets;
char key_str[128]; char value_str[128];
const int ret_sscanf = sscanf(buf, "%[^:]: %[^\r]\r\n", key_str, value_str);
if(ret_sscanf!=2) {
if(strcmp(buf, "\r\n")) throw;
break;
}
fprintf(fp_out, "key: %s\n", key_str);
fprintf(fp_out, "data: %s\n", value_str);
if(strcmp(key_str, "Content-Length")==0) {
sscanf(value_str, "%d", &content_length);
}
}
if(content_length>0) {
char* const body_ary = (char*)malloc(content_length);
fread(body_ary, 1, content_length, fp);
fprintf(fp_out, "%s", body_ary);
free(body_ary);
} else {
;
}
}
int close() const { return fclose(this->fp); }
};
int main()
{
const char addr[] = "www.google.co.jp";
http http(addr, 80);
http.get("/");
http.header_host(addr);
http.header_range(0, 500);
http.header_connection(false);
http.request();
http.read_get(stdout);
http.close();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment