/usr/lib/python2.7/dist-packages/stetl/outputs/httpoutput.py is in python-stetl 1.1+ds-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | #!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Base classes for HTTP output like WFS-T and SOS-T or any other HTTP writing service.
#
# Author: Just van den Broecke
#
from stetl.output import Output
from stetl.util import Util
from stetl.packet import FORMAT
from stetl.component import Config
import httplib
import base64
log = Util.get_log('httpoutput')
class HttpOutput(Output):
"""
Output via HTTP protocol, usually via POST.
consumes=FORMAT.any
"""
@Config(ptype=str, default=None, required=True)
def host(self):
"""
The hostname/IP addr for target request.
"""
pass
@Config(ptype=int, default=80, required=False)
def port(self):
"""
The port number for target request.
"""
pass
@Config(ptype=str, default='/', required=False)
def path(self):
"""
The path number for target request.
"""
pass
@Config(ptype=str, default='POST', required=False)
def method(self):
"""
The HTTP method for target request.
"""
pass
@Config(ptype=str, default='text/xml', required=False)
def content_type(self):
"""
The HTTP ContentType request header for target request.
"""
pass
@Config(ptype=str, default=None, required=False)
def user(self):
"""
The Username for HTTP basic auth for target request.
"""
pass
@Config(ptype=str, default=None, required=False)
def password(self):
"""
The Password for HTTP basic auth for target request.
"""
pass
@Config(ptype=bool, default=True, required=False)
def list_fanout(self):
"""
If we consume a list(), should we create a HTTP req for each member?
"""
pass
def __init__(self, configdict, section, consumes=FORMAT.any):
Output.__init__(self, configdict, section, consumes)
# self.accept_type = self.cfg.get('accept_type', self.content_type)
self.req_nr = 0
def create_payload(self, packet):
"""
Create a HTTP body payload like for POST of an XML or JSON message.
Subclasses like WFS and SOS override.
:param packet:
:return payload as string:
"""
return packet.data
def post(self, packet, payload):
self.req_nr += 1
webservice = httplib.HTTP(self.host, self.port)
# write your headers
webservice.putrequest(self.method, self.path)
webservice.putheader("Host", self.host)
webservice.putheader("User-Agent", "Stetl Python http")
webservice.putheader("Content-Type", self.content_type)
# webservice.putheader("Accept", self.accept_type)
webservice.putheader("Content-Length", "%d" % len(payload))
# basic auth: http://mozgovipc.blogspot.nl/2012/06/python-http-basic-authentication-with.html
# base64 encode the username and password
# write the Authorization header like: 'Basic base64encode(username + ':' + password)
if self.user is not None:
auth = base64.encodestring('%s:%s' % (self.user, self.password)).replace('\n', '')
webservice.putheader("Authorization", "Basic %s" % auth)
webservice.endheaders()
webservice.send(payload)
# get the response
statuscode, statusmessage, header = webservice.getreply()
log.info("Req nr %d - response status: code=%d msg=%s" % (self.req_nr, statuscode, statusmessage))
if statuscode == 200:
res = webservice.getfile().read()
elif statuscode == 204:
res = ''
else:
log.error("Headers: %s" % str(header))
res = webservice.getfile().read()
log.info('Content: %s' % res)
return statuscode, statusmessage, res
def write(self, packet):
if packet.data is None:
return packet
if type(packet.data) is list and self.list_fanout is True:
# Multiple records in list, save original
original_data = packet.data
for data_elm in original_data:
packet.data = data_elm
self.post(packet, self.create_payload(packet))
packet.data = original_data
else:
# Regular, single data element or list_fanout is False
self.post(packet, self.create_payload(packet))
return packet
|