📄 http_basic.c
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@CFILE http_basic.c * @brief HTTP basic header * * The file @b http_basic.c contains implementation of header classes for * basic HTTP headers, like request and status lines, payload, @b Call-ID, @b * CSeq, @b Contact, @b Content-Length, @b Date, @b Expires, @b From, @b * Route, @b Record-Route, @b To, and @b Via. * * @author Pekka Pessi <Pekka.Pessi@nokia.com> * * @date Created: Tue Jun 13 02:57:51 2000 ppessi */#include "config.h"#include <stddef.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <stdio.h>#include <sofia-sip/su_alloc.h>#include <sofia-sip/http_parser.h>#include <sofia-sip/http_header.h>#include <sofia-sip/http_status.h>#include <sofia-sip/msg_mime_protos.h>#include <sofia-sip/msg_date.h>/* ====================================================================== *//**@HTTP_HEADER http_request HTTP request line. * * The HTTP request line contains the method, URL, and an optional HTTP * protocol version. The missing version indicates version 0.9 without any * request headers. *//** * Parse request line of a HTTP message. * * The function @c http_request_d() parses the request line from a a HTTP * message. */int http_request_d(su_home_t *home, http_header_t *h, char *s, int slen){ http_request_t *rq = h->sh_request; char *uri, *version; if (msg_firstline_d(s, &uri, &version) < 0 || (rq->rq_method = http_method_d(&s, &rq->rq_method_name)) < 0 || *s || url_d(rq->rq_url, uri) < 0 || (http_version_d(&version, &rq->rq_version) < 0 || version[0])) return -1; return 0;}/** * Encode a HTTP request line. * * The function @c http_request_e() prints a HTTP request line. */int http_request_e(char b[], int bsiz, http_header_t const *h, int flags){ http_request_t const *rq = h->sh_request; return snprintf(b, bsiz, "%s " URL_FORMAT_STRING "%s%s" CRLF, rq->rq_method_name, URL_PRINT_ARGS(rq->rq_url), rq->rq_version ? " " : "", rq->rq_version ? rq->rq_version : "");}int http_request_dup_xtra(http_header_t const *h, int offset){ int rv = offset; http_request_t const *rq = h->sh_request; rv += url_xtra(rq->rq_url); if (!rq->rq_method) rv += MSG_STRING_SIZE(rq->rq_method_name); if (rq->rq_version) rv += http_version_xtra(rq->rq_version); return rv;}/** Duplicate one request header. */char *http_request_dup_one(http_header_t *dst, http_header_t const *src, char *b, int xtra){ http_request_t *rq = dst->sh_request; http_request_t const *o = src->sh_request; char *end = b + xtra; URL_DUP(b, end, rq->rq_url, o->rq_url); if (!(rq->rq_method = o->rq_method)) MSG_STRING_DUP(b, rq->rq_method_name, o->rq_method_name); else rq->rq_method_name = o->rq_method_name; http_version_dup(&b, &rq->rq_version, o->rq_version); assert(b <= end); return b;}/** Create a request line object. * * Note that version string is not copied; it @b MUST remain constant during * lifetime of the @c http_request_t object. You can use constants * http_version_1_1 or http_version_1_0 declared in <http_header.h>. */http_request_t *http_request_create(su_home_t *home, http_method_t method, char const *name, url_string_t const *url, char const *version){ int xtra; http_request_t *rq; if (method) name = http_method_name(method, name); if (!name) return NULL; xtra = url_xtra(url->us_url) + (method ? 0 : strlen(name) + 1); rq = msg_header_alloc(home, http_request_class, xtra)->sh_request; if (rq) { char *b = (char *)(rq + 1), *end = b + xtra; rq->rq_method = method; rq->rq_method_name = name; if (!method) MSG_STRING_DUP(b, rq->rq_method_name, name); URL_DUP(b, end, rq->rq_url, url->us_url); rq->rq_version = version ? version : HTTP_VERSION_CURRENT; assert(b == end); } return rq;}msg_hclass_t http_request_class[] =HTTP_HEADER_CLASS(request, NULL, rq_common, single_critical, request);/* ====================================================================== *//**@HTTP_HEADER http_status HTTP status line. * * The HTTP status line contains the HTTP protocol version, a reason code * (100..599) and reason phrase. *//** Parse status line */int http_status_d(su_home_t *home, http_header_t *h, char *s, int slen){ http_status_t *st = h->sh_status; char *status, *phrase; uint32_t code; if (msg_firstline_d(s, &status, &phrase) < 0 || http_version_d(&s, &st->st_version) < 0 || *s || msg_uint32_d(&status, &code) == -1 || status[0]) return -1; st->st_status = code; st->st_phrase = phrase; return 0;}int http_status_e(char b[], int bsiz, http_header_t const *h, int flags){ http_status_t const *st = h->sh_status; char const *phrase = st->st_phrase; if (phrase == NULL) phrase = ""; if (st->st_version) return snprintf(b, bsiz, "%s %03u %s" CRLF, st->st_version, st->st_status, phrase); else return snprintf(b, bsiz, "%03u %s" CRLF, st->st_status, phrase);}/** Extra size of a http_status_t object. */int http_status_dup_xtra(http_header_t const *h, int offset){ if (h->sh_status->st_version) offset += http_version_xtra(h->sh_status->st_version); offset += MSG_STRING_SIZE(h->sh_status->st_phrase); return offset;}/** Duplicate one status header. */char *http_status_dup_one(http_header_t *dst, http_header_t const *src, char *b, int xtra){ http_status_t *st = dst->sh_status; http_status_t const *o = src->sh_status; char *end = b + xtra; if (o->st_version) http_version_dup(&b, &st->st_version, o->st_version); st->st_status = o->st_status; MSG_STRING_DUP(b, st->st_phrase, o->st_phrase); assert(b <= end); return b;}/** Create a status line object. * * Note that version is not copied; it @b MUST remain constant during * lifetime of the @c http_status_t object. */http_status_t *http_status_create(su_home_t *home, unsigned status, char const *phrase, char const *version){ http_status_t *st; if (phrase == NULL && (phrase = http_status_phrase(status)) == NULL) return NULL; if ((st = msg_header_alloc(home, http_status_class, 0)->sh_status)) { st->st_status = status; st->st_phrase = phrase; st->st_version = version ? version : HTTP_VERSION_CURRENT; } return st;}msg_hclass_t http_status_class[] =HTTP_HEADER_CLASS(status, NULL, st_common, single_critical, status);/* ====================================================================== *//**@HTTP_HEADER http_accept Accept header. * * We use MIME Accept header. *//* ====================================================================== *//**@HTTP_HEADER http_accept_charset Accept-Charset header. * * We use MIME Accept-Charset header. *//* ====================================================================== *//**@HTTP_HEADER http_accept_encoding Accept-Encoding header. * * We use MIME Accept-Encoding header. *//* ====================================================================== *//**@HTTP_HEADER http_accept_language Accept-Language header. * * We use MIME Accept-Language header. *//* ====================================================================== *//**@HTTP_HEADER http_accept_ranges Accept-Ranges header. */#define http_accept_ranges_d msg_list_d#define http_accept_ranges_e msg_list_emsg_hclass_t http_accept_ranges_class[] =HTTP_HEADER_CLASS_LIST(accept_ranges, "Accept-Ranges", list);/* ====================================================================== *//**@HTTP_HEADER http_age Age header. */#define http_age_d msg_numeric_d#define http_age_e msg_numeric_e#define http_age_dup_xtra msg_default_dup_xtra#define http_age_dup_one msg_default_dup_onemsg_hclass_t http_age_class[] =HTTP_HEADER_CLASS(age, "Age", x_common, single, age);/* ====================================================================== *//**@HTTP_HEADER http_allow Allow header. */#define http_allow_d msg_list_d#define http_allow_e msg_list_emsg_hclass_t http_allow_class[] =HTTP_HEADER_CLASS_LIST(allow, "Allow", list);/* ====================================================================== *//**@HTTP_HEADER http_authentication_info Authentication-Info header. * @sa RFC 2617 */#define http_authentication_info_d msg_list_d#define http_authentication_info_e msg_list_e#define http_authentication_info_dup_xtra msg_list_dup_xtra#define http_authentication_info_dup_one msg_list_dup_onemsg_hclass_t http_authentication_info_class[] =HTTP_HEADER_CLASS(authentication_info, "Authentication-Info", ai_params, list, authentication_info);/* ====================================================================== *//**@HTTP_HEADER http_authorization Authorization header. * * We use MIME Authorization header. */#define http_authorization_d msg_auth_d#define http_authorization_e msg_auth_emsg_hclass_t http_authorization_class[] =HTTP_HEADER_CLASS_AUTH(authorization, "Authorization", single);/* ====================================================================== *//**@HTTP_HEADER http_cache_control Cache-Control header. */#define http_cache_control_d msg_list_d#define http_cache_control_e msg_list_emsg_hclass_t http_cache_control_class[] = HTTP_HEADER_CLASS_LIST(cache_control, "Cache-Control", list);/* ====================================================================== *//**@HTTP_HEADER http_connection Connection header. */#define http_connection_d msg_list_d#define http_connection_e msg_list_emsg_hclass_t http_connection_class[] =HTTP_HEADER_CLASS_LIST(connection, "Connection", list_critical);/* ====================================================================== *//**@HTTP_HEADER http_content_encoding Content-Encoding header. * * We use MIME Content-Encoding header. *//* ====================================================================== *//**@HTTP_HEADER http_content_language Content-Language header. * * We use MIME Content-Language header. *//* ====================================================================== *//**@HTTP_HEADER http_content_length Content-Length header. * * We use MIME Content-Length header. *//* ====================================================================== *//**@HTTP_HEADER http_content_location Content-Location header. * * We use MIME Content-Location header. *//* ====================================================================== *//**@HTTP_HEADER http_content_md5 Content-MD5 header. * * We use MIME Content-MD5 header. *//* ====================================================================== *//**@HTTP_HEADER http_content_range Content-Range header. * * The Content-Range entity-header is sent with a partial entity-body to * specify where in the full entity-body the partial body should be * applied. Its syntax is defined in [H14.16] as follows: * * @code * Content-Range = "Content-Range" ":" content-range-spec
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -