int main(int argc, char *argv[]) { bool do_ssl = false; const char *url = argv[1]; const char *domain = argv[1]; const char *port = argv[2]; const char *uri = argv[3]; if (argc < 4) { printf("ERROR: Need url, port and uri\n"); return 1; } SSL_load_error_strings(); ERR_load_BIO_strings(); OpenSSL_add_all_algorithms(); event_init(); struct http_client *client = http_client_new(domain, port, NULL); struct http_request *req = http_client_request(client, HTTP_METHOD_GET, strlen(uri), uri); http_client_request_dispatch(req, callback, NULL); event_loop(0); return 1; }
static struct fts_parser * fts_parser_tika_try_init(struct mail_user *user, const char *content_type, const char *content_disposition) { struct tika_fts_parser *parser; struct http_url *http_url; struct http_client_request *http_req; if (tika_get_http_client_url(user, &http_url) < 0) return NULL; parser = i_new(struct tika_fts_parser, 1); parser->parser.v = fts_parser_tika; parser->user = user; http_req = http_client_request(tika_http_client, "PUT", http_url->host_name, t_strconcat(http_url->path, http_url->enc_query, NULL), fts_tika_parser_response, parser); http_client_request_set_port(http_req, http_url->port); http_client_request_set_ssl(http_req, http_url->have_ssl); http_client_request_add_header(http_req, "Content-Type", content_type); http_client_request_add_header(http_req, "Content-Disposition", content_disposition); http_client_request_add_header(http_req, "Accept", "text/plain"); parser->http_req = http_req; return &parser->parser; }
/* Earlier versions of ffmpeg/libav do not seem to allow access to the http * headers, so we must instead open the stream ourselves to get the metadata. * Sorry about the extra connections, you radio streaming people! * * It is not possible to get the packet metadata with these versions of ffmpeg */ struct http_icy_metadata * http_icy_metadata_get(AVFormatContext *fmtctx, int packet_only) { struct http_icy_metadata *metadata; struct http_client_ctx ctx; struct keyval *kv; const char *value; int got_header; int ret; /* Can only get header metadata */ if (packet_only) return NULL; kv = keyval_alloc(); if (!kv) return NULL; memset(&ctx, 0, sizeof(struct http_client_ctx)); ctx.url = fmtctx->filename; ctx.headers = kv; ctx.headers_only = 1; ctx.body = NULL; ret = http_client_request(&ctx); if (ret < 0) { DPRINTF(E_LOG, L_HTTP, "Error fetching %s\n", fmtctx->filename); free(kv); return NULL; } metadata = malloc(sizeof(struct http_icy_metadata)); if (!metadata) return NULL; memset(metadata, 0, sizeof(struct http_icy_metadata)); got_header = 0; if ( (value = keyval_get(ctx.headers, "icy-name")) ) { metadata->name = strdup(value); got_header = 1; } if ( (value = keyval_get(ctx.headers, "icy-description")) ) { metadata->description = strdup(value); got_header = 1; } if ( (value = keyval_get(ctx.headers, "icy-genre")) ) { metadata->genre = strdup(value); got_header = 1; } keyval_clear(kv); free(kv); if (!got_header) { free(metadata); return NULL; } /* DPRINTF(E_DBG, L_HTTP, "Found ICY: N %s, D %s, G %s, T %s, A %s, U %s, I %" PRIu32 "\n", metadata->name, metadata->description, metadata->genre, metadata->title, metadata->artist, metadata->artwork_url, metadata->hash );*/ return metadata; }
/* * request_read: 处理http连接请求。 * 参数: * client: client实例的指针, * sockfd: socket 文件描述符。 * 返回: * -1: 表示出错, * 1(HTTP_SOCKFD_IN): 表示I/O层监听sockfd读事件。 * 2(HTTP_SOCKFD_OUT): 表示I/O层监听sockfd写事件。 * 4(HTTP_SOCKFD_DEL): 表示I/O层删除sockfd事件监听。 */ int request_read(struct http_client *client, int sockfd) { struct pool_entry *mem; int total_read = 0, ret = -1; int mem_inuse = 0; unsigned int epflag = 0; if ( NULL == client || sockfd < -1 ) return ret; mem = client->inbuff; if ( !client->inprocess ) { /* 新请求 */ client->inprocess = 1; } else { if ( mem->inuse_size ) { mem_inuse = mem->inuse_size; ret = http_client_head_valid(client); if ( ret == 1 ) { /* 判断有没有读取到请求完整的content */ ret = http_client_req_entire(client); if ( !ret ) { total_read = http_client_current_buff(client, mem); } } else if ( ret == 0) /* 还没有读取到完整的头域 */ total_read += mem_inuse; else return ret; } else { return ret; } } while ( 1 ) { ret = read(sockfd, mem->buff + total_read, HTTP_MAX_HEAD_LEN - total_read); if ( -1 == ret && errno == EINTR ) continue; else if ( -1 == ret && (errno == EAGAIN || errno == EWOULDBLOCK)) { /* 目前读不到数据了 */ break; } else if ( -1 == ret ) { perror("read error: "); return ret; } else if ( 0 == ret ) { fprintf(stderr, "remote closed socket\n"); return ret; } total_read += ret; } mem->inuse_size = total_read; *((char *)mem->buff + total_read) = '\0'; /* 判断是否读取到整个HTTP 头域 */ ret = http_client_head_valid(client); if ( ret < 0 ) return ret; else if ( ret == 0 ) { /* 没有读取到完整的头域,等待下一步处理 */ return HTTP_SOCKFD_IN; } else { /* 已经读取到完整的头部 */ if ( (ret = http_client_parse(client)) < 0 ) return ret; /* 处理请求 */ ret = http_client_request(client, &epflag); if ( ret == -1 ) return ret; if ( HTTP_SOCKFD_OUT == epflag ) { return HTTP_SOCKFD_OUT; } else if ( HTTP_SOCKFD_IN == epflag ) { return HTTP_SOCKFD_IN; } else if ( HTTP_SOCKFD_DEL == epflag ) { return HTTP_SOCKFD_DEL; } else { /* 出错了 */ return -1; } } }
int http_stream_setup(char **stream, const char *url) { struct http_client_ctx ctx; struct evbuffer *evbuf; const char *ext; char *line; int ret; int n; *stream = NULL; ext = strrchr(url, '.'); if (strcasecmp(ext, ".m3u") != 0) { *stream = strdup(url); return 0; } // It was a m3u playlist, so now retrieve it memset(&ctx, 0, sizeof(struct http_client_ctx)); evbuf = evbuffer_new(); if (!evbuf) return -1; ctx.url = url; ctx.body = evbuf; ret = http_client_request(&ctx); if (ret < 0) { DPRINTF(E_LOG, L_HTTP, "Couldn't fetch internet playlist: %s\n", url); evbuffer_free(evbuf); return -1; } /* Read the playlist until the first stream link is found, but give up if * nothing is found in the first 10 lines */ n = 0; while ((line = evbuffer_readln(ctx.body, NULL, EVBUFFER_EOL_ANY)) && (n < 10)) { n++; if (strncasecmp(line, "http://", strlen("http://")) == 0) { DPRINTF(E_DBG, L_HTTP, "Found internet playlist stream (line %d): %s\n", n, line); n = -1; break; } free(line); } evbuffer_free(ctx.body); if (n != -1) { DPRINTF(E_LOG, L_HTTP, "Couldn't find stream in internet playlist: %s\n", url); return -1; } *stream = line; return 0; }