http.h
来自「Shorthand是一个强大的脚本语言」· C头文件 代码 · 共 359 行
H
359 行
#ifndef __http_h
#define __http_h
/////////////////////////////////////////////////////////////////////////////
// $Header: /shorthand/src/http.h 4 8/28/02 6:27a Arm $
//---------------------------------------------------------------------------
// This file is part of "libAndrix" library - a collection of classes
// and functions developed by Andrei Remenchuk.
//---------------------------------------------------------------------------
// While you may own complete copyright on the project with which you have
// received this file, the author reserves the right to use code contained
// in this very file for any purposes, including publishing and usage in
// any free or commercial software.
//
// You may re-distribute this file or re-use it in your own free or
// commercial software provided that this text is included in the file.
// If you change this file you must include clear notice stating that
// you changed this file and the date of change.
//
// This statement doesn't apply to other files that are part of the same
// package unless otherwise noted.
//---------------------------------------------------------------------------
// (c) 1998-2002 Andrei Remenchuk <andrei@remenchuk.com>
//---------------------------------------------------------------------------
// http.h - HTTP client
/////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "map.h"
#include "cstring.h"
#include "datetime.h"
/**
* Generic URL object.
*/
class CURL
{
protected:
string m_url;
string m_host;
string m_port;
string m_protocol;
/** uri: everything that follows host name (or '/' if nothing follows) */
string m_uri;
/** path: everything from host (with '/' at the beginning up to first '?' */
string m_path;
/** directory: everything starting from '/' until last slash or '?' */
string m_directory;
/** file: everything after last slash until end-of-line or '?' */
string m_file;
/** query: everything after ? (or empty if there is no '?') */
string m_query;
/** top-level domain name (com/org/uk, etc.) */
string m_tld;
private:
void ctor();
public:
CURL();
CURL(const char* spec);
CURL(const CURL& curl);
void clear();
/** Parses URL from string specification. All member variables are replaced. */
void parse(const char* spec);
/** Makes deep copy of another URL object. */
void copyfrom(const CURL& curl);
/** Returns complete URL as string */
const char* url() const { return m_url; }
/** Returns hostname part of the URL as string */
const char* host() const { return m_host; }
/** Returns port part of the URL as string (which is empty if not explicitly defined) */
const char* port() const { return m_port; }
/** Returns protocol part of the URL as string (which is empty if not explicitly defined) */
const char* protocol() const { return m_protocol; }
/** Returns URI part of the URL as string (which is "/" if not explicitly defined) */
const char* uri() const { return m_uri; }
const char* path() const { return m_path; }
const char* query() const { return m_query; }
const char* directory() const { return m_directory; }
const char* file() const { return m_file; }
bool has_host() const { return !m_host.is_empty(); }
bool has_protocol() const { return !m_protocol.is_empty(); }
bool has_port() const { return !m_port.is_empty(); }
bool has_uri() const { return !m_uri.is_empty(); }
/**
* Returns top-level domain of the URL as string
* which is empty if host part was not fully-qualified name or if it
* was numeric address.
*/
const char* tld() const { return m_tld; }
/** Reports whether or not URL is empty (not initialized) */
bool is_empty() const;
/** Reports true if this is HTTPS URL */
bool is_secure() const;
/**
* Assignment operator that makes deep copy of another URL object.
*/
const CURL& operator = (const CURL& curl);
/**
* Creates follow-up URL based on the address of this URL
* and specified url which can be partial, in which case it is treated
* as relative to the address of this response object.
* For example, if this URL is from "https://www.my-server.com:3833/",
* and given url is /login.html?, the following URL will be produced:
* "https://www.myserver.com:3833/login.html".
*
* @param url URL or URI relative to this document.
* @param new_url resulting URL is written to this object.
*/
void followup(const char* url, CURL& new_url) const;
friend class CHttpRequest;
friend class CHttpResponse;
friend class CHttpUserAgent;
};
/**
* HTTP Cookie
*/
/**
* HTTP Cookie object.
*/
class CHttpCookie
{
protected:
string m_name;
string m_value;
datetime m_expires;
bool m_expireable;
string m_path;
string m_domain;
bool m_secure;
bool m_deleted;
protected:
CHttpCookie();
void ctor();
public:
/**
* Constructs cookie based on external spec, which is the format used
* in Set-Cookie: response header)
*/
CHttpCookie(const char* spec);
CHttpCookie(const char* name, const char* value, const datetime& expires, const char* path, const char* domain, bool secure);
/** Clones this cookie (makes new deep copy) */
CHttpCookie* clone() const;
/** Deep-copies all member fields from another cookie */
void copyfrom(const CHttpCookie& cookie);
/** Returns cookie name (always defined) */
const char* name() const { return m_name; }
/** Returns cookie value (empty string if not defined) */
const char* value() const { return m_value; }
/** Returns cookie domain (empty string if not defined) */
const char* domain() const { return m_domain; }
/** Returns cookie path (empty string if not defined */
const char* path() const { return m_path; }
/** Reports whether or not the cookie is "secure" */
bool is_secure() const { return m_secure; }
/** Returns expiration date (date is "empty" date if cookie is not persistent) */
const datetime& expires() const { return m_expires; }
/** Changes the name of the cookie */
void set_name(const char* name) { m_name = name; }
/** Changes the value of the cookie (NULL is treated as empty string) */
void set_value(const char* value) { m_value = value; }
/** Changes cookie domain (NULL ok) */
void set_domain(const char* domain) { m_domain = domain; }
/** Changes cookie path (NULL ok) */
void set_path(const char* path) { m_path = path; }
/**
* Changes expiration date of the cookie. Also changes "expireable" flag
* depending on whether the date is empty/invalid or not.
*/
void set_expiration(const datetime& d)
{
m_expires = d;
m_expireable = d.is_valid();
}
void set_secure(bool secure) { m_secure = secure; }
/**
* Reports whether or not the cookie is "expireable". The cookie is expireable
* if expiration date for it has been explicitly set.
* If this is not the case (no expiration date), cookie is considered to be not persistent.
*/
bool is_expireable() const { return m_expireable; }
/** Parses cookie from external spec */
bool parse(const char* spec);
/** reports whether or not this cookie's domain and path
* matches specified URL */
bool matches(const CURL& url);
/** Reports whether or not the cookie is expired at the current moment */
bool is_expired();
/** Reports whether or not this cookie was deleted (mark_for_deletion() method was called) */
bool is_deleted() { return m_deleted; }
/** Marks cookie as logically "deleted" */
void mark_for_deletion() { m_deleted = true; }
void create_response(string& s, bool omit_header_name = false);
//friend class CHttpUserAgent;
friend class CHttpCookieJar;
//friend class CHttpResponse;
};
/**
* Cookie Jar
*/
class CHttpCookieJar : public array<CHttpCookie>
{
public:
CHttpCookieJar();
CHttpCookie* find(const char* name, const char* domain);
};
/**
* Generic HTTP stream handler interface.
* Depending on the way the program is invoked, different implementations
* will provide different output methods.
*/
class HttpStream
{
public:
// reads from HTTP request (this must yield POSTed data if any)
// returns number of bytes read.
virtual int http_read(void* buffer, int buffer_size) = 0;
// tries to find INBOUND cookie (received in request from client).
// returned cookie object (if any) should be located in internal storage.
// the caller must clone the cookie if it wishes to use it afterwards
virtual const char* http_get_cookie(const char* name) = 0;
// sets http cookie to be sent to the client (outbound cookie)
virtual int http_set_cookie(const CHttpCookie* cookie) = 0;
// adds header to the list of headers
virtual int http_add_header(const char* name, const char* value) = 0;
// reports whether or not the headers have been already sent
virtual bool http_headers_sent() = 0;
// overrides HTTP response code (with optional status line message)
// most servers will allow to change code, but few allow to change message
virtual void http_set_response_code(int code, const char* msg) = 0;
// writes a chunk of data to the HTTP stream
virtual int http_write_chunk(const void* chunk_data, unsigned int chunk_length) = 0;
// flushes any buffered data down the stream and sends implementation-defined
// indication that document output is finished.
// this method must also send headers if they were not sent before
virtual int http_finalize() = 0;
};
/**
* Implementation of standard input/output HTTP stream.
* This implementation is used when the program works in CGI script mode.
*/
class StandardHttpStream : public HttpStream
{
private:
map<string*> m_headers;
// inbound cookies
map<string*> m_in_cookies;
// outbound cookies
CHttpCookieJar m_out_cookies;
bool m_cookies_grabbed;
bool m_headers_sent;
int http_send_headers();
int m_status;
string m_status_msg;
void grab_cookies();
public:
StandardHttpStream();
// tries to find INBOUND cookie (received in request from client).
// returned cookie object (if any) should be located in internal storage.
// the caller must clone the cookie if it wishes to use it afterwards
const char* http_get_cookie(const char* name);
int http_read(void* buffer, int size);
bool http_headers_sent();
int http_add_header(const char* name, const char* value);
int http_write_chunk(const void* chunk_data, unsigned int chunk_length);
int http_finalize();
void http_set_response_code(int code, const char* msg);
// sets http cookie to be sent to the client
int http_set_cookie(const CHttpCookie* cookie);
};
#endif //__chunk_h
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?