📄 ghttp.c
字号:
/* * ghttp.c -- Implementation of the public interface to http functions * Created: Christopher Blizzard <blizzard@appliedtheory.com>, 21-Aug-1998 * * Copyright (C) 1998 Free Software Foundation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdlib.h>#include <string.h>#include <unistd.h>#include "ghttp.h"#include "http_uri.h"#include "http_hdrs.h"#include "http_trans.h"#include "http_req.h"#include "http_resp.h"#include "http_date.h"#include "http_global.h"#include "http_base64.h"struct _ghttp_request{ http_uri *uri; http_uri *proxy; http_req *req; http_resp *resp; http_trans_conn *conn; const char *errstr; int connected; ghttp_proc proc; char *username; char *password; char *authtoken; char *proxy_username; char *proxy_password; char *proxy_authtoken;};static const char *basic_header = "Basic ";ghttp_request *ghttp_request_new(void){ struct _ghttp_request *l_return = NULL; /* create everything */ l_return = malloc(sizeof(struct _ghttp_request)); memset(l_return, 0, sizeof(struct _ghttp_request)); l_return->uri = http_uri_new(); l_return->proxy = http_uri_new(); l_return->req = http_req_new(); l_return->resp = http_resp_new(); l_return->conn = http_trans_conn_new(); return l_return;}voidghttp_request_destroy(ghttp_request *a_request){ if (!a_request) return; /* make sure that the socket was shut down. */ if (a_request->conn->sock >= 0) { close(a_request->conn->sock); a_request->conn->sock = -1; } /* destroy everything else */ if (a_request->uri) http_uri_destroy(a_request->uri); if (a_request->proxy) http_uri_destroy(a_request->proxy); if (a_request->req) http_req_destroy(a_request->req); if (a_request->resp) http_resp_destroy(a_request->resp); if (a_request->conn) http_trans_conn_destroy(a_request->conn); /* destroy username info. */ if (a_request->username) { free(a_request->username); a_request->username = NULL; } if (a_request->password) { free(a_request->password); a_request->password = NULL; } if (a_request->authtoken) { free(a_request->authtoken); a_request->authtoken = NULL; } /* destroy proxy authentication */ if (a_request->proxy_username) { free(a_request->proxy_username); a_request->proxy_username = NULL; } if (a_request->proxy_password) { free(a_request->proxy_password); a_request->proxy_password = NULL; } if (a_request->proxy_authtoken) { free(a_request->proxy_authtoken); a_request->proxy_authtoken = NULL; } if (a_request) free(a_request); return;}intghttp_uri_validate(char *a_uri){ if (!a_uri) return -1; /* you can do this... */ return(http_uri_parse(a_uri, NULL));}intghttp_set_uri(ghttp_request *a_request, char *a_uri){ int l_rv = 0; http_uri *l_new_uri = NULL; if ((!a_request) || (!a_uri)) return -1; /* set the uri */ l_new_uri = http_uri_new(); l_rv = http_uri_parse(a_uri, l_new_uri); if (l_rv < 0) { http_uri_destroy(l_new_uri); return -1; } if (a_request->uri) { /* check to see if this has been set yet. */ if (a_request->uri->host && a_request->uri->port && a_request->uri->resource) { /* check to see if we just need to change the resource */ if ((!strcmp(a_request->uri->host, l_new_uri->host)) && (a_request->uri->port == l_new_uri->port)) { free(a_request->uri->resource); /* make a copy since we're about to destroy it */ a_request->uri->resource = strdup(l_new_uri->resource); http_uri_destroy(l_new_uri); } else { http_uri_destroy(a_request->uri); a_request->uri = l_new_uri; } } else { http_uri_destroy(a_request->uri); a_request->uri = l_new_uri; } } return 0;}intghttp_set_proxy(ghttp_request *a_request, char *a_uri){ int l_rv = 0; if ((!a_request) || (!a_uri)) return -1; /* set the uri */ l_rv = http_uri_parse(a_uri, a_request->proxy); if (l_rv < 0) return -1; return 0;}intghttp_set_type(ghttp_request *a_request, ghttp_type a_type){ int l_return = 0; /* check to make sure that the args are ok */ if (!a_request) return -1; /* switch on all of the supported types */ switch(a_type) { case ghttp_type_get: a_request->req->type = http_req_type_get; break; case ghttp_type_options: a_request->req->type = http_req_type_options; break; case ghttp_type_head: a_request->req->type = http_req_type_head; break; case ghttp_type_post: a_request->req->type = http_req_type_post; break; case ghttp_type_put: a_request->req->type = http_req_type_put; break; case ghttp_type_delete: a_request->req->type = http_req_type_delete; break; case ghttp_type_trace: a_request->req->type = http_req_type_trace; break; case ghttp_type_connect: a_request->req->type = http_req_type_connect; break; case ghttp_type_propfind: a_request->req->type = http_req_type_propfind; break; case ghttp_type_proppatch: a_request->req->type = http_req_type_proppatch; break; case ghttp_type_mkcol: a_request->req->type = http_req_type_mkcol; break; case ghttp_type_copy: a_request->req->type = http_req_type_copy; break; case ghttp_type_move: a_request->req->type = http_req_type_move; break; case ghttp_type_lock: a_request->req->type = http_req_type_lock; break; case ghttp_type_unlock: a_request->req->type = http_req_type_unlock; break; default: l_return = -1; break; } return l_return;}intghttp_set_body(ghttp_request *a_request, char *a_body, int a_len){ /* check to make sure the request is there */ if (!a_request) return -1; /* check to make sure the body is there */ if ((a_len > 0) && (a_body == NULL)) return -1; /* check to make sure that it makes sense */ if ((a_request->req->type != http_req_type_post) && (a_request->req->type != http_req_type_put) && (a_request->req->type != http_req_type_proppatch) && (a_request->req->type != http_req_type_propfind) && (a_request->req->type != http_req_type_lock)) return -1; /* set the variables */ a_request->req->body = a_body; a_request->req->body_len = a_len; return 0;}intghttp_set_sync(ghttp_request *a_request, ghttp_sync_mode a_mode){ if (!a_request) return -1; if (a_mode == ghttp_sync) a_request->conn->sync = HTTP_TRANS_SYNC; else if (a_mode == ghttp_async) a_request->conn->sync = HTTP_TRANS_ASYNC; else return -1; return 0;}intghttp_prepare(ghttp_request *a_request){ /* only allow http requests if no proxy has been set */ if (!a_request->proxy->host && a_request->uri->proto && strcmp(a_request->uri->proto, "http")) return 1; /* check to see if we have to set up the host information */ if ((a_request->conn->host == NULL) || (a_request->conn->host != a_request->uri->host) || (a_request->conn->port != a_request->uri->port) || (a_request->conn->proxy_host != a_request->proxy->host) || (a_request->conn->proxy_port != a_request->proxy->port)) { /* reset everything. */ a_request->conn->host = a_request->uri->host; a_request->req->host = a_request->uri->host; a_request->req->full_uri = a_request->uri->full; a_request->conn->port = a_request->uri->port; a_request->conn->proxy_host = a_request->proxy->host; a_request->conn->proxy_port = a_request->proxy->port; a_request->conn->hostinfo = NULL; /* close the socket if it looks open */ if (a_request->conn->sock >= 0) { close(a_request->conn->sock); a_request->conn->sock = -1; a_request->connected = 0; } } /* check to see if we need to change the resource. */ if ((a_request->req->resource == NULL) || (a_request->req->resource != a_request->uri->resource)) { a_request->req->resource = a_request->uri->resource; a_request->req->host = a_request->uri->host; } /* set the authorization header */ if ((a_request->authtoken != NULL) && (strlen(a_request->authtoken) > 0)) { http_hdr_set_value(a_request->req->headers, http_hdr_Authorization, a_request->authtoken); } else { http_hdr_set_value(a_request->req->headers, http_hdr_WWW_Authenticate, NULL); } /* set the proxy authorization header */ if ((a_request->proxy_authtoken != NULL) && (strlen(a_request->proxy_authtoken) > 0)) { http_hdr_set_value(a_request->req->headers, http_hdr_Proxy_Authorization, a_request->proxy_authtoken); } http_req_prepare(a_request->req); return 0;}ghttp_statusghttp_process(ghttp_request *a_request){ int l_rv = 0; if (a_request->proc == ghttp_proc_none) a_request->proc = ghttp_proc_request; if (a_request->proc == ghttp_proc_request) { if (a_request->connected == 0) { if (http_trans_connect(a_request->conn) < 0) { if (a_request->conn->error_type == http_trans_err_type_errno) a_request->errstr = strerror(a_request->conn->error); else if(a_request->conn->error_type == http_trans_err_type_host) a_request->errstr = http_trans_get_host_error(h_errno); return ghttp_error; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -