Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / loader / BeaconLoader.cpp
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/loader/BeaconLoader.h"
7
8 #include "core/FetchInitiatorTypeNames.h"
9 #include "core/fetch/CrossOriginAccessControl.h"
10 #include "core/fetch/FetchContext.h"
11 #include "core/fileapi/File.h"
12 #include "core/frame/LocalFrame.h"
13 #include "core/html/DOMFormData.h"
14 #include "platform/network/FormData.h"
15 #include "platform/network/ParsedContentType.h"
16 #include "platform/network/ResourceRequest.h"
17 #include "public/platform/WebURLRequest.h"
18 #include "wtf/ArrayBufferView.h"
19
20 namespace blink {
21
22 void BeaconLoader::prepareRequest(LocalFrame* frame, ResourceRequest& request)
23 {
24     request.setRequestContext(WebURLRequest::RequestContextBeacon);
25     request.setHTTPMethod("POST");
26     request.setHTTPHeaderField("Cache-Control", "max-age=0");
27     request.setAllowStoredCredentials(true);
28     frame->loader().fetchContext().addAdditionalRequestHeaders(frame->document(), request, FetchSubresource);
29     frame->loader().fetchContext().setFirstPartyForCookies(request);
30 }
31
32 void BeaconLoader::issueRequest(LocalFrame* frame, ResourceRequest& request)
33 {
34     FetchInitiatorInfo initiatorInfo;
35     initiatorInfo.name = FetchInitiatorTypeNames::beacon;
36
37     PingLoader::start(frame, request, initiatorInfo);
38 }
39
40 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, const String& data, int& payloadLength)
41 {
42     ResourceRequest request(beaconURL);
43     prepareRequest(frame, request);
44
45     RefPtr<FormData> entityBody = FormData::create(data.utf8());
46     unsigned long long entitySize = entityBody->sizeInBytes();
47     if (allowance > 0 && static_cast<unsigned>(allowance) < entitySize)
48         return false;
49
50     request.setHTTPBody(entityBody);
51     request.setHTTPContentType("text/plain;charset=UTF-8");
52
53     issueRequest(frame, request);
54     payloadLength = entitySize;
55     return true;
56 }
57
58 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, PassRefPtr<ArrayBufferView>& data, int& payloadLength)
59 {
60     ASSERT(data);
61     unsigned long long entitySize = data->byteLength();
62     if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize)
63         return false;
64
65     ResourceRequest request(beaconURL);
66     prepareRequest(frame, request);
67
68     RefPtr<FormData> entityBody = FormData::create(data->baseAddress(), data->byteLength());
69     request.setHTTPBody(entityBody.release());
70
71     // FIXME: a reasonable choice, but not in the spec; should it give a default?
72     AtomicString contentType = AtomicString("application/octet-stream");
73     request.setHTTPContentType(contentType);
74
75     issueRequest(frame, request);
76     payloadLength = entitySize;
77     return true;
78 }
79
80 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, PassRefPtrWillBeRawPtr<Blob>& data, int& payloadLength)
81 {
82     ASSERT(data);
83     unsigned long long entitySize = data->size();
84     if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize)
85         return false;
86
87     ResourceRequest request(beaconURL);
88     prepareRequest(frame, request);
89
90     RefPtr<FormData> entityBody = FormData::create();
91     if (data->hasBackingFile())
92         entityBody->appendFile(toFile(data.get())->path());
93     else
94         entityBody->appendBlob(data->uuid(), data->blobDataHandle());
95
96     request.setHTTPBody(entityBody.release());
97
98     AtomicString contentType;
99     const String& blobType = data->type();
100     if (!blobType.isEmpty() && isValidContentType(blobType))
101         request.setHTTPContentType(AtomicString(contentType));
102
103     issueRequest(frame, request);
104     payloadLength = entitySize;
105     return true;
106 }
107
108 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, PassRefPtrWillBeRawPtr<DOMFormData>& data, int& payloadLength)
109 {
110     ASSERT(data);
111     ResourceRequest request(beaconURL);
112     prepareRequest(frame, request);
113
114     RefPtr<FormData> entityBody = data->createMultiPartFormData();
115
116     unsigned long long entitySize = entityBody->sizeInBytes();
117     if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize)
118         return false;
119
120     AtomicString contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + entityBody->boundary().data();
121     request.setHTTPBody(entityBody.release());
122     request.setHTTPContentType(contentType);
123
124     issueRequest(frame, request);
125     payloadLength = entitySize;
126     return true;
127 }
128
129 } // namespace blink