关于 LIBGHTTP 收集的资料
龚勇锐
2023-12-01
源码在这里:
http://libghttp.sourcearchive.com/documentation/1.0.9-17/files.html
注意一个问题:
用函数获 ghttp_get_body_len() 取长度时,如果要得到的包长度比较长话, 有可能对端服务器没有flush,把缓冲区的内容输出, 导致长度始终是一个定值。
例子
A simple example
Here's a simple example to get you started. This snippit of code shows how you can go out and get a file off of an HTTP server. Please note that this code contains no error checking at all.
// This is the http request object
ghttp_request *request = NULL;
// Allocate a new empty request object
request = ghttp_request_new();
// Set the URI for the request object
ghttp_set_uri(request, "http://localhost:8080/index.html");
// Close the connection after you are done.
ghttp_set_header(request, http_hdr_Connection, "close");
//Prepare the connection
ghttp_prepare(request);
// Process the request
ghttp_process(request);
// Write out the body. Note that the body of the request may not be null terminated so we have to be careful of the length.
fwrite(ghttp_get_body(request), ghttp_get_body_len(request), 1, stdout);
//Destroy the request. This closes any file descriptors that may be open and will free any memory associated with the request.
ghttp_request_destroy(request);
simple-get.c
#include <stdio.h>
#include <ghttp.h>
#include <unistd.h>
void bail(char *s)
{
fputs(s, stderr); fputc('\n', stderr);
exit(1);
}
void status(ghttp_request *r, char *desc)
{
ghttp_current_status st;
st = ghttp_get_status(r);
fprintf(stderr, "%s: %s [%d/%d]\n",
desc,
st.proc == ghttp_proc_request ? "request" :
st.proc == ghttp_proc_response_hdrs ? "response-headers" :
st.proc == ghttp_proc_response ? "response" : "none",
st.bytes_read, st.bytes_total);
}
int main(int argc, char **argv)
{
int bytes = 0;
ghttp_request *req;
ghttp_status req_status;
if (argc < 2) bail("usage: simple-get URI");
req = ghttp_request_new();
if (ghttp_set_uri(req,argv[1]) < 0)
bail("ghttp_set_uri");
if (ghttp_prepare(req) < 0)
bail("ghttp_prepare");
if (ghttp_set_sync(req, ghttp_async) < 0)
bail("ghttp_set_sync");
do {
status(req, "conn0");
req_status = ghttp_process(req);
if (req_status == ghttp_error) {
fprintf(stderr, "ghttp err: %s\n",
ghttp_get_error(req));
return 2;
}
if (req_status != ghttp_error && ghttp_get_body_len(req) > 0) {
bytes += ghttp_get_body_len(req);
ghttp_flush_response_buffer(req);
}
} while (req_status == ghttp_not_done);
fprintf(stderr, "conn0 received %d bytes\n", bytes);
ghttp_clean(req);
return 0;
}
转自 http://blog.sina.com.cn/s/blog_498a6eeb0100s186.html
前些时间,由于找不到一个比较好使用的http库,自己封装了一个,不过时间紧迫,也没有完整分析HTTP协议,因此心里总不塌实地使用它,一次偶然的机会,让我在网上找到一个好用的http库 -- libghttp,目前的版本因该是libghttp-1.0.9.
这个库十分的方便使用,它能够轻松地实现同步和异步的Http请求。
简单使用实例:
#include <ghttp.h>
int main(int argc, char *argv[])
{
char *uri = "http://www.hao123.com";
ghttp_request *request = NULL;
ghttp_status status;
char *buf;
int bytes_read;
request = ghttp_request_new();
if(ghttp_set_uri(request, uri) == -1)
exit(-1);
if(ghttp_set_type(request, ghttp_type_get) == -1)
exit(-1);
ghttp_prepare(request);
status = ghttp_process(request);
if(status == ghttp_error)
exit(-1);
/* OK, done */
printf("Status code -> %d/n", ghttp_status_code(request));
buf = ghttp_get_body(loader->request);
bytes_read = ghttp_get_body_len(loader->request);
return 0;
}
异步请求实例:
#include <ghttp.h>
int main(int argc, char *argv[])
{
char *uri = "http://www.hao123.com";
ghttp_request *request = NULL;
ghttp_status status;
char *buf;
int bytes_read;
request = ghttp_request_new();
if(ghttp_set_uri(request, uri) == -1)
exit(-1);
if(ghttp_set_type(request, ghttp_type_get) == -1)
exit(-1);
/* NOTE: Set async request */
ghttp_set_sync(request, ghttp_async);
ghttp_prepare(request);
while(1) {
status = ghttp_process(request);
if(status == ghttp_error)
break;
/* NOTE: buf may NULL, notice it */
buf = ghttp_get_body(loader->request);
bytes_read = ghttp_get_body_len(loader->request);
if(status == ghttp_done) {
/* NOTE: Ok, done */
break;
}
}
return 0;
}
libcurl note(Http应用)
设置Callback function处理Http头,返回内容,进度
CURLOPT_WRITEFUNCTION
CURLOPT_WRITEDATA
CURLOPT_HEADERFUNCTION
CURLOPT_HEADERDATA
CURLOPT_NOPROGRESS
CURLOPT_PROGRESSFUNCTION
CURLOPT_PROGRESSDATA
设置连接等待时间,传输等待时间:
CURLOPT_TIMEOUT:
CURLOPT_CONNECTIONTIMEOUT:
设置重定位URL:
CURLOPT_FOLLOWLOCATION
实现断点续传:
CURLOPT_RANGE:
CURLOPT_RESUME_FROM:
注: 在我的测试中 这两个参数无效。 设置RANGE后 下载全部数据,而不是后续数据;设置RESUME_FROM后,程序无响应。
Http头设置:
Range: bytes=xx- [可以用来实现断点续传]
User-Agent: xx
Location: [网页重定位 url]
Set-Cookie: [Cookie]
Content-Length: [报文长度]
Content-Type: [报文类型]
例程:
test()
{
CURL *curl;
CURLcode res;
struct curl_slist *slist_header = NULL;
FILE *pFile_error = fopen(CURL_ERROR_FILE, "w+");
curl = curl_easy_init();
if(curl)
{
slist_header = curl_slist_append(slist_header, version_id.data());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist_header);
QString follow_location=QString("With follow location");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, follow_location.data());
curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout_connect); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &progress_percent) ;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &recv_buf);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); curl_easy_setopt(curl, CURLOPT_HEADERDATA, &header_buf);
curl_easy_setopt(curl, CURLOPT_POST, TRUE);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS,zip_buf);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE,zip_len);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_STDERR, pFile_error);
int res = curl_easy_perform(curl);
if (res == 0) {
.......
}
curl_easy_cleanup(curl);
curl_slist_free_all(slist_header);
fflush(pFile_error);
fclose(pFile_error);
}
}
CURLOPT_RESUME_FROM参数实验有效的。我使用的时候,他当前文件的大小作为参数一起传递进去,他会传递后续数据。
转自 http://blog.csdn.net/yjfkpyu/article/details/3955186