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