File: BeaconLoader.cpp

package info (click to toggle)
chromium-browser 37.0.2062.120-1~deb7u1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,707,260 kB
  • sloc: cpp: 8,976,677; ansic: 3,473,199; python: 586,578; asm: 449,013; xml: 184,195; java: 142,924; sh: 118,496; perl: 81,467; makefile: 27,557; yacc: 10,506; objc: 8,886; tcl: 3,186; cs: 2,252; lex: 2,213; sql: 1,198; pascal: 1,170; lisp: 790; awk: 407; ruby: 155; php: 83; sed: 52; exp: 11
file content (130 lines) | stat: -rw-r--r-- 4,650 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"
#include "core/loader/BeaconLoader.h"

#include "core/FetchInitiatorTypeNames.h"
#include "core/dom/Document.h"
#include "core/fetch/CrossOriginAccessControl.h"
#include "core/fetch/FetchContext.h"
#include "core/fileapi/File.h"
#include "core/frame/LocalFrame.h"
#include "core/html/DOMFormData.h"
#include "platform/network/FormData.h"
#include "platform/network/ParsedContentType.h"
#include "platform/network/ResourceRequest.h"
#include "wtf/ArrayBufferView.h"

namespace WebCore {

void BeaconLoader::prepareRequest(LocalFrame* frame, ResourceRequest& request)
{
    // NOTE: do not distinguish Beacon by target type.
    request.setTargetType(ResourceRequest::TargetIsPing);
    request.setHTTPMethod("POST");
    request.setHTTPHeaderField("Cache-Control", "max-age=0");
    request.setAllowStoredCredentials(true);
    frame->loader().fetchContext().addAdditionalRequestHeaders(frame->document(), request, FetchSubresource);
    frame->loader().fetchContext().setFirstPartyForCookies(request);
}

void BeaconLoader::issueRequest(LocalFrame* frame, ResourceRequest& request)
{
    FetchInitiatorInfo initiatorInfo;
    initiatorInfo.name = FetchInitiatorTypeNames::beacon;

    PingLoader::start(frame, request, initiatorInfo);
}

bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, const String& data, int& payloadLength)
{
    ResourceRequest request(beaconURL);
    prepareRequest(frame, request);

    RefPtr<FormData> entityBody = FormData::create(data.utf8());
    unsigned long long entitySize = entityBody->sizeInBytes();
    if (allowance > 0 && static_cast<unsigned>(allowance) < entitySize)
        return false;

    request.setHTTPBody(entityBody);
    request.setHTTPContentType("text/plain;charset=UTF-8");

    issueRequest(frame, request);
    payloadLength = entitySize;
    return true;
}

bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, PassRefPtr<ArrayBufferView>& data, int& payloadLength)
{
    ASSERT(data);
    unsigned long long entitySize = data->byteLength();
    if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize)
        return false;

    ResourceRequest request(beaconURL);
    prepareRequest(frame, request);

    RefPtr<FormData> entityBody = FormData::create(data->baseAddress(), data->byteLength());
    request.setHTTPBody(entityBody.release());

    // FIXME: a reasonable choice, but not in the spec; should it give a default?
    AtomicString contentType = AtomicString("application/octet-stream");
    request.setHTTPContentType(contentType);

    issueRequest(frame, request);
    payloadLength = entitySize;
    return true;
}

bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, PassRefPtrWillBeRawPtr<Blob>& data, int& payloadLength)
{
    ASSERT(data);
    unsigned long long entitySize = data->size();
    if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize)
        return false;

    ResourceRequest request(beaconURL);
    prepareRequest(frame, request);

    RefPtr<FormData> entityBody = FormData::create();
    if (data->hasBackingFile())
        entityBody->appendFile(toFile(data.get())->path());
    else
        entityBody->appendBlob(data->uuid(), data->blobDataHandle());

    request.setHTTPBody(entityBody.release());

    AtomicString contentType;
    const String& blobType = data->type();
    if (!blobType.isEmpty() && isValidContentType(blobType))
        request.setHTTPContentType(AtomicString(contentType));

    issueRequest(frame, request);
    payloadLength = entitySize;
    return true;
}

bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, PassRefPtrWillBeRawPtr<DOMFormData>& data, int& payloadLength)
{
    ASSERT(data);
    ResourceRequest request(beaconURL);
    prepareRequest(frame, request);

    RefPtr<FormData> entityBody = data->createMultiPartFormData();

    unsigned long long entitySize = entityBody->sizeInBytes();
    if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize)
        return false;

    AtomicString contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + entityBody->boundary().data();
    request.setHTTPBody(entityBody.release());
    request.setHTTPContentType(contentType);

    issueRequest(frame, request);
    payloadLength = entitySize;
    return true;
}

} // namespace WebCore