HTTPStream.cpp revision 878342993276a1a98f35f3ccda24c675ed09b7eb
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 17bd7b43bb02852e51b3000185fa66e10c56b120e0Andreas Huber#include "include/HTTPStream.h" 18bd7b43bb02852e51b3000185fa66e10c56b120e0Andreas Huber 19e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <sys/socket.h> 20e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 21e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <arpa/inet.h> 22e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <ctype.h> 23e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <errno.h> 24e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <netdb.h> 25e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdio.h> 26e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdlib.h> 27e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <string.h> 28e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <unistd.h> 29e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 30b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber#include <media/stagefright/MediaDebug.h> 31e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 32e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android { 33e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 34e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber// static 35e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberconst char *HTTPStream::kStatusKey = ":status:"; 36e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 37e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberHTTPStream::HTTPStream() 38e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber : mState(READY), 39e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSocket(-1) { 40e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 41e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 42e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberHTTPStream::~HTTPStream() { 43e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 44e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 45e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 46e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t HTTPStream::connect(const char *server, int port) { 47edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber Mutex::Autolock autoLock(mLock); 48edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 49e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = OK; 50e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 51e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mState == CONNECTED) { 52e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_ALREADY_CONNECTED; 53e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 55edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber struct hostent *ent = gethostbyname(server); 56edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber if (ent == NULL) { 57edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber return ERROR_UNKNOWN_HOST; 58edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber } 59edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 60b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK_EQ(mSocket, -1); 61e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSocket = socket(AF_INET, SOCK_STREAM, 0); 629763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber 63e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mSocket < 0) { 64e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return UNKNOWN_ERROR; 65e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 66e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 67edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber mState = CONNECTING; 68edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 69edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber int s = mSocket; 70edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 71edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber mLock.unlock(); 72e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 73e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber struct sockaddr_in addr; 74e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber addr.sin_family = AF_INET; 75e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber addr.sin_port = htons(port); 76e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr; 77e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber memset(addr.sin_zero, 0, sizeof(addr.sin_zero)); 78e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 79edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber int res = ::connect(s, (const struct sockaddr *)&addr, sizeof(addr)); 80edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 81edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber mLock.lock(); 82edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 83edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber if (mState != CONNECTING) { 84edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber return UNKNOWN_ERROR; 85e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 86e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 87edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber if (res < 0) { 88edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber close(mSocket); 89edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber mSocket = -1; 90e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 91edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber mState = READY; 92edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber return UNKNOWN_ERROR; 93edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber } 94e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 95edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber mState = CONNECTED; 96e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 97edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber return OK; 98e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 99e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 100e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t HTTPStream::disconnect() { 101edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber Mutex::Autolock autoLock(mLock); 102edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber 103edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber if (mState != CONNECTED && mState != CONNECTING) { 104e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_NOT_CONNECTED; 105e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 106e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 107b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK(mSocket >= 0); 108e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber close(mSocket); 109e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSocket = -1; 110e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 111e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mState = READY; 112e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 113e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 114e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 115e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 116e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t HTTPStream::send(const char *data, size_t size) { 117e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mState != CONNECTED) { 118e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_NOT_CONNECTED; 119e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 120e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 121e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (size > 0) { 122e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ssize_t n = ::send(mSocket, data, size, 0); 123e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 124e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n < 0) { 125e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (errno == EINTR) { 126e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber continue; 127e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 128e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 129e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 130e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 131e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 132e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (n == 0) { 133e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 134e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 135e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_CONNECTION_LOST; 136e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 137e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 138e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size -= (size_t)n; 139e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data += (size_t)n; 140e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 141e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 142e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 143e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 144e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 145e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t HTTPStream::send(const char *data) { 146e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return send(data, strlen(data)); 147e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 148e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1499763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber// A certain application spawns a local webserver that sends invalid responses, 1509763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber// specifically it terminates header line with only a newline instead of the 1519763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber// CRLF (carriage-return followed by newline) required by the HTTP specs. 1529763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber// The workaround accepts both behaviours but could potentially break 1539763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber// legitimate responses that use a single newline to "fold" headers, which is 1549763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber// why it's not yet on by default. 1559763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber#define WORKAROUND_FOR_MISSING_CR 0 1569763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber 157e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t HTTPStream::receive_line(char *line, size_t size) { 158e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mState != CONNECTED) { 159e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_NOT_CONNECTED; 160e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 161e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 162e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool saw_CR = false; 163e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t length = 0; 164e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 165e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (;;) { 166e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char c; 167e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ssize_t n = recv(mSocket, &c, 1, 0); 168e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n < 0) { 169e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (errno == EINTR) { 170e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber continue; 171e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 172e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 173e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 174e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 175e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 176e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (n == 0) { 177e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 178e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 179e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_CONNECTION_LOST; 180e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 181e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1829763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber#if WORKAROUND_FOR_MISSING_CR 1839763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber if (c == '\n') { 1849763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber // We have a complete line. 1859763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber 1869763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber line[saw_CR ? length - 1 : length] = '\0'; 1879763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber return OK; 1889763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber } 1899763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber#else 1909763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber if (saw_CR && c == '\n') { 191e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // We have a complete line. 192e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 193e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber line[length - 1] = '\0'; 194e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 195e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1969763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber#endif 197e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber saw_CR = (c == '\r'); 199e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2009763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber if (length + 1 >= size) { 2019763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber return ERROR_MALFORMED; 2029763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber } 203e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber line[length++] = c; 204e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 205e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 206e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 207e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t HTTPStream::receive_header(int *http_status) { 208e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *http_status = -1; 209e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHeaders.clear(); 210e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2119763f64925cd04a684b014085f0a148bb9cc40feAndreas Huber char line[2048]; 212e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = receive_line(line, sizeof(line)); 213e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 214e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 215e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 216e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 217e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHeaders.add(string(kStatusKey), string(line)); 218e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 219e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char *spacePos = strchr(line, ' '); 220e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (spacePos == NULL) { 221e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Malformed response? 222e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return UNKNOWN_ERROR; 223e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 224e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 225e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char *status_start = spacePos + 1; 226e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char *status_end = status_start; 227e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (isdigit(*status_end)) { 228e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ++status_end; 229e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 230e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 231e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (status_end == status_start) { 232e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Malformed response, status missing? 233e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return UNKNOWN_ERROR; 234e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 235e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 236e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber memmove(line, status_start, status_end - status_start); 237e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber line[status_end - status_start] = '\0'; 238e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 239e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber long tmp = strtol(line, NULL, 10); 240e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (tmp < 0 || tmp > 999) { 241e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return UNKNOWN_ERROR; 242e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 243e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 244e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *http_status = (int)tmp; 245e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 246e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (;;) { 247e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber err = receive_line(line, sizeof(line)); 248e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 249e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 250e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 251e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 252e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (*line == '\0') { 253e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Empty line signals the end of the header. 254e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 255e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 256e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 257e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // puts(line); 258e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 259e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char *colonPos = strchr(line, ':'); 260e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (colonPos == NULL) { 261e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHeaders.add(string(line), string()); 262e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 263e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char *end_of_key = colonPos; 264e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (end_of_key > line && isspace(end_of_key[-1])) { 265e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber --end_of_key; 266e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 267e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 268e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char *start_of_value = colonPos + 1; 269e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (isspace(*start_of_value)) { 270e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ++start_of_value; 271e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 272e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 273e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *end_of_key = '\0'; 274e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 275e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHeaders.add(string(line), string(start_of_value)); 276e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 277e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 278e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 279e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 280e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 281e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 282e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberssize_t HTTPStream::receive(void *data, size_t size) { 283e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t total = 0; 284e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (total < size) { 285e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ssize_t n = recv(mSocket, (char *)data + total, size - total, 0); 286e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 287e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n < 0) { 288e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (errno == EINTR) { 289e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber continue; 290e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 291e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 292878342993276a1a98f35f3ccda24c675ed09b7ebAndreas Huber LOGE("recv failed, errno = %d (%s)", errno, strerror(errno)); 293878342993276a1a98f35f3ccda24c675ed09b7ebAndreas Huber 294e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 295878342993276a1a98f35f3ccda24c675ed09b7ebAndreas Huber return (ssize_t)ERROR_IO; 296e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (n == 0) { 297e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber disconnect(); 298e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 299878342993276a1a98f35f3ccda24c675ed09b7ebAndreas Huber LOGE("recv failed, server is gone"); 300878342993276a1a98f35f3ccda24c675ed09b7ebAndreas Huber 30157f790f96d5ed1f1dad8179a110143e9d3df808bAndreas Huber return total == 0 ? (ssize_t)ERROR_CONNECTION_LOST : total; 302e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 303e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 304e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber total += (size_t)n; 305e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 306e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 307e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return (ssize_t)total; 308e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 309e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 310e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberbool HTTPStream::find_header_value(const string &key, string *value) const { 311e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ssize_t index = mHeaders.indexOfKey(key); 312e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (index < 0) { 313e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber value->clear(); 314e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return false; 315e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 316e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 317e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *value = mHeaders.valueAt(index); 318e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 319e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return true; 320e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 321e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 322e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} // namespace android 323e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 324