⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http.c

📁 windows mobile上面实现的http协议
💻 C
字号:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "sock.h"
#include "http.h"
#include "url.h"

//#define WAP_PROXY

#define RSP_LENGTH "Content-Length"
#define RSP_STATE  "HTTP/1.1"

typedef struct
{
	IHttpClient vt;
	TUrl  url;
	ISock * sock;
	char method[5];
} CSimpHttp;

#ifdef WAP_PROXY
static AStream * CSimpHttp_request(CSimpHttp * i, char * url)
{
	AStream * out;

	i->sock = InitSock();
	if (i->sock)
	{
		out = i->sock->Connect(i->sock, "10.0.0.172", 80);
		
		if (out == NULL)
		{
			i->sock->Release(i->sock);
			i->sock = NULL;
			return out;
		}
		url_parse(url, &i->url);

		ASTREAM_WRITESTR(out, i->method);
		out->Write(out, "\x20", 1);
		ASTREAM_WRITESTR(out, url);
		ASTREAM_WRITESTR(out, "\x20HTTP/1.1\r\nHost:");

		ASTREAM_WRITESTR(out, i->url.host);
		ASTREAM_WRITESTR(out, "\r\n");
			
		if (i->vt.ext_head)
		{
			ASTREAM_WRITESTR(out, i->vt.ext_head);
		}
		ASTREAM_WRITESTR(out, "Accept: */*\r\nUser-Agent: TDTV-Aspire;\r\n\r\n");
	}

	return out;
}
#else
static AStream * CSimpHttp_request(CSimpHttp * i, char * url)
{
	AStream * out;

	i->sock = InitSock();

	if (i->sock)
	{
		url_parse(url, &i->url);
		out = i->sock->Connect(i->sock, i->url.host, i->url.port);
		
		if (out == NULL)
		{
			i->sock->Release(i->sock);
			i->sock = NULL;
			return out;
		}

		ASTREAM_WRITESTR(out, i->method);
		out->Write(out, "\x20", 1);
		ASTREAM_WRITESTR(out, i->url.file);
		ASTREAM_WRITESTR(out, "\x20HTTP/1.1\r\nHost:");

		ASTREAM_WRITESTR(out, i->url.host);
		ASTREAM_WRITESTR(out, "\r\n");
			
		if (i->vt.ext_head)
		{
			ASTREAM_WRITESTR(out, i->vt.ext_head);
		}
		ASTREAM_WRITESTR(out, "Accept: */*\r\nUser-Agent: TDTV-Aspire;\r\n\r\n");
	}

	return out;
}
#endif

#define IsHeaderEnd(s, p) (ReadLine(s, p) && *p == 0)

static int ReadLine(ISock * s, char *p, int cbMax)
{
	int i = 0;
	for (;s->Read(s, p, 1)==1 && i<cbMax; ++i)
	{
		if (*p == '\n')
		{
			*(--p) = 0;
			return i;
		}
		++p;
	}

	return 0;
}

//0通讯错
//其他为http返回码,如200,404等
static int CSimpHttp_commit(CSimpHttp * i, AStream * o)
{
	uint32_t status = 404;
	int nRead = 0;
	int nBodyLen = 0;
	char str[512];
	char * pTmp;
	assert(i->sock != NULL);
	
	if (nRead = ReadLine(i->sock, str, 512))
	{
		status = atoi(str + sizeof(RSP_STATE));
	}
	else
	{
		return 0;
	}

	while (nRead = ReadLine(i->sock, str, 512))
	{
		if (*str == 0)
		{//http头结束
			break;
		}
	
		if (!strncmp(str, RSP_LENGTH, sizeof(RSP_LENGTH) - 1))
		{//找到Content-Length串
			pTmp = strchr(str, ':');
			++pTmp;
			nBodyLen = atoi(pTmp);
			continue;
		}
	}

	if (nRead == 0)
		return 0;

	while (nBodyLen)
	{
		nRead = i->sock->Read(i->sock, str, 512);
		if (o)
		{
			o->Write(o, str, nRead);
		}
		nBodyLen -= nRead;
	}
	
	return status;
}

static void CSimpHttp_Release(CSimpHttp * i)
{
	if (i->sock)
	{
		i->sock->Release(i->sock);
		i->sock = NULL;
	}

	free(i);
}

IHttpClient * SimpleHttpClient(int method)
{
	CSimpHttp * simpleHttp = (CSimpHttp *) malloc(sizeof(CSimpHttp));
	simpleHttp->vt.ext_head = NULL;

	if (method == GET)
		strcpy(simpleHttp->method, "GET");
	else
		strcpy(simpleHttp->method, "POST");

	simpleHttp->vt.request = CSimpHttp_request;
	simpleHttp->vt.commit = CSimpHttp_commit;
	simpleHttp->vt.Release = CSimpHttp_Release;
	return (IHttpClient*)simpleHttp;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -