1e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber/* 2e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Copyright (C) 2009 The Android Open Source Project 3e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * 4e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * you may not use this file except in compliance with the License. 6e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * You may obtain a copy of the License at 7e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * 8e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * 10e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Unless required by applicable law or agreed to in writing, software 11e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * See the License for the specific language governing permissions and 14e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * limitations under the License. 15e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber */ 16e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 17b75d137faf2e719b389edd5c1d64ab31cc34fb32Andreas Huber//#define LOG_NDEBUG 0 18b75d137faf2e719b389edd5c1d64ab31cc34fb32Andreas Huber#define LOG_TAG "HTTPStream" 19b75d137faf2e719b389edd5c1d64ab31cc34fb32Andreas Huber#include <utils/Log.h> 20b75d137faf2e719b389edd5c1d64ab31cc34fb32Andreas Huber 21bd7b43bb02852e51b3000185fa66e10c56b120e0Andreas Huber#include "include/HTTPStream.h" 22bd7b43bb02852e51b3000185fa66e10c56b120e0Andreas Huber 23e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <sys/socket.h> 24e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 25e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <arpa/inet.h> 26e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <ctype.h> 27e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <errno.h> 28e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <netdb.h> 29e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdio.h> 30e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdlib.h> 31e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <string.h> 32e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <unistd.h> 33e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 34b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber#include <media/stagefright/MediaDebug.h> 35e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 36e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android { 37e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 38e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber// static 39e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberconst char *HTTPStream::kStatusKey = ":status:"; 40e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 41e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberHTTPStream::HTTPStream() 42e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber : mState(READY), 43e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSocket(-1) { 44e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 45e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 46e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberHTTPStream::~HTTPStream() { 47e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 48e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 49e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 50e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t HTTPStream::connect(const char *server, int port) { 51edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber Mutex::Autolock autoLock(mLock); 52edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 53e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = OK; 54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 55e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mState == CONNECTED) { 56e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_ALREADY_CONNECTED; 57e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 58e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 59edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber struct hostent *ent = gethostbyname(server); 60edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber if (ent == NULL) { 61edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber return ERROR_UNKNOWN_HOST; 62edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber } 63edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 64b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK_EQ(mSocket, -1); 65e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSocket = socket(AF_INET, SOCK_STREAM, 0); 669763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber 67e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mSocket < 0) { 68e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return UNKNOWN_ERROR; 69e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 70e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 71e67c1607ccab2702ea745f962b5354be8f45c733Andreas Huber setReceiveTimeout(5); // Time out reads after 5 secs by default 7263fbd5ab8fee9db73077d10c9b5ac61625588624Andreas Huber 73edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber mState = CONNECTING; 74edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 75edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber int s = mSocket; 76edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 77edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber mLock.unlock(); 78e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 79e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber struct sockaddr_in addr; 80e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber addr.sin_family = AF_INET; 81e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber addr.sin_port = htons(port); 82e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr; 83e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber memset(addr.sin_zero, 0, sizeof(addr.sin_zero)); 84e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 85edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber int res = ::connect(s, (const struct sockaddr *)&addr, sizeof(addr)); 86edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 87edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber mLock.lock(); 88edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 89edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber if (mState != CONNECTING) { 90edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber return UNKNOWN_ERROR; 91e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 92e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 93edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber if (res < 0) { 94edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber close(mSocket); 95edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber mSocket = -1; 96e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 97edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber mState = READY; 98edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber return UNKNOWN_ERROR; 99edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber } 100e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 101edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber mState = CONNECTED; 102e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 103edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber return OK; 104e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 105e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 106e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t HTTPStream::disconnect() { 107edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber Mutex::Autolock autoLock(mLock); 108edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 109edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber if (mState != CONNECTED && mState != CONNECTING) { 110e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_NOT_CONNECTED; 111e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 112e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 113b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK(mSocket >= 0); 114e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber close(mSocket); 115e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSocket = -1; 116e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 117e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mState = READY; 118e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 119e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 120e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 121e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 122e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t HTTPStream::send(const char *data, size_t size) { 123e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mState != CONNECTED) { 124e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_NOT_CONNECTED; 125e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 126e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 127e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (size > 0) { 128e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ssize_t n = ::send(mSocket, data, size, 0); 129e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 130e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n < 0) { 131e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (errno == EINTR) { 132e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber continue; 133e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 134e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 135e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 136e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 137e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 138e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (n == 0) { 139e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 140e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 141e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_CONNECTION_LOST; 142e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 143e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 144e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size -= (size_t)n; 145e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data += (size_t)n; 146e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 147e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 148e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 149e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 150e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 151e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t HTTPStream::send(const char *data) { 152e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return send(data, strlen(data)); 153e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 154e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1559763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber// A certain application spawns a local webserver that sends invalid responses, 1569763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber// specifically it terminates header line with only a newline instead of the 1579763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber// CRLF (carriage-return followed by newline) required by the HTTP specs. 1589763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber// The workaround accepts both behaviours but could potentially break 1599763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber// legitimate responses that use a single newline to "fold" headers, which is 1609763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber// why it's not yet on by default. 1619763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber#define WORKAROUND_FOR_MISSING_CR 0 1629763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber 163e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t HTTPStream::receive_line(char *line, size_t size) { 164e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mState != CONNECTED) { 165e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_NOT_CONNECTED; 166e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 167e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 168e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool saw_CR = false; 169e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t length = 0; 170e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 171e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (;;) { 172e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char c; 17363fbd5ab8fee9db73077d10c9b5ac61625588624Andreas Huber ssize_t n = recv(mSocket, &c, 1, 0); 174e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n < 0) { 175e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (errno == EINTR) { 176e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber continue; 177e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 178e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 179e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 180e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 181e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 182e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (n == 0) { 183e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 184e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 185e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_CONNECTION_LOST; 186e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 187e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1889763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber#if WORKAROUND_FOR_MISSING_CR 1899763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber if (c == '\n') { 1909763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber // We have a complete line. 1919763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber 1929763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber line[saw_CR ? length - 1 : length] = '\0'; 1939763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber return OK; 1949763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber } 1959763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber#else 1969763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber if (saw_CR && c == '\n') { 197e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // We have a complete line. 198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 199e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber line[length - 1] = '\0'; 200e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 201e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 2029763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber#endif 203e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 204e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber saw_CR = (c == '\r'); 205e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2069763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber if (length + 1 >= size) { 2079763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber return ERROR_MALFORMED; 2089763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber } 209e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber line[length++] = c; 210e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 211e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 212e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 213e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t HTTPStream::receive_header(int *http_status) { 214e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *http_status = -1; 215e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHeaders.clear(); 216e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2179763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber char line[2048]; 218e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = receive_line(line, sizeof(line)); 219e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 220e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 221e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 222e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 223e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHeaders.add(string(kStatusKey), string(line)); 224e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 225e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char *spacePos = strchr(line, ' '); 226e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (spacePos == NULL) { 227e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Malformed response? 228e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return UNKNOWN_ERROR; 229e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 230e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 231e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char *status_start = spacePos + 1; 232e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char *status_end = status_start; 233e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (isdigit(*status_end)) { 234e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ++status_end; 235e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 236e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 237e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (status_end == status_start) { 238e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Malformed response, status missing? 239e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return UNKNOWN_ERROR; 240e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 241e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 242e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber memmove(line, status_start, status_end - status_start); 243e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber line[status_end - status_start] = '\0'; 244e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 245e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber long tmp = strtol(line, NULL, 10); 246e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (tmp < 0 || tmp > 999) { 247e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return UNKNOWN_ERROR; 248e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 249e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 250e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *http_status = (int)tmp; 251e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 252e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (;;) { 253e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber err = receive_line(line, sizeof(line)); 254e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 255e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 256e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 257e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 258e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (*line == '\0') { 259e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Empty line signals the end of the header. 260e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 261e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 262e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 263e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // puts(line); 264e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 265e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char *colonPos = strchr(line, ':'); 266e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (colonPos == NULL) { 267e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHeaders.add(string(line), string()); 268e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 269e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char *end_of_key = colonPos; 270e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (end_of_key > line && isspace(end_of_key[-1])) { 271e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber --end_of_key; 272e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 273e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 274e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char *start_of_value = colonPos + 1; 275e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (isspace(*start_of_value)) { 276e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ++start_of_value; 277e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 278e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 279e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *end_of_key = '\0'; 280e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 281e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHeaders.add(string(line), string(start_of_value)); 282e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 283e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 284e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 285e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 286e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 287e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 288e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberssize_t HTTPStream::receive(void *data, size_t size) { 289e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t total = 0; 290e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (total < size) { 29163fbd5ab8fee9db73077d10c9b5ac61625588624Andreas Huber ssize_t n = recv(mSocket, (char *)data + total, size - total, 0); 292e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 293e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n < 0) { 294e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (errno == EINTR) { 295e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber continue; 296e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 297e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 298878342993276a1a98f35f3ccda24c675ed09b7ebAndreas Huber LOGE("recv failed, errno = %d (%s)", errno, strerror(errno)); 299878342993276a1a98f35f3ccda24c675ed09b7ebAndreas Huber 300e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 301878342993276a1a98f35f3ccda24c675ed09b7ebAndreas Huber return (ssize_t)ERROR_IO; 302e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (n == 0) { 303e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 304e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 305b75d137faf2e719b389edd5c1d64ab31cc34fb32Andreas Huber LOGE("recv failed, server is gone, total received: %d bytes", 306b75d137faf2e719b389edd5c1d64ab31cc34fb32Andreas Huber total); 307878342993276a1a98f35f3ccda24c675ed09b7ebAndreas Huber 30857f790f96d5ed1f1dad8179a110143e9d3df808bAndreas Huber return total == 0 ? (ssize_t)ERROR_CONNECTION_LOST : total; 309e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 310e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 311e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber total += (size_t)n; 312e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 313e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 314e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return (ssize_t)total; 315e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 316e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 317e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberbool HTTPStream::find_header_value(const string &key, string *value) const { 318e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ssize_t index = mHeaders.indexOfKey(key); 319e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (index < 0) { 320e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber value->clear(); 321e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return false; 322e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 323e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 324e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *value = mHeaders.valueAt(index); 325e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 326e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return true; 327e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 328e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 329e67c1607ccab2702ea745f962b5354be8f45c733Andreas Hubervoid HTTPStream::setReceiveTimeout(int seconds) { 330e67c1607ccab2702ea745f962b5354be8f45c733Andreas Huber if (seconds < 0) { 331e67c1607ccab2702ea745f962b5354be8f45c733Andreas Huber // Disable the timeout. 332e67c1607ccab2702ea745f962b5354be8f45c733Andreas Huber seconds = 0; 333e67c1607ccab2702ea745f962b5354be8f45c733Andreas Huber } 334e67c1607ccab2702ea745f962b5354be8f45c733Andreas Huber 335e67c1607ccab2702ea745f962b5354be8f45c733Andreas Huber struct timeval tv; 336e67c1607ccab2702ea745f962b5354be8f45c733Andreas Huber tv.tv_usec = 0; 337e67c1607ccab2702ea745f962b5354be8f45c733Andreas Huber tv.tv_sec = seconds; 338e67c1607ccab2702ea745f962b5354be8f45c733Andreas Huber CHECK_EQ(0, setsockopt(mSocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))); 339e67c1607ccab2702ea745f962b5354be8f45c733Andreas Huber} 340e67c1607ccab2702ea745f962b5354be8f45c733Andreas Huber 341e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} // namespace android 342e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 343